From 03d354efcea67f186c107d7e18a56b9c45753b87 Mon Sep 17 00:00:00 2001
From: "NCTU OpinConnect Terng-Yin Hsu/WEI-YING,LIN" <tyhsu@cs.nctu.edu.tw>
Date: Mon, 1 Jun 2020 19:27:44 +0800
Subject: [PATCH] merge to develop

---
 NOTICE.md                                     |    2 +-
 ci-scripts/.gitignore                         |    2 +
 ci-scripts/Jenkinsfile-inria-r2lab            |   47 +-
 ci-scripts/checkCodingFormattingRules.sh      |   65 +
 .../enb.band17.tm1.mbms.25PRB.usrpb210.conf   |    2 +-
 ci-scripts/cppcheck_suppressions.list         |    5 +
 ci-scripts/main.py                            | 3749 ++-----
 ci-scripts/reportBuildLocally.sh              |   71 +
 ci-scripts/runTestOnVM.sh                     |  176 +-
 .../enb_usrp210_band13_test_10mhz_tm1.xml     |    2 +-
 .../enb_usrp210_band40_test_05mhz_tm2.xml     |    2 +-
 ...st_05mhz_tm1_rrc_inactivity_no_flexran.xml |    4 +-
 ...est_05mhz_tm1_rrc_inactivity_w_flexran.xml |    4 +-
 .../enb_ue_usrp210_band7_test_05mhz_tm1.xml   |    2 +-
 ...b_ue_usrp210_band7_test_05mhz_tm1_nos1.xml |    2 +-
 .../enb_usrp210_band7_test_05mhz_tm1.xml      |    2 +-
 ...enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml |    4 +-
 cmake_targets/CMakeLists.txt                  |  127 +-
 cmake_targets/autotests/test_case_list.xml    |   46 +-
 cmake_targets/build_oai                       |    9 +-
 cmake_targets/nas_sim_tools/CMakeLists.txt    |    1 +
 cmake_targets/phy_simulators/CMakeLists.txt   |   30 +-
 cmake_targets/tools/build_helper              |   13 +-
 common/utils/LOG/vcd_signal_dumper.c          |    5 +-
 common/utils/LOG/vcd_signal_dumper.h          |    3 +
 common/utils/T/T_defs.h                       |    4 +-
 common/utils/T/T_messages.txt                 |   10 +
 common/utils/T/tracer/config.h                |    6 +-
 common/utils/T/tracer/hacks/time_meas.c       |   10 +-
 common/utils/T/tracer/hacks/timeplot.c        |   18 +-
 common/utils/T/tracer/packet-mac-lte.h        |    4 +
 common/utils/assertions.h                     |    8 +-
 common/utils/itti_analyzer/common/queue.h     |  592 -
 common/utils/nr/nr_common.h                   |    5 +
 common/utils/ocp_itti/intertask_interface.cpp |   28 +-
 common/utils/ocp_itti/intertask_interface.h   |   25 +-
 common/utils/system.c                         |    6 +-
 .../utils/telnetsrv/telnetsrv_cpumeasur_def.h |    4 +
 .../telnetsrv/telnetsrv_enb_measurements.c    |   16 +-
 .../utils/telnetsrv/telnetsrv_ltemeasur_def.h |    4 +
 .../utils/telnetsrv/telnetsrv_measurements.h  |    5 +
 common/utils/telnetsrv/telnetsrv_phycmd.h     |    4 +
 common/utils/telnetsrv/telnetsrv_proccmd.h    |    5 +
 common/utils/threadPool/measurement_display.c |   23 +-
 common/utils/threadPool/thread-pool.c         |   23 +-
 common/utils/threadPool/thread-pool.h         |   29 +-
 doc/L2NFAPI.md                                |   19 +-
 doc/L2NFAPI_S1.md                             |  165 +-
 executables/nr-gnb.c                          |   86 +-
 executables/nr-ru.c                           |  128 +-
 executables/nr-softmodem.c                    |   83 +-
 executables/nr-ue.c                           |   76 +-
 executables/nr-uesoftmodem.c                  |   44 +-
 executables/nr-uesoftmodem.h                  |    1 -
 executables/softmodem-common.c                |   56 +-
 executables/softmodem-common.h                |   15 +-
 nfapi/oai_integration/nfapi.c                 |    2 +-
 nfapi/oai_integration/nfapi_pnf.c             |   18 +-
 nfapi/oai_integration/nfapi_pnf.h             |    2 +-
 .../nfapi/public_inc/fapi_nr_ue_interface.h   |  153 +-
 .../nfapi/public_inc/nfapi_nr_interface.h     |    1 +
 .../nfapi/public_inc/nfapi_nr_interface_scf.h |   39 +-
 .../pnf/public_inc/nfapi_pnf_interface.h      |    7 +-
 nfapi/open-nFAPI/pnf/src/pnf_interface.c      |    2 +-
 nfapi/open-nFAPI/pnf/src/pnf_p7.c             |   18 +-
 nfapi/open-nFAPI/vnf/src/vnf_interface.c      |    2 +-
 nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c   |    2 +-
 openair1/PHY/CODING/TESTBENCH/ldpctest.c      |   76 +-
 .../CODING/nrLDPC_decoder/nrLDPC_decoder.c    |    4 +-
 .../PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h  |  256 +-
 openair1/PHY/INIT/lte_init_ru.c               |    4 +-
 openair1/PHY/INIT/lte_init_ue.c               |    2 +-
 openair1/PHY/INIT/nr_init.c                   |    5 +-
 openair1/PHY/INIT/nr_init_ue.c                |   26 +-
 .../PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c  |    8 +-
 .../PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c   |    1 -
 .../lte_dl_bf_channel_estimation.c            |   96 +-
 .../lte_dl_channel_estimation.c               |   54 +-
 .../lte_dl_mbsfn_channel_estimation.c         |   10 +-
 openair1/PHY/LTE_ESTIMATION/lte_sync_time.c   |   40 +-
 .../PHY/LTE_ESTIMATION/lte_sync_timefreq.c    |    8 +-
 .../PHY/LTE_ESTIMATION/lte_ue_measurements.c  |    2 +-
 .../lte_ul_channel_estimation.c               |   23 +-
 openair1/PHY/LTE_REFSIG/mod_table.h           |    5 +
 openair1/PHY/LTE_TRANSPORT/dlsch_coding.c     |  704 +-
 openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c |   24 +-
 openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c |    2 +-
 openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h   |    4 +
 openair1/PHY/LTE_TRANSPORT/if5_tools.h        |    3 +-
 openair1/PHY/LTE_TRANSPORT/lte_mcs.c          |   29 +
 openair1/PHY/LTE_TRANSPORT/phich.c            |    2 +-
 openair1/PHY/LTE_TRANSPORT/pmch.c             |    1 +
 openair1/PHY/LTE_TRANSPORT/prach.c            |  101 +-
 openair1/PHY/LTE_TRANSPORT/prach_extern.h     |    5 +
 openair1/PHY/LTE_TRANSPORT/pucch.c            |    2 +-
 openair1/PHY/LTE_TRANSPORT/pucch_extern.h     |    5 +
 .../LTE_TRANSPORT/transport_common_proto.h    |    2 +
 openair1/PHY/LTE_TRANSPORT/transport_eNB.h    |   11 +-
 openair1/PHY/LTE_TRANSPORT/transport_extern.h |    2 +-
 openair1/PHY/LTE_TRANSPORT/transport_proto.h  |   36 +-
 openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c   |  616 +-
 .../PHY/LTE_TRANSPORT/ulsch_demodulation.c    |  205 +-
 .../PHY/LTE_UE_TRANSPORT/dlsch_decoding.c     |    2 +-
 openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c  |    1 -
 openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c      |   30 +-
 openair1/PHY/LTE_UE_TRANSPORT/sldch.c         |    3 -
 openair1/PHY/LTE_UE_TRANSPORT/slsch.c         |    4 -
 openair1/PHY/LTE_UE_TRANSPORT/slss.c          |    4 -
 openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c  |   10 +-
 .../PHY/LTE_UE_TRANSPORT/ulsch_modulation.c   |  204 +-
 openair1/PHY/MODULATION/nr_modulation.c       |   68 +-
 openair1/PHY/MODULATION/ofdm_mod.c            |   24 +-
 openair1/PHY/MODULATION/slot_fep.c            |  114 +-
 openair1/PHY/MODULATION/slot_fep_mbsfn.c      |   72 +-
 openair1/PHY/MODULATION/slot_fep_nr.c         |   81 +-
 openair1/PHY/MODULATION/slot_fep_ul.c         |   22 +-
 .../NR_ESTIMATION/nr_ul_channel_estimation.c  |   18 +-
 openair1/PHY/NR_REFSIG/dmrs_nr.c              |  156 -
 openair1/PHY/NR_REFSIG/dmrs_nr.h              |   13 -
 openair1/PHY/NR_REFSIG/nr_mod_table.h         |   26 +
 openair1/PHY/NR_REFSIG/nr_refsig.h            |    8 +-
 openair1/PHY/NR_REFSIG/pss_nr.h               |    4 +-
 openair1/PHY/NR_REFSIG/ptrs_nr.c              |  291 +-
 openair1/PHY/NR_REFSIG/ptrs_nr.h              |   46 +-
 openair1/PHY/NR_TRANSPORT/nr_dci_tools.c      |    6 +-
 openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c   |    3 +-
 openair1/PHY/NR_TRANSPORT/nr_prach.c          |  103 +-
 openair1/PHY/NR_TRANSPORT/nr_transport.h      |   28 +
 .../NR_TRANSPORT/nr_transport_common_proto.h  |   13 +
 .../NR_TRANSPORT/nr_transport_proto_common.h  |   73 +-
 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c |   35 +-
 .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c  |  137 +-
 openair1/PHY/NR_TRANSPORT/pucch_rx.c          |  868 +-
 .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c |    1 -
 .../nr_dl_channel_estimation.c                |   23 +-
 openair1/PHY/NR_UE_TRANSPORT/dci_nr.h         |    5 +
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |    3 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_prach.c       |   68 +-
 .../NR_UE_TRANSPORT/nr_transport_proto_ue.h   |    3 +-
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     |   30 +-
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |   53 +-
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c    |  192 +-
 openair1/PHY/NR_UE_TRANSPORT/pss_nr.c         |   65 +-
 openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c       |  197 +-
 openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h       |   51 +-
 openair1/PHY/NR_UE_TRANSPORT/sss_nr.c         |    2 +-
 openair1/PHY/TOOLS/lte_dfts.c                 | 9688 -----------------
 openair1/PHY/TOOLS/lte_phy_scope.c            |   12 +-
 openair1/PHY/TOOLS/nr_phy_scope.c             |    8 +-
 openair1/PHY/TOOLS/smbv.h                     |    3 +
 openair1/PHY/TOOLS/time_meas.h                |    2 +-
 openair1/PHY/TOOLS/tools_defs.h               |  208 +-
 openair1/PHY/defs_L1_NB_IoT.h                 |    4 -
 openair1/PHY/defs_RU.h                        |    7 +-
 openair1/PHY/defs_common.h                    |    8 -
 openair1/PHY/defs_eNB.h                       |   91 +-
 openair1/PHY/defs_gNB.h                       |   72 +-
 openair1/PHY/defs_nr_UE.h                     |    3 -
 openair1/PHY/phy_extern.h                     |   33 +-
 openair1/PHY/phy_extern_nr_ue.h               |   30 +-
 openair1/PHY/phy_extern_ue.h                  |   32 +-
 openair1/PHY/phy_vars.h                       |   38 +-
 openair1/PHY/phy_vars_nr_ue.h                 |   38 +-
 openair1/PHY/phy_vars_ue.h                    |   44 +-
 openair1/SCHED/fapi_l1.c                      |   16 +-
 openair1/SCHED/fapi_l1.h                      |    6 +-
 openair1/SCHED/phy_procedures_lte_eNb.c       |  270 +-
 openair1/SCHED/ru_procedures.c                |    4 +-
 openair1/SCHED/sched_common.h                 |    2 +-
 openair1/SCHED/sched_eNB.h                    |    8 +-
 openair1/SCHED_NR/fapi_nr_l1.h                |    3 +-
 openair1/SCHED_NR/nr_prach_procedures.c       |   82 +-
 openair1/SCHED_NR/phy_frame_config_nr.c       |    2 +-
 openair1/SCHED_NR/phy_procedures_nr_gNB.c     |  198 +-
 openair1/SCHED_NR_UE/fapi_nr_ue_l1.c          |   16 +-
 openair1/SCHED_NR_UE/harq_nr.c                |    8 +-
 openair1/SCHED_NR_UE/phy_frame_config_nr.h    |    5 +-
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   |   13 +-
 openair1/SCHED_NR_UE/pucch_uci_ue_nr.c        |    6 +-
 openair1/SIMULATION/ETH_TRANSPORT/socket.h    |    5 +-
 openair1/SIMULATION/LTE_PHY/dlsim.c           |   29 +-
 openair1/SIMULATION/LTE_PHY/ulsim.c           |   22 +-
 openair1/SIMULATION/NR_PHY/dlsim.c            |    9 +-
 openair1/SIMULATION/NR_PHY/pbchsim.c          |    2 +-
 openair1/SIMULATION/NR_PHY/prachsim.c         |   15 +-
 openair1/SIMULATION/NR_PHY/pucchsim.c         |  213 +-
 openair1/SIMULATION/NR_PHY/ulschsim.c         |   26 +-
 openair1/SIMULATION/NR_PHY/ulsim.c            |  158 +-
 openair2/COMMON/platform_constants.h          |    2 +
 openair2/COMMON/rrc_messages_def.h            |    3 +
 openair2/COMMON/rrc_messages_types.h          |   10 +
 openair2/COMMON/s1ap_messages_types.h         |    4 -
 openair2/DOCS/TEMPLATES/CODE/example_doxy.h   |    4 +
 .../CONTROL_MODULES/MAC/flexran_agent_mac.c   |    8 +-
 .../MAC/flexran_agent_mac_internal.c          |    6 +-
 openair2/ENB_APP/L1_paramdef.h                |    4 +
 openair2/ENB_APP/MACRLC_paramdef.h            |    4 +
 openair2/ENB_APP/NB_IoT_paramdef.h            |    5 +
 openair2/ENB_APP/enb_paramdef.h               |   13 +-
 openair2/ENB_APP/enb_paramdef_emtc.h          |    5 +
 openair2/ENB_APP/enb_paramdef_mce.h           |    6 +-
 openair2/ENB_APP/enb_paramdef_mme.h           |    7 +-
 openair2/ENB_APP/flexran_agent_ran_api.c      |  106 +-
 openair2/F1AP/f1ap_cu_ue_context_management.c |    1 -
 openair2/F1AP/f1ap_du_rrc_message_transfer.c  |    2 +-
 openair2/F1AP/f1ap_du_ue_context_management.c |    4 +-
 openair2/GNB_APP/L1_nr_paramdef.h             |    3 +
 openair2/GNB_APP/MACRLC_nr_paramdef.h         |    3 +
 openair2/GNB_APP/RRC_nr_paramsvalues.h        |   24 +-
 openair2/GNB_APP/gnb_config.c                 |    2 -
 openair2/GNB_APP/gnb_paramdef.h               |    4 +
 openair2/LAYER2/MAC/config.c                  |   50 +-
 openair2/LAYER2/MAC/config_NB_IoT.h           |    4 +-
 openair2/LAYER2/MAC/defs.h                    | 1321 ---
 openair2/LAYER2/MAC/eNB_scheduler.c           |  117 +-
 openair2/LAYER2/MAC/eNB_scheduler_RA.c        |   51 +-
 openair2/LAYER2/MAC/eNB_scheduler_dlsch.c     | 2256 ++--
 openair2/LAYER2/MAC/eNB_scheduler_fairRR.c    |  754 +-
 openair2/LAYER2/MAC/eNB_scheduler_fairRR.h    |   24 +
 openair2/LAYER2/MAC/eNB_scheduler_mch.c       |   18 +-
 openair2/LAYER2/MAC/eNB_scheduler_phytest.c   |   36 +-
 .../LAYER2/MAC/eNB_scheduler_primitives.c     |  588 +-
 openair2/LAYER2/MAC/eNB_scheduler_ulsch.c     | 1211 +--
 openair2/LAYER2/MAC/mac.h                     |   91 +-
 openair2/LAYER2/MAC/mac_extern.h              |    2 +-
 openair2/LAYER2/MAC/mac_proto.h               |  153 +-
 openair2/LAYER2/MAC/main.c                    |   36 +-
 openair2/LAYER2/MAC/pre_processor.c           | 2641 ++---
 openair2/LAYER2/MAC/ra_procedures.c           |    4 +-
 openair2/LAYER2/MAC/ue_procedures.c           |   24 +-
 openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c |  147 +
 openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h |    2 +-
 openair2/LAYER2/NR_MAC_UE/mac_proto.h         |    5 +
 openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c  |  342 +-
 openair2/LAYER2/NR_MAC_gNB/config.c           |    2 -
 openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c    |  114 +-
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c |   79 +-
 .../NR_MAC_gNB/gNB_scheduler_primitives.c     |  355 +-
 .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c   |   11 +-
 openair2/LAYER2/NR_MAC_gNB/mac_proto.h        |   30 +-
 openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h       |  135 +-
 .../LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h   |   70 -
 openair2/LAYER2/PROTO_AGENT/proto_agent.c     |   48 +-
 openair2/LAYER2/PROTO_AGENT/proto_agent.h     |   49 +-
 .../LAYER2/PROTO_AGENT/proto_agent_async.c    |   49 +-
 .../LAYER2/PROTO_AGENT/proto_agent_async.h    |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_common.c   |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_common.h   |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_defs.h     |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_handler.c  |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_net_comm.c |   48 +-
 .../LAYER2/PROTO_AGENT/proto_agent_net_comm.h |   48 +-
 openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c        |   26 +-
 openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h        |   12 +-
 openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c        |    3 -
 openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h        |    4 +-
 openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c        |   15 +-
 openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h        |   16 +-
 openair2/LAYER2/RLC/rlc.h                     |   11 +-
 openair2/LAYER2/RLC/rlc_mac.c                 |   14 +-
 openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c       |   10 +-
 openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h    |    4 -
 openair2/LAYER2/openair2_proc.c               |  104 +-
 openair2/M2AP/m2ap_MCE_handler.h              |    6 +-
 .../M2AP/m2ap_MCE_management_procedures.h     |    6 +-
 openair2/M2AP/m2ap_eNB_generate_messages.h    |    6 +-
 .../M2AP/m2ap_eNB_management_procedures.h     |    6 +-
 openair2/MCE_APP/mce_app.c                    |    4 +-
 openair2/NETWORK_DRIVER/LITE/proto_extern.h   |    4 +-
 openair2/NETWORK_DRIVER/MESH/proto_extern.h   |    4 +-
 openair2/NR_PHY_INTERFACE/NR_IF_Module.c      |  139 +-
 openair2/NR_PHY_INTERFACE/NR_IF_Module.h      |   23 +-
 openair2/PHY_INTERFACE/IF_Module.c            |    4 +-
 openair2/PHY_INTERFACE/IF_Module.h            |   77 +-
 openair2/PHY_INTERFACE/phy_stub_UE.c          |  341 +-
 openair2/PHY_INTERFACE/phy_stub_UE.h          |   26 +-
 openair2/RRC/LTE/rrc_eNB.c                    |  305 +-
 openair2/RRC/LTE/rrc_eNB_UE_context.h         |    2 +
 openair2/RRC/LTE/utils.c                      |   14 +-
 openair2/RRC/NR/MESSAGES/asn1_msg.c           |    4 +-
 openair2/RRC/NR/nr_rrc_extern.h               |   10 +-
 openair2/RRC/NR/rrc_gNB.c                     |    8 +-
 openair2/RRC/NR/rrc_gNB_UE_context.h          |    6 +-
 openair2/RRC/NR/rrc_gNB_nsa.c                 |    6 +-
 openair2/UTIL/MEM/mem_block.c                 |  668 --
 openair2/UTIL/MEM/mem_block.h                 |  108 -
 openair2/UTIL/MEM/mem_mngt.c                  |  489 -
 openair2/UTIL/MEM/mem_mngt_proto_extern.h     |   21 -
 openair2/UTIL/MEM/mem_pool.h                  |   38 -
 openair2/UTIL/OCG/OCG_if.h                    |    4 +-
 openair2/UTIL/OPT/mac_pcap.h                  |    5 +-
 openair2/UTIL/OPT/opt.h                       |    4 -
 openair2/UTIL/OPT/packet-mac-lte.h            |    4 +
 openair2/UTIL/OPT/probe.c                     |   12 +-
 openair2/UTIL/OSA/osa_defs.h                  |    6 +-
 openair2/UTIL/OTG/traffic_config.h            |    5 +
 openair2/X2AP/x2ap_eNB_generate_messages.c    |   10 +-
 openair2/X2AP/x2ap_eNB_handler.c              |    5 +-
 .../X2AP/x2ap_eNB_management_procedures.h     |    6 +-
 openair3/M3AP/m3ap_MCE_generate_messages.h    |   25 +-
 openair3/M3AP/m3ap_MCE_handler.h              |   10 +-
 .../M3AP/m3ap_MCE_management_procedures.h     |    6 +-
 openair3/M3AP/m3ap_MME_generate_messages.h    |    8 +-
 .../M3AP/m3ap_MME_management_procedures.h     |    6 +-
 openair3/MME_APP/enb_paramdef_mme.h           |    4 +
 openair3/MME_APP/mme_config.h                 |    7 +-
 openair3/NAS/COMMON/API/NETWORK/as_message.h  |  578 -
 openair3/NAS/COMMON/UTIL/socket.c             |    2 +-
 openair3/NAS/COMMON/UTIL/socket.h             |    6 +-
 openair3/NAS/COMMON/commonDef.h               |  333 -
 openair3/NAS/COMMON/networkDef.h              |  271 -
 openair3/NAS/TEST/USER/user_parser.h          |    6 +-
 openair3/NAS/TOOLS/conf_network.c             |    4 +-
 openair3/NAS/TOOLS/conf_parser.c              |    2 +-
 openair3/TEST/oaisim_mme_test_s1c_s1ap.h      |    5 +
 openair3/TEST/oaisim_mme_test_s1c_scenario.h  |    5 +
 openair3/UTILS/mme_config.h                   |    8 +-
 openair3/UTILS/queue.h                        |  592 -
 openair3/UTILS/tree.h                         |  678 --
 targets/ARCH/COMMON/common_lib.h              |   42 +-
 targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h |    9 +-
 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp  |  274 +-
 targets/ARCH/rfsimulator/README.md            |   33 +-
 targets/ARCH/rfsimulator/apply_channelmod.c   |   23 +-
 targets/ARCH/rfsimulator/simulator.c          |   52 +-
 targets/ARCH/rfsimulator/stored_node.c        |   23 +-
 targets/COMMON/create_tasks.c                 |    5 +-
 targets/COMMON/create_tasks_mbms.h            |   32 -
 .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf  |    4 +-
 .../CONF/gnb.band78.tm1.273PRB.usrpn300.conf  |    2 +-
 targets/RT/USER/gNB_usrp.gtkw                 |   22 +-
 targets/RT/USER/lte-enb.c                     |   14 +-
 targets/RT/USER/lte-ru.c                      |   32 +-
 targets/RT/USER/lte-softmodem.c               |   77 +-
 targets/RT/USER/lte-softmodem.h               |    4 +-
 targets/RT/USER/lte-ue.c                      |  149 +-
 targets/RT/USER/lte-uesoftmodem.c             |   19 +-
 targets/RT/USER/rfsim.c                       |    4 +-
 338 files changed, 11504 insertions(+), 28958 deletions(-)
 delete mode 100644 common/utils/itti_analyzer/common/queue.h
 delete mode 100644 openair1/PHY/TOOLS/lte_dfts.c
 delete mode 100644 openair2/LAYER2/MAC/defs.h
 delete mode 100644 openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
 delete mode 100644 openair2/UTIL/MEM/mem_block.c
 delete mode 100644 openair2/UTIL/MEM/mem_mngt.c
 delete mode 100644 openair2/UTIL/MEM/mem_mngt_proto_extern.h
 delete mode 100644 openair2/UTIL/MEM/mem_pool.h
 delete mode 100644 openair3/NAS/COMMON/API/NETWORK/as_message.h
 delete mode 100644 openair3/NAS/COMMON/commonDef.h
 delete mode 100644 openair3/NAS/COMMON/networkDef.h
 delete mode 100644 openair3/UTILS/queue.h
 delete mode 100644 openair3/UTILS/tree.h
 delete mode 100644 targets/COMMON/create_tasks_mbms.h

diff --git a/NOTICE.md b/NOTICE.md
index 65c6105660f..96b5d4c552e 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -4,7 +4,7 @@ For more details of the license, refer to [LICENSE](LICENSE) file in the same di
 
 However, the source code also contains third party software that is acknowledged here for reference.
 
-## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/liblfds6.1.1/ ##
+## Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/ ##
 
 See on [liblfds website](https://liblfds.org/) the license section.
 
diff --git a/ci-scripts/.gitignore b/ci-scripts/.gitignore
index d77a672c0c5..dc5e7c74764 100644
--- a/ci-scripts/.gitignore
+++ b/ci-scripts/.gitignore
@@ -5,3 +5,5 @@ iperf_*.*
 phones_list.txt
 modules_list.txt
 test_results*.html
+pMain*
+__pycache__
diff --git a/ci-scripts/Jenkinsfile-inria-r2lab b/ci-scripts/Jenkinsfile-inria-r2lab
index 3c4dddae8b3..ada52277f4e 100644
--- a/ci-scripts/Jenkinsfile-inria-r2lab
+++ b/ci-scripts/Jenkinsfile-inria-r2lab
@@ -62,6 +62,7 @@ def r2labUE0IpAddr = r2labBaseIpAddr + r2labUE0Idx
 def r2labENB1Idx = '16'
 def r2labENB1 = 'fit' + r2labENB1Idx
 def r2labENB1IpAddr = r2labBaseIpAddr + r2labENB1Idx
+def r2labDoAllOff = true
 
 pipeline {
     agent {
@@ -136,19 +137,49 @@ pipeline {
                         sh "python3 /home/eurecom/inria-scripts/booking-lease.py --book-lease --from ${BOOK_TIMESTAMP}T${r2labStartTime} --duration ${r2labDuration} --slice inria_oaici ${r2labuser} ${r2labpassword}"
                         sh "python3 /home/eurecom/inria-scripts/booking-lease.py --get-leases ${r2labuser} ${r2labpassword} | grep -v nightly"
                     }
+
+                    // Adding a tempo after booking leases
+                    sh "sleep 10"
+                    LEASE_STATUS = sh returnStdout: true, script: "ssh -t inria_oaici@faraday.inria.fr 'rleases --check'"
+                    LEASE_STATUS = LEASE_STATUS.trim()
+                    if (LEASE_STATUS ==~ /.*Access currently denied to inria_oaici.*/) {
+                        r2labDoAllOff = false
+                        currentBuild.result = 'ABORTED'
+                        error('Stopping early because R2LAB not available')
+                    }
                 }
             }
         }
         stage ("Load Images") {
             steps {
                 script {
+                    sh "ssh -t inria_oaici@faraday.inria.fr 'all-off'"
+                    sh "sleep 10"
+
                     echo '\u2705 \u001B[32mLoad Image for Python Executor\u001B[0m'
-                    sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx} > /dev/null 2>&1'"
-                    sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labPythonExeIdx}'"
+                    try {
+                       sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labPythonExeIdx} > /dev/null 2>&1'"
+                    } catch (Exception e) {
+                       echo "Why is it wrong?"
+                    }
+                    try {
+                       //sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labPythonExeIdx}'"
+                       sh "ssh -t inria_oaici@faraday.inria.fr 'rwait ${r2labPythonExeIdx}'"
+                    } catch (Exception e) {
+                       echo "Why is it wrong?"
+                    }
 
                     echo '\u2705 \u001B[32mLoad Image for two (2) eNBs\u001B[0m'
-                    sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'"
-                    sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'"
+                    try {
+                      sh "ssh -t inria_oaici@faraday.inria.fr 'rload -i oai-ci-cd-u18-lowlatency-enb-ue ${r2labENB0Idx},${r2labENB1Idx} > /dev/null 2>&1'"
+                    } catch (Exception e) {
+                       echo "Why is it wrong?"
+                    }
+                    try {
+                       sh "ssh -t inria_oaici@faraday.inria.fr 'rwait --silent ${r2labENB0Idx},${r2labENB1Idx}'"
+                    } catch (Exception e) {
+                       echo "Why is it wrong?"
+                    }
                     sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
                     sh "sleep 5"
                     sh "ssh -t inria_oaici@faraday.inria.fr 'uon ${r2labENB0Idx},${r2labENB1Idx}'"
@@ -415,9 +446,11 @@ pipeline {
     post {
         always {
             script {
-                echo '\u2705 \u001B[32mShutdown every node\u001B[0m'
-                sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"'
-                sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"'
+                if (r2labDoAllOff) {
+                    echo '\u2705 \u001B[32mShutdown every node\u001B[0m'
+                    sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"'
+                    sh 'ssh -t inria_oaici@faraday.inria.fr "all-off"'
+                }
             }
         }
     }
diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh
index 6ac43ca19fe..fb159d4da07 100755
--- a/ci-scripts/checkCodingFormattingRules.sh
+++ b/ci-scripts/checkCodingFormattingRules.sh
@@ -62,6 +62,30 @@ then
     NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted `
     echo "Nb Files that do NOT follow OAI rules: $NB_FILES_TO_FORMAT"
     echo $NB_FILES_TO_FORMAT > ./oai_rules_result.txt
+
+    # Testing Circular Dependencies protection
+    awk '/#[ \t]*ifndef/ { gsub("^.*ifndef *",""); if (names[$1]!="") print "files with same {define ", FILENAME, names[$1]; names[$1]=FILENAME } /#[ \t]*define/ { gsub("^.*define *",""); if(names[$1]!=FILENAME) print "error in declaration", FILENAME, $1, names[$1]; nextfile }' `find openair* common targets executables -name *.h |grep -v LFDS` > header-files-w-incorrect-define.txt
+
+    # Testing if explicit GNU GPL license banner
+    egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . > files-w-gnu-gpl-license-banner.txt
+
+    # Looking at exotic/suspect banner
+    LIST_OF_FILES_W_BANNER=`egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "Copyright|copyleft" .`
+    if [ -f ./files-w-suspect-banner.txt ]; then rm -f ./files-w-suspect-banner.txt; fi
+    for FILE in $LIST_OF_FILES_W_BANNER
+    do
+       IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"`
+       IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE`
+       IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE`
+       IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"`
+       if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
+       then
+           if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
+           then
+               echo $FILE >> ./files-w-suspect-banner.txt
+           fi
+       fi
+    done
     exit 0
 fi
 
@@ -131,8 +155,25 @@ if [ -f oai_rules_result_list.txt ]
 then
     rm -f oai_rules_result_list.txt
 fi
+if [ -f header-files-w-incorrect-define.txt ]
+then
+    rm -f header-files-w-incorrect-define.txt
+fi
+if [ -f files-w-gnu-gpl-license-banner.txt ]
+then
+    rm -f files-w-gnu-gpl-license-banner.txt
+fi
+if [ -f files-w-suspect-banner.txt ]
+then
+    rm -f files-w-suspect-banner.txt
+fi
+awk '/#[ \t]*ifndef/ { gsub("^.*ifndef *",""); if (names[$1]!="") print "files with same {define ", FILENAME, names[$1]; names[$1]=FILENAME } /#[ \t]*define/ { gsub("^.*define *",""); if(names[$1]!=FILENAME) print "error in declaration", FILENAME, $1, names[$1]; nextfile }' `find openair* common targets executables -name *.h |grep -v LFDS` > header-files-w-incorrect-define-tmp.txt
+
 for FULLFILE in $MODIFIED_FILES
 do
+    # sometimes, we remove files
+    if [ ! -f $FULLFILE ]; then continue; fi
+
     filename=$(basename -- "$FULLFILE")
     EXT="${filename##*.}"
     if [ $EXT = "c" ] || [ $EXT = "h" ] || [ $EXT = "cpp" ] || [ $EXT = "hpp" ]
@@ -144,8 +185,32 @@ do
             echo $FULLFILE
             echo $FULLFILE >> ./oai_rules_result_list.txt
         fi
+        # Testing if explicit GNU GPL license banner
+        egrep -i "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt
+        # Looking at exotic/suspect banner
+        IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE`
+        if [ $IS_BANNER -ne 0 ]
+        then
+            IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"`
+            IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE`
+            IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE`
+            IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"`
+            if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ]
+            then
+                if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ]
+                then
+                    echo $FILE >> ./files-w-suspect-banner.txt
+                fi
+            fi
+        fi
+    fi
+    # Testing Circular Dependencies protection
+    if [ $EXT = "h" ] || [ $EXT = "hpp" ]
+    then
+        grep $FULLFILE header-files-w-incorrect-define-tmp.txt >> header-files-w-incorrect-define.txt
     fi
 done
+rm -f header-files-w-incorrect-define-tmp.txt
 echo ""
 echo " ----------------------------------------------------------"
 echo "Nb Files that do NOT follow OAI rules: $NB_TO_FORMAT"
diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
index fbb8c5d6f87..de58950df4e 100644
--- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf
@@ -288,7 +288,7 @@ MCEs = (
                                     mnc_length = 2;
                                 }
                                 service_id=0;
-                                lcid=8; #this must be properly defined lcid:8+service:0 -> rab_id:8
+                                lcid=5; #this must be properly defined lcid:8+service:0 -> rab_id:5
                         }
                         );
                    }
diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list
index 4536f573156..cad2aab88b4 100644
--- a/ci-scripts/cppcheck_suppressions.list
+++ b/ci-scripts/cppcheck_suppressions.list
@@ -76,6 +76,11 @@ nullPointer:common/utils/T/local_tracer.c:243
 // first iteration of the loop
 nullPointer:common/utils/T/tracer/multi.c:264
 nullPointer:common/utils/T/tracer/multi.c:265
+//-----------------------------------------------------------------------------
+// this file is used for testing the RLC V2 implementation, this error is
+// not a problem, the programmer has to know what she does when writing
+// the tests
+arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401
 //
 //*****************************************************************************
 //
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 21d51105f85..e9313051fc1 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1,4 +1,4 @@
-#/*
+
 # * 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.
@@ -28,47 +28,7 @@
 #     pexpect
 #---------------------------------------------------------------------
 
-#-----------------------------------------------------------
-# Version
-#-----------------------------------------------------------
-Version = '0.1'
-
-#-----------------------------------------------------------
-# Constants
-#-----------------------------------------------------------
-ALL_PROCESSES_OK = 0
-ENB_PROCESS_FAILED = -1
-ENB_PROCESS_OK = +1
-ENB_PROCESS_SEG_FAULT = -11
-ENB_PROCESS_ASSERTION = -12
-ENB_PROCESS_REALTIME_ISSUE = -13
-ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
-ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15
-HSS_PROCESS_FAILED = -2
-HSS_PROCESS_OK = +2
-MME_PROCESS_FAILED = -3
-MME_PROCESS_OK = +3
-SPGW_PROCESS_FAILED = -4
-SPGW_PROCESS_OK = +4
-UE_IP_ADDRESS_ISSUE = -5
-OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20
-OAI_UE_PROCESS_COULD_NOT_SYNC = -21
-OAI_UE_PROCESS_ASSERTION = -22
-OAI_UE_PROCESS_FAILED = -23
-OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24
-OAI_UE_PROCESS_SEG_FAULT = -25
-OAI_UE_PROCESS_OK = +6
-
-UE_STATUS_DETACHED = 0
-UE_STATUS_DETACHING = 1
-UE_STATUS_ATTACHING = 2
-UE_STATUS_ATTACHED = 3
-
-X2_HO_REQ_STATE__IDLE = 0
-X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1
-X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2
-X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3
-X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10
+import constants as CONST
 
 #-----------------------------------------------------------
 # Import
@@ -89,55 +49,27 @@ logging.basicConfig(
 	format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s"
 )
 
+
 #-----------------------------------------------------------
 # Class Declaration
 #-----------------------------------------------------------
-class SSHConnection():
+class OaiCiTest():
+	
 	def __init__(self):
-		self.prematureExit = False
 		self.ranRepository = ''
 		self.ranBranch = ''
-		self.ranAllowMerge = False
 		self.ranCommitID = ''
+		self.ranAllowMerge = False
 		self.ranTargetBranch = ''
-		self.eNBIPAddress = ''
-		self.eNBUserName = ''
-		self.eNBPassword = ''
-		self.eNBSourceCodePath = ''
-		self.EPCIPAddress = ''
-		self.EPCUserName = ''
-		self.EPCPassword = ''
-		self.eNB1IPAddress = ''
-		self.eNB1UserName = ''
-		self.eNB1Password = ''
-		self.eNB1SourceCodePath = ''
-		self.eNB2IPAddress = ''
-		self.eNB2UserName = ''
-		self.eNB2Password = ''
-		self.eNB2SourceCodePath = ''
-		self.EPCSourceCodePath = ''
-		self.EPCType = ''
-		self.EPC_PcapFileName = ''
+
+		self.FailReportCnt = 0
 		self.ADBIPAddress = ''
 		self.ADBUserName = ''
 		self.ADBPassword = ''
 		self.ADBCentralized = True
 		self.testCase_id = ''
 		self.testXMLfiles = []
-		self.nbTestXMLfiles = 0
 		self.desc = ''
-		self.Build_eNB_args = ''
-		self.backgroundBuild = False
-		self.backgroundBuildTestId = ['', '', '']
-		self.Build_eNB_forced_workspace_cleanup = False
-		self.Initialize_eNB_args = ''
-		self.air_interface = 'lte'
-		self.eNB_instance = ''
-		self.eNB_serverId = ''
-		self.eNBLogFiles = ['', '', '']
-		self.eNBOptions = ['', '', '']
-		self.eNBmbmsEnables = [False, False, False]
-		self.eNBstatuses = [-1, -1, -1]
 		self.ping_args = ''
 		self.ping_packetloss_threshold = ''
 		self.iperf_args = ''
@@ -154,30 +86,13 @@ class SSHConnection():
 		self.UEDevicesRebootCmd = []
 		self.CatMDevices = []
 		self.UEIPAddresses = []
-		self.htmlFile = ''
-		self.htmlHeaderCreated = False
-		self.htmlFooterCreated = False
-		self.htmlUEConnected = -1
-		self.htmleNBFailureMsg = ''
-		self.htmlUEFailureMsg = ''
-		self.picocom_closure = False
 		self.idle_sleep_time = 0
 		self.x2_ho_options = 'network'
 		self.x2NbENBs = 0
 		self.x2ENBBsIds = []
 		self.x2ENBConnectedUEs = []
-		self.htmlTabRefs = []
-		self.htmlTabNames = []
-		self.htmlTabIcons = []
 		self.repeatCounts = []
 		self.finalStatus = False
-		self.OsVersion = ''
-		self.KernelVersion = ''
-		self.UhdVersion = ''
-		self.UsrpBoard = ''
-		self.CpuNb = ''
-		self.CpuModel = ''
-		self.CpuMHz = ''
 		self.UEIPAddress = ''
 		self.UEUserName = ''
 		self.UEPassword = ''
@@ -187,819 +102,192 @@ class SSHConnection():
 		self.Build_OAI_UE_args = ''
 		self.Initialize_OAI_UE_args = ''
 		self.clean_repository = True
-		self.flexranCtrlInstalled = False
-		self.flexranCtrlStarted = False
 		self.expectedNbOfConnectedUEs = 0
-		self.startTime = 0
-
-	def open(self, ipaddress, username, password):
-		count = 0
-		connect_status = False
-		while count < 4:
-			self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress], timeout = 5)
-			self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT])
-			if self.sshresponse == 0:
-				self.ssh.sendline('yes')
-				self.ssh.expect('password:')
-				self.ssh.sendline(password)
-				self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if self.sshresponse == 0:
-					count = 10
-					connect_status = True
-				else:
-					logging.debug('self.sshresponse = ' + str(self.sshresponse))
-			elif self.sshresponse == 1:
-				self.ssh.sendline(password)
-				self.sshresponse = self.ssh.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if self.sshresponse == 0:
-					count = 10
-					connect_status = True
-				else:
-					logging.debug('self.sshresponse = ' + str(self.sshresponse))
-			elif self.sshresponse == 2:
-				# Checking if we are really on the remote client defined by its IP address
-				self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', '\$', 5)
-				result = re.search(str(ipaddress), str(self.ssh.before))
-				if result is None:
-					self.close()
-				else:
-					count = 10
-					connect_status = True
-			else:
-				# debug output
-				logging.debug(str(self.ssh.before))
-				logging.debug('self.sshresponse = ' + str(self.sshresponse))
-			# adding a tempo when failure
-			if not connect_status:
-				time.sleep(1)
-			count += 1
-		if connect_status:
-			pass
-		else:
-			sys.exit('SSH Connection Failed')
-
-	def command(self, commandline, expectedline, timeout):
-		logging.debug(commandline)
-		self.ssh.timeout = timeout
-		self.ssh.sendline(commandline)
-		self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
-		if self.sshresponse == 0:
-			return 0
-		elif self.sshresponse == 1:
-			logging.debug('\u001B[1;37;41m Unexpected EOF \u001B[0m')
-			logging.debug('Expected Line : ' + expectedline)
-			logging.debug(str(self.ssh.before))
-			sys.exit(self.sshresponse)
-		elif self.sshresponse == 2:
-			logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m')
-			logging.debug('Expected Line : ' + expectedline)
-			result = re.search('ping |iperf |picocom', str(commandline))
-			if result is None:
-				logging.debug(str(self.ssh.before))
-				sys.exit(self.sshresponse)
-			else:
-				return -1
-		else:
-			logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m')
-			logging.debug('Expected Line : ' + expectedline)
-			sys.exit(self.sshresponse)
-
-	def close(self):
-		self.ssh.timeout = 5
-		self.ssh.sendline('exit')
-		self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
-		if self.sshresponse == 0:
-			pass
-		elif self.sshresponse == 1:
-			if not self.picocom_closure:
-				logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m')
-		else:
-			logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m')
-
-	def copyin(self, ipaddress, username, password, source, destination):
-		count = 0
-		copy_status = False
-		logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
-		while count < 10:
-			scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
-			scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-			if scp_response == 0:
-				scp_spawn.sendline('yes')
-				scp_spawn.expect('password:')
-				scp_spawn.sendline(password)
-				scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if scp_response == 0:
-					count = 10
-					copy_status = True
-				else:
-					logging.debug('1 - scp_response = ' + str(scp_response))
-			elif scp_response == 1:
-				scp_spawn.sendline(password)
-				scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if scp_response == 0 or scp_response == 3:
-					count = 10
-					copy_status = True
-				else:
-					logging.debug('2 - scp_response = ' + str(scp_response))
-			elif scp_response == 2:
-				count = 10
-				copy_status = True
-			else:
-				logging.debug('3 - scp_response = ' + str(scp_response))
-			# adding a tempo when failure
-			if not copy_status:
-				time.sleep(1)
-			count += 1
-		if copy_status:
-			return 0
-		else:
-			return -1
-
-	def copyout(self, ipaddress, username, password, source, destination):
-		count = 0
-		copy_status = False
-		logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
-		while count < 4:
-			scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
-			scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-			if scp_response == 0:
-				scp_spawn.sendline('yes')
-				scp_spawn.expect('password:')
-				scp_spawn.sendline(password)
-				scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if scp_response == 0:
-					count = 10
-					copy_status = True
-				else:
-					logging.debug('1 - scp_response = ' + str(scp_response))
-			elif scp_response == 1:
-				scp_spawn.sendline(password)
-				scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
-				if scp_response == 0 or scp_response == 3:
-					count = 10
-					copy_status = True
-				else:
-					logging.debug('2 - scp_response = ' + str(scp_response))
-			elif scp_response == 2:
-				count = 10
-				copy_status = True
-			else:
-				logging.debug('3 - scp_response = ' + str(scp_response))
-			# adding a tempo when failure
-			if not copy_status:
-				time.sleep(1)
-			count += 1
-		if copy_status:
-			pass
-		else:
-			sys.exit('SCP failed')
-
-	def BuildeNB(self):
-		if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		if self.eNB_serverId == '0':
-			lIpAddr = self.eNBIPAddress
-			lUserName = self.eNBUserName
-			lPassWord = self.eNBPassword
-			lSourcePath = self.eNBSourceCodePath
-		elif self.eNB_serverId == '1':
-			lIpAddr = self.eNB1IPAddress
-			lUserName = self.eNB1UserName
-			lPassWord = self.eNB1Password
-			lSourcePath = self.eNB1SourceCodePath
-		elif self.eNB_serverId == '2':
-			lIpAddr = self.eNB2IPAddress
-			lUserName = self.eNB2UserName
-			lPassWord = self.eNB2Password
-			lSourcePath = self.eNB2SourceCodePath
-		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(lIpAddr, lUserName, lPassWord)
-		result = re.search('--gNB', self.Build_eNB_args)
-		if result is not None:
-			self.air_interface = 'nr'
-		else:
-			self.air_interface = 'lte'
-		if self.Build_eNB_forced_workspace_cleanup:
-			self.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
-		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
-		if result is not None:
-			full_ran_repo_name = self.ranRepository
-		else:
-			full_ran_repo_name = self.ranRepository + '.git'
-		self.command('mkdir -p ' + lSourcePath, '\$', 5)
-		self.command('cd ' + lSourcePath, '\$', 5)
-		self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
-		# Raphael: here add a check if git clone or git fetch went smoothly
-		self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
-		self.command('git config user.name "OAI Jenkins"', '\$', 5)
-		# Checking the BUILD INFO file
-		if not self.backgroundBuild:
-			self.command('ls *.txt', '\$', 5)
-			result = re.search('LAST_BUILD_INFO', str(self.ssh.before))
-			if result is not None:
-				mismatch = False
-				self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2)
-				result = re.search(self.ranCommitID, str(self.ssh.before))
-				if result is None:
-					mismatch = True
-				self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
-				if (self.ranAllowMerge):
-					result = re.search('YES', str(self.ssh.before))
-					if result is None:
-						mismatch = True
-					self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
-					if self.ranTargetBranch == '':
-						result = re.search('develop', str(self.ssh.before))
-					else:
-						result = re.search(self.ranTargetBranch, str(self.ssh.before))
-					if result is None:
-						mismatch = True
-				else:
-					result = re.search('NO', str(self.ssh.before))
-					if result is None:
-						mismatch = True
-				if not mismatch:
-					self.close()
-					self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
-					return
-
-		self.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30)
-		# if the commit ID is provided use it to point to it
-		if self.ranCommitID != '':
-			self.command('git checkout -f ' + self.ranCommitID, '\$', 5)
-		# if the branch is not develop, then it is a merge request and we need to do 
-		# the potential merge. Note that merge conflicts should already been checked earlier
-		if (self.ranAllowMerge):
-			if self.ranTargetBranch == '':
-				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
-					self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
-			else:
-				logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
-				self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
-		self.command('source oaienv', '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('mkdir -p log', '\$', 5)
-		self.command('chmod 777 log', '\$', 5)
-		# no need to remove in log (git clean did the trick)
-		if self.backgroundBuild:
-			self.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5)
-			self.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5)
-			self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5)
-			self.close()
-			self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
-			self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id
-			return
-		self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500)
-		self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id)
-
-	def WaitBuildeNBisFinished(self):
-		if self.eNB_serverId == '0':
-			lIpAddr = self.eNBIPAddress
-			lUserName = self.eNBUserName
-			lPassWord = self.eNBPassword
-			lSourcePath = self.eNBSourceCodePath
-		elif self.eNB_serverId == '1':
-			lIpAddr = self.eNB1IPAddress
-			lUserName = self.eNB1UserName
-			lPassWord = self.eNB1Password
-			lSourcePath = self.eNB1SourceCodePath
-		elif self.eNB_serverId == '2':
-			lIpAddr = self.eNB2IPAddress
-			lUserName = self.eNB2UserName
-			lPassWord = self.eNB2Password
-			lSourcePath = self.eNB2SourceCodePath
-		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(lIpAddr, lUserName, lPassWord)
-		count = 40
-		buildOAIprocess = True
-		while (count > 0) and buildOAIprocess:
-			self.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3)
-			result = re.search('build_oai', str(self.ssh.before))
-			if result is None:
-				buildOAIprocess = False
-			else:
-				count -= 1
-				time.sleep(30)
-		self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)])
-
-	def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId):
-		self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3)
-		self.command('ls ran_build/build', '\$', 3)
-		self.command('ls ran_build/build', '\$', 3)
-		if self.air_interface == 'nr':
-			nodeB_prefix = 'g'
-		else:
-			nodeB_prefix = 'e'
-		buildStatus = True
-		result = re.search(self.air_interface + '-softmodem', str(self.ssh.before))
-		if result is None:
-			buildStatus = False
-		else:
-			# Generating a BUILD INFO file
-			self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
-			self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-			if (self.ranAllowMerge):
-				self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-				if self.ranTargetBranch == '':
-					self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-				else:
-					self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-			else:
-				self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-		self.command('mkdir -p build_log_' + testcaseId, '\$', 5)
-		self.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5)
-		self.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5)
-		if self.eNB_serverId != '0':
-			self.command('cd cmake_targets', '\$', 5)
-			self.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5)
-			self.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5)
-			self.close()
-			if (os.path.isfile('./tmp_build' + testcaseId + '.zip')):
-				os.remove('./tmp_build' + testcaseId + '.zip')
-			self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/tmp_build' + testcaseId + '.zip', '.')
-			if (os.path.isfile('./tmp_build' + testcaseId + '.zip')):
-				self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './tmp_build' + testcaseId + '.zip', self.eNBSourceCodePath + '/cmake_targets/.')
-				os.remove('./tmp_build' + testcaseId + '.zip')
-				self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
-				self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
-				self.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
-				self.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5)
-				self.close()
-		else:
-			self.close()
-
-		if buildStatus:
-			logging.info('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Pass\u001B[0m')
-			self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
-		else:
-			logging.error('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Failed\u001B[0m')
-			self.CreateHtmlTestRow(self.Build_eNB_args, 'KO', ALL_PROCESSES_OK)
-			self.CreateHtmlTabFooter(False)
-			sys.exit(1)
 
 	def BuildOAIUE(self):
 		if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 		result = re.search('--nrUE', self.Build_OAI_UE_args)
 		if result is not None:
-			self.air_interface = 'nr'
+			RAN.Setair_interface('nr')
 			ue_prefix = 'NR '
 		else:
-			self.air_interface = 'lte'
+			RAN.Setair_interface('lte')
 			ue_prefix = ''
 		result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
 		if result is not None:
 			full_ran_repo_name = self.ranRepository
 		else:
 			full_ran_repo_name = self.ranRepository + '.git'
-		self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
-		self.command('cd ' + self.UESourceCodePath, '\$', 5)
-		self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
+		SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
+		SSH.command('cd ' + self.UESourceCodePath, '\$', 5)
+		SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
 		# here add a check if git clone or git fetch went smoothly
-		self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
-		self.command('git config user.name "OAI Jenkins"', '\$', 5)
+		SSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
+		SSH.command('git config user.name "OAI Jenkins"', '\$', 5)
 		if self.clean_repository:
-			self.command('ls *.txt', '\$', 5)
-			result = re.search('LAST_BUILD_INFO', str(self.ssh.before))
+			SSH.command('ls *.txt', '\$', 5)
+			result = re.search('LAST_BUILD_INFO', SSH.getBefore())
 			if result is not None:
 				mismatch = False
-				self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2)
-				result = re.search(self.ranCommitID, str(self.ssh.before))
+				SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2)
+				result = re.search(self.ranCommitID, SSH.getBefore())
 				if result is None:
 					mismatch = True
-				self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
-				if (self.ranAllowMerge):
-					result = re.search('YES', str(self.ssh.before))
+				SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
+				if self.ranAllowMerge:
+					result = re.search('YES', SSH.getBefore())
 					if result is None:
 						mismatch = True
-					self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
+					SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
 					if self.ranTargetBranch == '':
-						result = re.search('develop', str(self.ssh.before))
+						result = re.search('develop', SSH.getBefore())
 					else:
-						result = re.search(self.ranTargetBranch, str(self.ssh.before))
+						result = re.search(self.ranTargetBranch, SSH.getBefore())
 					if result is None:
 						mismatch = True
 				else:
-					result = re.search('NO', str(self.ssh.before))
+					result = re.search('NO', SSH.getBefore())
 					if result is None:
 						mismatch = True
 				if not mismatch:
-					self.close()
-					self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
+					SSH.close()
+					HTML.CreateHtmlTestRow(RAN.GetBuild_eNB_args(), 'OK', CONST.ALL_PROCESSES_OK)
 					return
 
-			self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
 
 		# if the commit ID is provided use it to point to it
 		if self.ranCommitID != '':
-			self.command('git checkout -f ' + self.ranCommitID, '\$', 5)
+			SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5)
 		# if the branch is not develop, then it is a merge request and we need to do 
 		# the potential merge. Note that merge conflicts should already been checked earlier
-		if (self.ranAllowMerge):
+		if self.ranAllowMerge:
 			if self.ranTargetBranch == '':
 				if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'):
-					self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
+					SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
 			else:
 				logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
-				self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
-		self.command('source oaienv', '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('mkdir -p log', '\$', 5)
-		self.command('chmod 777 log', '\$', 5)
+				SSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
+		SSH.command('source oaienv', '\$', 5)
+		SSH.command('cd cmake_targets', '\$', 5)
+		SSH.command('mkdir -p log', '\$', 5)
+		SSH.command('chmod 777 log', '\$', 5)
 		# no need to remove in log (git clean did the trick)
-		self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 600)
-		self.command('ls ran_build/build', '\$', 3)
-		self.command('ls ran_build/build', '\$', 3)
+		SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 900)
+		SSH.command('ls ran_build/build', '\$', 3)
+		SSH.command('ls ran_build/build', '\$', 3)
 		buildStatus = True
-		result = re.search(self.air_interface + '-uesoftmodem', str(self.ssh.before))
+		result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore())
 		if result is None:
 			buildStatus = False
-		self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
-		self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
-		self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5)
+		SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
+		SSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
+		SSH.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5)
 		if buildStatus:
 			# Generating a BUILD INFO file
-			self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
-			self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-			if (self.ranAllowMerge):
-				self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+			SSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
+			SSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+			if self.ranAllowMerge:
+				SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2)
 				if self.ranTargetBranch == '':
-					self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+					SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2)
 				else:
-					self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+					SSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
 			else:
-				self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
-			self.close()
-			self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
+				SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+			SSH.close()
+			HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE')
 		else:
-			self.close()
+			SSH.close()
 			logging.error('\u001B[1m Building OAI UE Failed\u001B[0m')
-			self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE')
-			self.CreateHtmlTabFooter(False)
+			HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE')
+			HTML.CreateHtmlTabFooter(False)
 			sys.exit(1)
-
-	def InitializeHSS(self):
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			logging.debug('Using the OAI EPC Release 14 Cassandra-based HSS')
-			self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-			logging.debug('\u001B[1m Launching tshark on all interfaces \u001B[0m')
-			EPC_PcapFileName = 'epc_' + self.testCase_id + '.pcap'
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f ' + EPC_PcapFileName, '\$', 5)
-			self.command('echo $USER; nohup sudo tshark -f "tcp port not 22 and port not 53" -i any -w ' + self.EPCSourceCodePath + '/scripts/' + EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S mkdir -p logs', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss_' + self.testCase_id + '.log logs/hss*.*', '\$', 5)
-			self.command('echo "oai_hss -j /usr/local/etc/oai/hss_rel14.json" > ./my-hss.sh', '\$', 5)
-			self.command('chmod 755 ./my-hss.sh', '\$', 5)
-			self.command('sudo daemon --unsafe --name=hss_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/hss_' + self.testCase_id + '.log ./my-hss.sh', '\$', 5)
-		elif re.match('OAI', self.EPCType, re.IGNORECASE):
-			logging.debug('Using the OAI EPC HSS')
-			self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-			self.command('source oaienv', '\$', 5)
-			self.command('cd scripts', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			logging.debug('Using the ltebox simulated HSS')
-			self.command('if [ -d ' + self.EPCSourceCodePath + '/scripts ]; then echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5)
-			self.command('mkdir -p ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-			self.command('cd /opt/hss_sim0609', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f hss.log daemon.log', '\$', 5)
-			# based on Robert's feedback, new method to run simulated HSS
-			self.command('sudo su -c "cd /opt/hss_sim0609 && screen -dm -S simulated_hss ./starthss_real"', '\$', 5)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-		self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK)
-
-	def InitializeMME(self):
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			logging.debug('Using the OAI EPC Release 14 MME')
-			self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f mme_' + self.testCase_id + '.log', '\$', 5)
-			self.command('echo "./run_mme --config-file /usr/local/etc/oai/mme.conf --set-virt-if" > ./my-mme.sh', '\$', 5)
-			self.command('chmod 755 ./my-mme.sh', '\$', 5)
-			self.command('sudo daemon --unsafe --name=mme_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/mme_' + self.testCase_id + '.log ./my-mme.sh', '\$', 5)
-		elif re.match('OAI', self.EPCType, re.IGNORECASE):
-			self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-			self.command('source oaienv', '\$', 5)
-			self.command('cd scripts', '\$', 5)
-			self.command('stdbuf -o0 hostname', '\$', 5)
-			result = re.search('hostname\\\\r\\\\n(?P<host_name>[a-zA-Z0-9\-\_]+)\\\\r\\\\n', str(self.ssh.before))
-			if result is None:
-				logging.debug('\u001B[1;37;41m Hostname Not Found! \u001B[0m')
-				sys.exit(1)
-			host_name = result.group('host_name')
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cd /opt/ltebox/tools', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-		self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK)
-
-	def InitializeSPGW(self):
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			logging.debug('Using the OAI EPC Release 14 SPGW-CUPS')
-			self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f spgwc_' + self.testCase_id + '.log spgwu_' + self.testCase_id + '.log', '\$', 5)
-			self.command('echo "spgwc -c /usr/local/etc/oai/spgw_c.conf" > ./my-spgwc.sh', '\$', 5)
-			self.command('chmod 755 ./my-spgwc.sh', '\$', 5)
-			self.command('sudo daemon --unsafe --name=spgwc_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwc_' + self.testCase_id + '.log ./my-spgwc.sh', '\$', 5)
-			time.sleep(5)
-			self.command('echo "spgwu -c /usr/local/etc/oai/spgw_u.conf" > ./my-spgwu.sh', '\$', 5)
-			self.command('chmod 755 ./my-spgwu.sh', '\$', 5)
-			self.command('sudo daemon --unsafe --name=spgwu_daemon --chdir=' + self.EPCSourceCodePath + '/scripts -o ' + self.EPCSourceCodePath + '/scripts/spgwu_' + self.testCase_id + '.log ./my-spgwu.sh', '\$', 5)
-		elif re.match('OAI', self.EPCType, re.IGNORECASE):
-			self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-			self.command('source oaienv', '\$', 5)
-			self.command('cd scripts', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cd /opt/ltebox/tools', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-		self.CreateHtmlTestRow(self.EPCType, 'OK', ALL_PROCESSES_OK)
-
+	
 	def CheckFlexranCtrlInstallation(self):
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '':
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
 			return
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5)
-		result = re.search('/opt/flexran_rtc/build/rt_controller', str(self.ssh.before))
+		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5)
+		result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore())
 		if result is not None:
-			self.flexranCtrlInstalled = True
+			RAN.SetflexranCtrlInstalled(True)
 			logging.debug('Flexran Controller is installed')
-		self.close()
+		SSH.close()
 
 	def InitializeFlexranCtrl(self):
-		if self.flexranCtrlInstalled == False:
+		if RAN.GetflexranCtrlInstalled() == False:
 			return
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '':
-			Usage()
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd /opt/flexran_rtc', '\$', 5)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f log/*.log', '\$', 5)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5)
-		self.command('ps -aux | grep --color=never rt_controller', '\$', 5)
-		result = re.search('rt_controller -c ', str(self.ssh.before))
+		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.command('cd /opt/flexran_rtc', '\$', 5)
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S rm -f log/*.log', '\$', 5)
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5)
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5)
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5)
+		SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5)
+		result = re.search('rt_controller -c ', SSH.getBefore())
 		if result is not None:
 			logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m')
-			self.flexranCtrlStarted = True
-		self.close()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-
-	def InitializeeNB(self):
-		if self.eNB_serverId == '0':
-			lIpAddr = self.eNBIPAddress
-			lUserName = self.eNBUserName
-			lPassWord = self.eNBPassword
-			lSourcePath = self.eNBSourceCodePath
-		elif self.eNB_serverId == '1':
-			lIpAddr = self.eNB1IPAddress
-			lUserName = self.eNB1UserName
-			lPassWord = self.eNB1Password
-			lSourcePath = self.eNB1SourceCodePath
-		elif self.eNB_serverId == '2':
-			lIpAddr = self.eNB2IPAddress
-			lUserName = self.eNB2UserName
-			lPassWord = self.eNB2Password
-			lSourcePath = self.eNB2SourceCodePath
-		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		check_eNB = False
-		check_OAI_UE = False
-		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
-		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus)
-			self.CreateHtmlTabFooter(False)
-			sys.exit(1)
-		# If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB
-		result = re.search('T_stdout', str(self.Initialize_eNB_args))
-		if result is not None:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5)
-			result = re.search('interfaceToUse=(?P<eth_interface>[a-zA-Z0-9\-\_]+)done', str(self.ssh.before))
-			if result is not None:
-				eth_interface = result.group('eth_interface')
-				logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m')
-				self.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap'
-				self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/' + self.EPC_PcapFileName, '\$', 5)
-				self.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -w /tmp/' + self.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5)
-			self.close()
-		self.open(lIpAddr, lUserName, lPassWord)
-		self.command('cd ' + lSourcePath, '\$', 5)
-		# Initialize_eNB_args usually start with -O and followed by the location in repository
-		full_config_file = self.Initialize_eNB_args.replace('-O ','')
-		extra_options = ''
-		extIdx = full_config_file.find('.conf')
-		if (extIdx > 0):
-			extra_options = full_config_file[extIdx + 5:]
-			# if tracer options is on, compiling and running T Tracer
-			result = re.search('T_stdout', str(extra_options))
-			if result is not None:
-				logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m')
-				self.command('cd common/utils/T/tracer', '\$', 5)
-				self.command('make', '\$', 10)
-				self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5)
-				self.command('cd ' + lSourcePath, '\$', 5)
-			full_config_file = full_config_file[:extIdx + 5]
-			config_path, config_file = os.path.split(full_config_file)
-		else:
-			sys.exit('Insufficient Parameter')
-		ci_full_config_file = config_path + '/ci-' + config_file
-		rruCheck = False
-		result = re.search('^rru|^rcc|^du.band', str(config_file))
-		if result is not None:
-			rruCheck = True
-		# do not reset board twice in IF4.5 case
-		result = re.search('^rru|^enb|^du.band', str(config_file))
-		if result is not None:
-			self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60)
-			result = re.search('type: b200', str(self.ssh.before))
-			if result is not None:
-				logging.debug('Found a B2xx device --> resetting it')
-				self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
-				# Reloading FGPA bin firmware
-				self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60)
-		# Make a copy and adapt to EPC / eNB IP addresses
-		self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
-		self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
-		self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
-		self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
-		self.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
-		self.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
-		if self.flexranCtrlInstalled and self.flexranCtrlStarted:
-			self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED        = "yes";/\' ' + ci_full_config_file, '\$', 2);
-		else:
-			self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED        = "no";/\' ' + ci_full_config_file, '\$', 2);
-		self.eNBmbmsEnables[int(self.eNB_instance)] = False
-		self.command('grep enable_enb_m2 ' + ci_full_config_file, '\$', 2);
-		result = re.search('yes', str(self.ssh.before))
-		if result is not None:
-			self.eNBmbmsEnables[int(self.eNB_instance)] = True
-			logging.debug('\u001B[1m MBMS is enabled on this eNB\u001B[0m')
-		result = re.search('noS1', str(self.Initialize_eNB_args))
-		eNBinNoS1 = False
-		if result is not None:
-			eNBinNoS1 = True
-			logging.debug('\u001B[1m eNB is in noS1 configuration \u001B[0m')
-		# Launch eNB with the modified config file
-		self.command('source oaienv', '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
-		self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
-		self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
-		self.command('hostnamectl','\$', 5)
-		result = re.search('CentOS Linux 7', str(self.ssh.before))
-		if result is not None:
-			self.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
-		else:
-			self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
-		self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
-		if extra_options != '':
-			self.eNBOptions[int(self.eNB_instance)] = extra_options
-		time.sleep(6)
-		doLoop = True
-		loopCounter = 20
-		enbDidSync = False
-		while (doLoop):
-			loopCounter = loopCounter - 1
-			if (loopCounter == 0):
-				# In case of T tracer recording, we may need to kill it
-				result = re.search('T_stdout', str(self.Initialize_eNB_args))
-				if result is not None:
-					self.command('killall --signal SIGKILL record', '\$', 5)
-				self.close()
-				doLoop = False
-				logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m')
-				self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK)
-				# In case of T tracer recording, we need to kill tshark on EPC side
-				result = re.search('T_stdout', str(self.Initialize_eNB_args))
-				if result is not None:
-					self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-					logging.debug('\u001B[1m Stopping tshark \u001B[0m')
-					self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
-					if self.EPC_PcapFileName != '':
-						time.sleep(0.5)
-						self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5)
-					self.close()
-					time.sleep(1)
-					if self.EPC_PcapFileName != '':
-						copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.')
-						if (copyin_res == 0):
-							self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.')
-				self.prematureExit = True
-				return
-			else:
-				self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4)
-				if rruCheck:
-					result = re.search('wait RUs', str(self.ssh.before))
-				else:
-					result = re.search('got sync|Starting F1AP at CU', str(self.ssh.before))
-				if result is None:
-					time.sleep(6)
-				else:
-					doLoop = False
-					enbDidSync = True
-					time.sleep(10)
-
-		if enbDidSync and eNBinNoS1:
-			self.command('ifconfig oaitun_enb1', '\$', 4)
-			self.command('ifconfig oaitun_enb1', '\$', 4)
-			result = re.search('inet addr:1|inet 1', str(self.ssh.before))
-			if result is not None:
-				logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m')
-			else:
-				logging.error('\u001B[1m oaitun_enb1 interface is either NOT mounted or NOT configured\u001B[0m')
-			if self.eNBmbmsEnables[int(self.eNB_instance)]:
-				self.command('ifconfig oaitun_enm1', '\$', 4)
-				result = re.search('inet addr', str(self.ssh.before))
-				if result is not None:
-					logging.debug('\u001B[1m oaitun_enm1 interface is mounted and configured\u001B[0m')
-				else:
-					logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m')
-		if enbDidSync:
-			self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId)
-
-		self.close()
-		self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK)
-		logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
-
+			RAN.SetflexranCtrlStarted(True)
+		SSH.close()
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+	
 	def InitializeUE_common(self, device_id, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			if not self.ADBCentralized:
 				# Reboot UE
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60)
 				# Wait
 				#time.sleep(60)
 				# Put in LTE-Mode only
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60)
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60)
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60)
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60)
 				# enable data service
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
 				# we need to do radio on/off cycle to make sure of above changes
 				# airplane mode off // radio on
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
 				#time.sleep(10)
 				# airplane mode on // radio off
-				#self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
+				#SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
 
 				# normal procedure without reboot
 				# enable data service
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
 				# airplane mode on // radio off
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
-				self.close()
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
+				SSH.close()
 				return
 			# enable data service
-			self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
+			SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
 
 			# The following commands are deprecated since we no longer work on Android 7+
-			# self.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
-			# self.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
+			# SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
+			# SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
 			# a dedicated script has to be installed inside the UE
 			# airplane mode on means call /data/local/tmp/off
 			if device_id == '84B7N16418004022':
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
 			else:
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
 			#airplane mode off means call /data/local/tmp/on
 			logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def InitializeUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		multi_jobs = []
 		i = 0
@@ -1011,62 +299,62 @@ class SSHConnection():
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def InitializeOAIUE(self):
 		if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		if self.air_interface == 'lte':
+		if RAN.Getair_interface() == 'lte':
 			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 			if result is None:
 				check_eNB = True
 				check_OAI_UE = False
 				pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 				if (pStatus < 0):
-					self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus)
-					self.CreateHtmlTabFooter(False)
+					HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus)
+					HTML.CreateHtmlTabFooter(False)
 					sys.exit(1)
 			UE_prefix = ''
 		else:
 			UE_prefix = 'NR '
-		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
 		# b2xx_fx3_utils reset procedure
-		self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
-		result = re.search('type: b200', str(self.ssh.before))
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
+		result = re.search('type: b200', SSH.getBefore())
 		if result is not None:
 			logging.debug('Found a B2xx device --> resetting it')
-			self.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
 			# Reloading FGPA bin firmware
-			self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
-		result = re.search('type: n3xx', str(self.ssh.before))
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60)
+		result = re.search('type: n3xx', str(SSH.getBefore()))
 		if result is not None:
 			logging.debug('Found a N3xx device --> resetting it')
-		self.command('cd ' + self.UESourceCodePath, '\$', 5)
+		SSH.command('cd ' + self.UESourceCodePath, '\$', 5)
 		# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
 		# in case of NR-UE, we may have rrc_config_path (Temporary?)
 		modifiedUeOptions = str(self.Initialize_OAI_UE_args)
-		if self.air_interface == 'nr':
+		if RAN.Getair_interface() == 'nr':
 			result = re.search('--rrc_config_path ', modifiedUeOptions)
 			if result is not None:
 				modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/')
-		self.command('source oaienv', '\$', 5)
-		self.command('cd cmake_targets/ran_build/build', '\$', 5)
-		if self.air_interface == 'lte':
+		SSH.command('source oaienv', '\$', 5)
+		SSH.command('cd cmake_targets/ran_build/build', '\$', 5)
+		if RAN.Getair_interface() == 'lte':
 			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
 			# We may have to regenerate the .u* files
 			if result is None:
-				self.command('ls /tmp/*.sed', '\$', 5)
-				result = re.search('adapt_usim_parameters', str(self.ssh.before))
+				SSH.command('ls /tmp/*.sed', '\$', 5)
+				result = re.search('adapt_usim_parameters', SSH.getBefore())
 				if result is not None:
-					self.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
+					SSH.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
 				else:
-					self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
-				self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5)
-				self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5)
-		self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
-		self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
-		self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
+					SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
+				SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5)
+				SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5)
+		SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
 		self.UELogFile = 'ue_' + self.testCase_id + '.log'
 
 		# We are now looping several times to hope we really sync w/ an eNB
@@ -1075,13 +363,13 @@ class SSHConnection():
 		gotSyncStatus = True
 		fullSyncStatus = True
 		while (doOutterLoop):
-			self.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5)
-			self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
+			SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5)
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
 			#use nohup instead of daemon
-			#self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
-			self.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
+			#SSH.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+			SSH.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
 			time.sleep(6)
-			self.command('cd ../..', '\$', 5)
+			SSH.command('cd ../..', '\$', 5)
 			doLoop = True
 			loopCounter = 10
 			gotSyncStatus = True
@@ -1094,11 +382,11 @@ class SSHConnection():
 					gotSyncStatus = False
 					doLoop = False
 					continue
-				self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4)
-				if self.air_interface == 'nr':
-					result = re.search('Starting sync detection', str(self.ssh.before))
+				SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4)
+				if RAN.Getair_interface() == 'nr':
+					result = re.search('Starting sync detection', SSH.getBefore())
 				else:
-					result = re.search('got sync', str(self.ssh.before))
+					result = re.search('got sync', SSH.getBefore())
 				if result is None:
 					time.sleep(10)
 				else:
@@ -1106,33 +394,60 @@ class SSHConnection():
 					logging.debug('Found "got sync" message!')
 			if gotSyncStatus == False:
 				# we certainly need to stop the lte-uesoftmodem process if it is still running!
-				self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4)
-				result = re.search('-uesoftmodem', str(self.ssh.before))
+				SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4)
+				result = re.search('-uesoftmodem', SSH.getBefore())
 				if result is not None:
-					self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4)
+					SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4)
 					time.sleep(3)
 				outterLoopCounter = outterLoopCounter - 1
 				if (outterLoopCounter == 0):
 					doOutterLoop = False
 				continue
-			if self.air_interface == 'nr':
-				fullSyncStatus = True
-				doOutterLoop = False
+			# We are now checking if sync w/ eNB DOES NOT OCCUR
+			# Usually during the cell synchronization stage, the UE returns with No cell synchronization message
+			# That is the case for LTE
+			# In NR case, it's a positive message that will show if synchronization occurs
+			doLoop = True
+			if RAN.Getair_interface() == 'nr':
+				loopCounter = 10
 			else:
 				# We are now checking if sync w/ eNB DOES NOT OCCUR
 				# Usually during the cell synchronization stage, the UE returns with No cell synchronization message
-				doLoop = True
 				loopCounter = 10
-				while (doLoop):
-					loopCounter = loopCounter - 1
-					if (loopCounter == 0):
+			while (doLoop):
+				loopCounter = loopCounter - 1
+				if (loopCounter == 0):
+					if RAN.Getair_interface() == 'nr':
+						# Here we do have great chances that UE did NOT cell-sync w/ gNB
+						doLoop = False
+						fullSyncStatus = False
+						logging.debug('Never seen the NR-Sync message (Measured Carrier Frequency) --> try again')
+						time.sleep(6)
+						# Stopping the NR-UE  
+						SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4)
+						result = re.search('nr-uesoftmodem', SSH.getBefore())
+						if result is not None:
+							SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT nr-uesoftmodem', '\$', 4)
+						time.sleep(6)
+					else:
 						# Here we do have a great chance that the UE did cell-sync w/ eNB
 						doLoop = False
 						doOutterLoop = False
 						fullSyncStatus = True
 						continue
-					self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4)
-					result = re.search('No cell synchronization found', str(self.ssh.before))
+				SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4)
+				if RAN.Getair_interface() == 'nr':
+					# Positive messaging -->
+					result = re.search('Measured Carrier Frequency', SSH.getBefore())
+					if result is not None:
+						doLoop = False
+						doOutterLoop = False
+						fullSyncStatus = True
+					else:
+						time.sleep(6)
+				else:
+					# Negative messaging -->
+					result = re.search('No cell synchronization found', SSH.getBefore())
 					if result is None:
 						time.sleep(6)
 					else:
@@ -1140,31 +455,40 @@ class SSHConnection():
 						fullSyncStatus = False
 						logging.debug('Found: "No cell synchronization" message! --> try again')
 						time.sleep(6)
-						self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4)
-						result = re.search('lte-uesoftmodem', str(self.ssh.before))
+						SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4)
+						result = re.search('lte-uesoftmodem', SSH.getBefore())
 						if result is not None:
-							self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4)
-				outterLoopCounter = outterLoopCounter - 1
-				if (outterLoopCounter == 0):
-					doOutterLoop = False
+							SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4)
+			outterLoopCounter = outterLoopCounter - 1
+			if (outterLoopCounter == 0):
+				doOutterLoop = False
 
-		if fullSyncStatus and gotSyncStatus and self.air_interface == 'lte':
-			result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
-			if result is None:
-				self.command('ifconfig oaitun_ue1', '\$', 4)
-				self.command('ifconfig oaitun_ue1', '\$', 4)
+		if fullSyncStatus and gotSyncStatus:
+			doInterfaceCheck = False
+			if RAN.Getair_interface() == 'lte':
+				result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args))
+				if result is None:
+					doInterfaceCheck = True
+			# For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface)
+			if RAN.Getair_interface() == 'nr':
+				result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args))
+				if result is not None:
+					doInterfaceCheck = True
+			if doInterfaceCheck:
+				SSH.command('ifconfig oaitun_ue1', '\$', 4)
+				SSH.command('ifconfig oaitun_ue1', '\$', 4)
 				# ifconfig output is different between ubuntu 16 and ubuntu 18
-				result = re.search('inet addr:1|inet 1', str(self.ssh.before))
+				result = re.search('inet addr:1|inet 1', SSH.getBefore())
 				if result is not None:
 					logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m')
 					tunnelInterfaceStatus = True
 				else:
-					logging.debug(str(self.ssh.before))
+					logging.debug(SSH.getBefore())
 					logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m')
 					tunnelInterfaceStatus = False
-				if self.eNBmbmsEnables[0]:
-					self.command('ifconfig oaitun_uem1', '\$', 4)
-					result = re.search('inet addr', str(self.ssh.before))
+				if RAN.GeteNBmbmsEnable(0):
+					SSH.command('ifconfig oaitun_uem1', '\$', 4)
+					result = re.search('inet addr', SSH.getBefore())
 					if result is not None:
 						logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m')
 						tunnelInterfaceStatus = tunnelInterfaceStatus and True
@@ -1176,116 +500,116 @@ class SSHConnection():
 		else:
 			tunnelInterfaceStatus = True
 
-		self.close()
+		SSH.close()
 		if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus:
-			self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
+			HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE')
 			logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m')
 			if (self.ADBIPAddress != 'none'):
 				self.UEDevices = []
 				self.UEDevices.append('OAI-UE')
 				self.UEDevicesStatus = []
-				self.UEDevicesStatus.append(UE_STATUS_DETACHED)
+				self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED)
 		else:
-			if self.air_interface == 'lte':
-				if self.eNBmbmsEnables[0]:
-					self.htmlUEFailureMsg = 'oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured'
+			if RAN.Getair_interface() == 'lte':
+				if RAN.GeteNBmbmsEnable(0):
+					HTML.SethtmlUEFailureMsg('oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured')
 				else:
-					self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured'
-				self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
+					HTML.SethtmlUEFailureMsg('oaitun_ue1 interface is either NOT mounted or NOT configured')
+				HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
 			else:
-				self.htmlUEFailureMsg = 'nr-uesoftmodem did NOT synced'
-				self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
+				HTML.SethtmlUEFailureMsg('nr-uesoftmodem did NOT synced')
+				HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE')
 			logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
 			self.AutoTerminateUEandeNB()
 
 	def checkDevTTYisUnlocked(self):
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		count = 0
 		while count < 5:
-			self.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10)
-			result = re.search('picocom', str(self.ssh.before))
+			SSH.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10)
+			result = re.search('picocom', SSH.getBefore())
 			if result is None:
 				count = 10
 			else:
 				time.sleep(5)
 				count = count + 1
-		self.close()
+		SSH.close()
 
 	def InitializeCatM(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.picocom_closure = True
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.enablePicocomClosure()
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		# dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S`
-		self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
-		self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
+		SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
+		SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
 		time.sleep(1)
 		# Calling twice AT to clear all buffers
-		self.command('AT', 'OK|ERROR', 5)
-		self.command('AT', 'OK', 5)
+		SSH.command('AT', 'OK|ERROR', 5)
+		SSH.command('AT', 'OK', 5)
 		# Doing a power cycle
-		self.command('AT^RESET', 'SIMSTORE,READY', 15)
-		self.command('AT', 'OK|ERROR', 5)
-		self.command('AT', 'OK', 5)
-		self.command('ATE1', 'OK', 5)
+		SSH.command('AT^RESET', 'SIMSTORE,READY', 15)
+		SSH.command('AT', 'OK|ERROR', 5)
+		SSH.command('AT', 'OK', 5)
+		SSH.command('ATE1', 'OK', 5)
 		# Disabling the Radio
-		self.command('AT+CFUN=0', 'OK', 5)
+		SSH.command('AT+CFUN=0', 'OK', 5)
 		logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m')
 		# Checking if auto-attach is enabled
-		self.command('AT^AUTOATT?', 'OK', 5)
-		result = re.search('AUTOATT: (?P<state>[0-9\-]+)', str(self.ssh.before))
+		SSH.command('AT^AUTOATT?', 'OK', 5)
+		result = re.search('AUTOATT: (?P<state>[0-9\-]+)', SSH.getBefore())
 		if result is not None:
 			if result.group('state') is not None:
 				autoAttachState = int(result.group('state'))
 				if autoAttachState is not None:
 					if autoAttachState == 0:
-						self.command('AT^AUTOATT=1', 'OK', 5)
+						SSH.command('AT^AUTOATT=1', 'OK', 5)
 					logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m')
 		else:
 			logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m')
 		# Force closure of picocom but device might still be locked
-		self.close()
-		self.picocom_closure = False
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		SSH.close()
+		SSH.disablePicocomClosure()
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 		self.checkDevTTYisUnlocked()
 
 	def TerminateCatM(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.picocom_closure = True
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.enablePicocomClosure()
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		# dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S`
-		self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
-		self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
+		SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
+		SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
 		time.sleep(1)
 		# Calling twice AT to clear all buffers
-		self.command('AT', 'OK|ERROR', 5)
-		self.command('AT', 'OK', 5)
+		SSH.command('AT', 'OK|ERROR', 5)
+		SSH.command('AT', 'OK', 5)
 		# Disabling the Radio
-		self.command('AT+CFUN=0', 'OK', 5)
+		SSH.command('AT+CFUN=0', 'OK', 5)
 		logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m')
-		self.close()
-		self.picocom_closure = False
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		SSH.close()
+		SSH.disablePicocomClosure()
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 		self.checkDevTTYisUnlocked()
 
 	def AttachCatM(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.picocom_closure = True
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.enablePicocomClosure()
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		# dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S`
-		self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
-		self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
+		SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10)
+		SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10)
 		time.sleep(1)
 		# Calling twice AT to clear all buffers
-		self.command('AT', 'OK|ERROR', 5)
-		self.command('AT', 'OK', 5)
+		SSH.command('AT', 'OK|ERROR', 5)
+		SSH.command('AT', 'OK', 5)
 		# Enabling the Radio
-		self.command('AT+CFUN=1', 'SIMSTORE,READY', 5)
+		SSH.command('AT+CFUN=1', 'SIMSTORE,READY', 5)
 		logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m')
 		time.sleep(4)
 		# We should check if we register
@@ -1293,15 +617,15 @@ class SSHConnection():
 		attach_cnt = 0
 		attach_status = False
 		while count < 5:
-			self.command('AT+CEREG?', 'OK', 5)
-			result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', str(self.ssh.before))
+			SSH.command('AT+CEREG?', 'OK', 5)
+			result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', SSH.getBefore())
 			if result is not None:
 				mDataConnectionState = int(result.group('state'))
 				if mDataConnectionState is not None:
 					if mDataConnectionState == 1:
 						count = 10
 						attach_status = True
-						result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', str(self.ssh.before))
+						result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', SSH.getBefore())
 						if result is not None:
 							networky = result.group('networky')
 							networkz = result.group('networkz')
@@ -1312,21 +636,21 @@ class SSHConnection():
 						logging.debug('+CEREG: 2,' + str(mDataConnectionState))
 						attach_cnt = attach_cnt + 1
 			else:
-				logging.debug(str(self.ssh.before))
+				logging.debug(SSH.getBefore())
 				attach_cnt = attach_cnt + 1
 			count = count + 1
 			time.sleep(1)
 		if attach_status:
-			self.command('AT+CESQ', 'OK', 5)
-			result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', str(self.ssh.before))
+			SSH.command('AT+CESQ', 'OK', 5)
+			result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', SSH.getBefore())
 			if result is not None:
 				nRSRQ = int(result.group('rsrq'))
 				nRSRP = int(result.group('rsrp'))
 				if (nRSRQ is not None) and (nRSRP is not None):
 					logging.debug('    RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB')
 					logging.debug('    RSRP = ' + str(-140+nRSRP) + ' dBm')
-		self.close()
-		self.picocom_closure = False
+		SSH.close()
+		SSH.disablePicocomClosure()
 		html_queue = SimpleQueue()
 		self.checkDevTTYisUnlocked()
 		if attach_status:
@@ -1337,74 +661,74 @@ class SSHConnection():
 			else:
 				html_cell += '</pre>'
 			html_queue.put(html_cell)
-			self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue)
+			HTML.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue)
 		else:
 			logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m')
 			html_cell = '<pre style="background-color:white">CAT-M module Attachment Failed</pre>'
 			html_queue.put(html_cell)
-			self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
+			HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
 			self.AutoTerminateUEandeNB()
 
 	def PingCatM(self):
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '':
-			Usage()
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
+			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		try:
 			statusQueue = SimpleQueue()
 			lock = Lock()
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-			self.command('cd scripts', '\$', 5)
-			if re.match('OAI', self.EPCType, re.IGNORECASE):
+			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+			SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+			SSH.command('cd scripts', '\$', 5)
+			if re.match('OAI', EPC.GetType(), re.IGNORECASE):
 				logging.debug('Using the OAI EPC HSS: not implemented yet')
-				self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
-				self.CreateHtmlTabFooter(False)
+				HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
+				HTML.CreateHtmlTabFooter(False)
 				sys.exit(1)
 			else:
-				self.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5)
-				result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', str(self.ssh.before))
+				SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5)
+				result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', SSH.getBefore())
 				if result is not None:
 					moduleIPAddr = result.group('ipaddr')
 				else:
-					self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
+					HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
 					self.AutoTerminateUEandeNB()
 					return
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
 			device_id = 'catm'
-			ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
+			ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
 			# TIMEOUT CASE
 			if ping_status < 0:
 				message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
 				return
-			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before))
+			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore())
 			if result is None:
 				message = 'Packet Loss Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
 				return
 			packetloss = result.group('packetloss')
 			if float(packetloss) == 100:
 				message = 'Packet Loss is 100%'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
 				return
-			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before))
+			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore())
 			if result is None:
 				message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
 				return
 			rtt_min = result.group('rtt_min')
@@ -1431,37 +755,37 @@ class SSHConnection():
 					qMsg += '\nPacket Loss is not 0%'
 					logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m')
 			lock.release()
-			self.close()
+			SSH.close()
 			html_cell = '<pre style="background-color:white">CAT-M module\nIP Address  : ' + moduleIPAddr + '\n' + qMsg + '</pre>'
 			statusQueue.put(html_cell)
 			if (packetLossOK):
-				self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
 			else:
-				self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
 				self.AutoTerminateUEandeNB()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def AttachUE_common(self, device_id, statusQueue, lock, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			if self.ADBCentralized:
 				if device_id == '84B7N16418004022':
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
 				else:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
 			else:
 				# airplane mode off // radio on
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
 			time.sleep(2)
 			max_count = 45
 			count = max_count
 			while count > 0:
 				if self.ADBCentralized:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15)
 				else:
-					self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60)
-				result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before))
+					SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60)
+				result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore())
 				if result is None:
 					logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m')
 					lock.acquire()
@@ -1484,19 +808,19 @@ class SSHConnection():
 					logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m')
 					if self.ADBCentralized:
 						if device_id == '84B7N16418004022':
-							self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+							SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
 						else:
-							self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+							SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
 					else:
-						self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
+						SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
 					time.sleep(0.5)
 					if self.ADBCentralized:
 						if device_id == '84B7N16418004022':
-							self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
+							SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
 						else:
-							self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
+							SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
 					else:
-						self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
+						SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60)
 					time.sleep(0.5)
 				logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m')
 				time.sleep(1)
@@ -1507,19 +831,19 @@ class SSHConnection():
 				statusQueue.put(device_id)
 				statusQueue.put('Attach Failed')
 				lock.release()
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def AttachUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow('N/A', 'KO', pStatus)
+			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		multi_jobs = []
@@ -1528,7 +852,7 @@ class SSHConnection():
 		nb_ue_to_connect = 0
 		for device_id in self.UEDevices:
 			if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach):
-				self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING
+				self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING
 				p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,))
 				p.daemon = True
 				p.start()
@@ -1538,7 +862,7 @@ class SSHConnection():
 			job.join()
 
 		if (status_queue.empty()):
-			self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
 			self.AutoTerminateUEandeNB()
 			return
 		else:
@@ -1558,48 +882,48 @@ class SSHConnection():
 			if (attach_status):
 				cnt = 0
 				while cnt < len(self.UEDevices):
-					if self.UEDevicesStatus[cnt] == UE_STATUS_ATTACHING:
-						self.UEDevicesStatus[cnt] = UE_STATUS_ATTACHED
+					if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING:
+						self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED
 					cnt += 1
-				self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
-				result = re.search('T_stdout', str(self.Initialize_eNB_args))
+				HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+				result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args()))
 				if result is not None:
 					logging.debug('Waiting 5 seconds to fill up record file')
 					time.sleep(5)
 			else:
-				self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
 				self.AutoTerminateUEandeNB()
 
 	def DetachUE_common(self, device_id, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			if self.ADBCentralized:
 				if device_id == '84B7N16418004022':
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
 				else:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
 			logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m')
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def DetachUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow('N/A', 'KO', pStatus)
+			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		multi_jobs = []
 		cnt = 0
 		for device_id in self.UEDevices:
-			self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING
+			self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING
 			p = Process(target = self.DetachUE_common, args = (device_id,cnt,))
 			p.daemon = True
 			p.start()
@@ -1607,37 +931,37 @@ class SSHConnection():
 			cnt += 1
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-		result = re.search('T_stdout', str(self.Initialize_eNB_args))
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+		result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args()))
 		if result is not None:
 			logging.debug('Waiting 5 seconds to fill up record file')
 			time.sleep(5)
 		cnt = 0
 		while cnt < len(self.UEDevices):
-			self.UEDevicesStatus[cnt] = UE_STATUS_DETACHED
+			self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED
 			cnt += 1
 
 	def RebootUE_common(self, device_id):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			previousmDataConnectionStates = []
 			# Save mDataConnectionState
-			self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
-			self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
-			result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before))
+			SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
+			SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
+			result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore())
 			if result is None:
 				logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m')
 				sys.exit(1)
 			previousmDataConnectionStates.append(int(result.group('state')))
 			# Reboot UE
-			self.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10)
+			SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10)
 			time.sleep(60)
 			previousmDataConnectionState = previousmDataConnectionStates.pop(0)
 			count = 180
 			while count > 0:
 				count = count - 1
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
-				result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', str(self.ssh.before))
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15)
+				result = re.search('mDataConnectionState.*=(?P<state>[0-9\-]+)', SSH.getBefore())
 				if result is None:
 					mDataConnectionState = None
 				else:
@@ -1652,20 +976,20 @@ class SSHConnection():
 			if count == 0:
 				logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m')
 				sys.exit(1)
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def RebootUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow('N/A', 'KO', pStatus)
-			self.CreateHtmlTabFooter(False)
+			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
+			HTML.CreateHtmlTabFooter(False)
 			sys.exit(1)
 		multi_jobs = []
 		for device_id in self.UEDevices:
@@ -1675,24 +999,24 @@ class SSHConnection():
 			multi_jobs.append(p)
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def DataDisableUE_common(self, device_id, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			# disable data service
 			if self.ADBCentralized:
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60)
 			logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m')
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def DataDisableUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		multi_jobs = []
 		i = 0
@@ -1704,24 +1028,24 @@ class SSHConnection():
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def DataEnableUE_common(self, device_id, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			# enable data service
 			if self.ADBCentralized:
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60)
 			logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m')
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def DataEnableUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		multi_jobs = []
 		i = 0
@@ -1733,25 +1057,26 @@ class SSHConnection():
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def GetAllUEDevices(self, terminate_ue_flag):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		if self.ADBCentralized:
-			self.command('adb devices', '\$', 15)
-			self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",str(self.ssh.before))
-			self.close()
+			SSH.command('adb devices', '\$', 15)
+			#self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore())
+			self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore())
+			SSH.close()
 		else:
 			if (os.path.isfile('./phones_list.txt')):
 				os.remove('./phones_list.txt')
-			self.command('ls /etc/*/phones*.txt', '\$', 5)
-			result = re.search('/etc/ci/phones_list.txt', str(self.ssh.before))
-			self.close()
+			SSH.command('ls /etc/*/phones*.txt', '\$', 5)
+			result = re.search('/etc/ci/phones_list.txt', SSH.getBefore())
+			SSH.close()
 			if (result is not None) and (len(self.UEDevices) == 0):
-				self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.')
+				SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.')
 				if (os.path.isfile('./phones_list.txt')):
 					phone_list_file = open('./phones_list.txt', 'r')
 					for line in phone_list_file.readlines():
@@ -1768,46 +1093,47 @@ class SSHConnection():
 						self.UEDevicesRebootCmd.append(comma_split[5])
 					phone_list_file.close()
 
-		if terminate_ue_flag == False:
+		if terminate_ue_flag == True:
 			if len(self.UEDevices) == 0:
 				logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m')
 				sys.exit(1)
 		if len(self.UEDevicesStatus) == 0:
 			cnt = 0
 			while cnt < len(self.UEDevices):
-				self.UEDevicesStatus.append(UE_STATUS_DETACHED)
+				self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED)
 				cnt += 1
 
 	def GetAllCatMDevices(self, terminate_ue_flag):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		if self.ADBCentralized:
-			self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15)
-			self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before))
+			SSH.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15)
+			#self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore())
+			self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore())
 		else:
 			if (os.path.isfile('./modules_list.txt')):
 				os.remove('./modules_list.txt')
-			self.command('ls /etc/*/modules*.txt', '\$', 5)
-			result = re.search('/etc/ci/modules_list.txt', str(self.ssh.before))
-			self.close()
+			SSH.command('ls /etc/*/modules*.txt', '\$', 5)
+			result = re.search('/etc/ci/modules_list.txt', SSH.getBefore())
+			SSH.close()
 			if result is not None:
 				logging.debug('Found a module list file on ADB server')
-		if terminate_ue_flag == False:
+		if terminate_ue_flag == True:
 			if len(self.CatMDevices) == 0:
 				logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m')
 				sys.exit(1)
-		self.close()
+		SSH.close()
 
 	def CheckUEStatus_common(self, lock, device_id, statusQueue, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			if self.ADBCentralized:
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60)
-			result = re.search('mServiceState=(?P<serviceState>[0-9]+)', str(self.ssh.before))
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60)
+			result = re.search('mServiceState=(?P<serviceState>[0-9]+)', SSH.getBefore())
 			serviceState = 'Service State: UNKNOWN'
 			if result is not None:
 				lServiceState = int(result.group('serviceState'))
@@ -1819,7 +1145,7 @@ class SSHConnection():
 					serviceState = 'Service State: IN_SERVICE'
 				if lServiceState == 2:
 					serviceState = 'Service State: EMERGENCY_ONLY'
-			result = re.search('mDataConnectionState=(?P<dataConnectionState>[0-9]+)', str(self.ssh.before))
+			result = re.search('mDataConnectionState=(?P<dataConnectionState>[0-9]+)', SSH.getBefore())
 			dataConnectionState = 'Data State:    UNKNOWN'
 			if result is not None:
 				lDataConnectionState = int(result.group('dataConnectionState'))
@@ -1831,7 +1157,7 @@ class SSHConnection():
 					dataConnectionState = 'Data State:    CONNECTED'
 				if lDataConnectionState == 3:
 					dataConnectionState = 'Data State:    SUSPENDED'
-			result = re.search('mDataConnectionReason=(?P<dataConnectionReason>[0-9a-zA-Z_]+)', str(self.ssh.before))
+			result = re.search('mDataConnectionReason=(?P<dataConnectionReason>[0-9a-zA-Z_]+)', SSH.getBefore())
 			dataConnectionReason = 'Data Reason:   UNKNOWN'
 			if result is not None:
 				dataConnectionReason = 'Data Reason:   ' + result.group('dataConnectionReason')
@@ -1845,20 +1171,20 @@ class SSHConnection():
 			qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason
 			statusQueue.put(qMsg)
 			lock.release()
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def CheckStatusUE(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow('N/A', 'KO', pStatus)
-			self.CreateHtmlTabFooter(False)
+			HTML.CreateHtmlTestRow('N/A', 'KO', pStatus)
+			HTML.CreateHtmlTabFooter(False)
 			sys.exit(1)
 		multi_jobs = []
 		lock = Lock()
@@ -1872,12 +1198,12 @@ class SSHConnection():
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		if self.flexranCtrlInstalled and self.flexranCtrlStarted:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('cd /opt/flexran_rtc', '\$', 5)
-			self.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5)
-			self.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5)
-			result = re.search('Nb Connected UE = (?P<nb_ues>[0-9]+)', str(self.ssh.before))
+		if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
+			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+			SSH.command('cd /opt/flexran_rtc', '\$', 5)
+			SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5)
+			SSH.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5)
+			result = re.search('Nb Connected UE = (?P<nb_ues>[0-9]+)', SSH.getBefore())
 			passStatus = True
 			if result is not None:
 				nb_ues = int(result.group('nb_ues'))
@@ -1888,13 +1214,13 @@ class SSHConnection():
 						passStatus = False
 			else:
 				htmlOptions = 'N/A'
-			self.close()
+			SSH.close()
 		else:
 			passStatus = True
 			htmlOptions = 'N/A'
 
 		if (status_queue.empty()):
-			self.CreateHtmlTestRow(htmlOptions, 'KO', ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK)
 			self.AutoTerminateUEandeNB()
 		else:
 			check_status = True
@@ -1908,24 +1234,24 @@ class SSHConnection():
 				html_cell = '<pre style="background-color:white">UE (' + device_id + ')\n' + message + '</pre>'
 				html_queue.put(html_cell)
 			if check_status and passStatus:
-				self.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue)
 			else:
-				self.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
 				self.AutoTerminateUEandeNB()
 
 	def GetAllUEIPAddresses(self):
 		if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		ue_ip_status = 0
 		self.UEIPAddresses = []
 		if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'):
 			if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
-				Usage()
+				HELP.GenericHelp(CONST.Version)
 				sys.exit('Insufficient Parameter')
-			self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-			self.command('ifconfig oaitun_ue1', '\$', 4)
-			result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P<ueipaddress2>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before))
+			SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+			SSH.command('ifconfig oaitun_ue1', '\$', 4)
+			result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P<ueipaddress2>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', SSH.getBefore())
 			if result is not None:
 				if result.group('ueipaddress') is not None:
 					UE_IPAddress = result.group('ueipaddress')
@@ -1936,21 +1262,21 @@ class SSHConnection():
 			else:
 				logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m')
 				ue_ip_status -= 1
-			self.close()
+			SSH.close()
 			return ue_ip_status
-		self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+		SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 		idx = 0
 		for device_id in self.UEDevices:
-			if self.UEDevicesStatus[idx] != UE_STATUS_ATTACHED:
+			if self.UEDevicesStatus[idx] != CONST.UE_STATUS_ATTACHED:
 				idx += 1
 				continue
 			count = 0
 			while count < 4:
 				if self.ADBCentralized:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15)
 				else:
-					self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60)
-				result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', str(self.ssh.before))
+					SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60)
+				result = re.search('inet (?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', SSH.getBefore())
 				if result is None:
 					logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m')
 					time.sleep(1)
@@ -1969,7 +1295,7 @@ class SSHConnection():
 					continue
 			self.UEIPAddresses.append(UE_IPAddress)
 			idx += 1
-		self.close()
+		SSH.close()
 		return ue_ip_status
 
 	def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message):
@@ -1985,50 +1311,50 @@ class SSHConnection():
 			# Launch ping on the EPC side (true for ltebox and old open-air-cn)
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
+			if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
 				launchFromEpc = False
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
 
 			if launchFromEpc:
-				self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-				self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-				self.command('cd scripts', '\$', 5)
-				ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
+				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+				SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+				SSH.command('cd scripts', '\$', 5)
+				ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
 			else:
 				cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' 
 				message = cmd + '\n'
 				logging.debug(cmd)
 				ret = subprocess.run(cmd, shell=True)
 				ping_status = ret.returncode
-				self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
-				self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-				self.command('cat ' + self.EPCSourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+				SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			# TIMEOUT CASE
 			if ping_status < 0:
 				message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 				return
-			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before))
+			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore())
 			if result is None:
 				message = 'Packet Loss Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 				return
 			packetloss = result.group('packetloss')
 			if float(packetloss) == 100:
 				message = 'Packet Loss is 100%'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 				return
-			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before))
+			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore())
 			if result is None:
 				message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-				self.close()
+				SSH.close()
 				self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 				return
 			rtt_min = result.group('rtt_min')
@@ -2062,7 +1388,7 @@ class SSHConnection():
 			statusQueue.put(UE_IPAddress)
 			statusQueue.put(qMsg)
 			lock.release()
-			self.close()
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
@@ -2070,41 +1396,41 @@ class SSHConnection():
 		html_queue = SimpleQueue()
 		html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>'
 		html_queue.put(html_cell)
-		self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
+		HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
 
 	def PingNoS1(self):
 		check_eNB = True
 		check_OAI_UE = True
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
+			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args))
 		if ping_from_eNB is not None:
-			if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '':
-				Usage()
+			if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '':
+				HELP.GenericHelp(CONST.Version)
 				sys.exit('Insufficient Parameter')
 		else:
 			if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
-				Usage()
+				HELP.GenericHelp(CONST.Version)
 				sys.exit('Insufficient Parameter')
 		try:
 			if ping_from_eNB is not None:
-				self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
-				self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5)
+				SSH.open(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword())
+				SSH.command('cd ' + RAN.GeteNBSourceCodePath() + '/cmake_targets/', '\$', 5)
 			else:
-				self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-				self.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5)
+				SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+				SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5)
 			ping_time = re.findall("-c (\d+)",str(self.ping_args))
-			ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5)
+			ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5)
 			# TIMEOUT CASE
 			if ping_status < 0:
 				message = 'Ping with OAI UE crashed due to TIMEOUT!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
 				self.PingNoS1_wrong_exit(message)
 				return
-			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before))
+			result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore())
 			if result is None:
 				message = 'Packet Loss Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
@@ -2116,7 +1442,7 @@ class SSHConnection():
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
 				self.PingNoS1_wrong_exit(message)
 				return
-			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before))
+			result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore())
 			if result is None:
 				message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!'
 				logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
@@ -2144,33 +1470,33 @@ class SSHConnection():
 				elif float(packetloss) > 0:
 					qMsg += '\nPacket Loss is not 0%'
 					logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m')
-			self.close()
+			SSH.close()
 			html_queue = SimpleQueue()
 			ip_addr = 'TBD'
 			html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>'
 			html_queue.put(html_cell)
 			if packetLossOK:
-				self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
 			else:
-				self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
 
 			# copying on the EPC server for logCollection
 			if ping_from_eNB is not None:
-				copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
+				copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
 			else:
-				copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
+				copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.')
 			if (copyin_res == 0):
-				self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '.log', self.EPCSourceCodePath + '/scripts')
+				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '.log', EPC.GetSourceCodePath() + '/scripts')
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def Ping(self):
-		result = re.search('noS1', str(self.Initialize_eNB_args))
+		result = re.search('noS1', str(RAN.GetInitialize_eNB_args()))
 		if result is not None:
 			self.PingNoS1()
 			return
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '':
-			Usage()
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'):
@@ -2179,12 +1505,12 @@ class SSHConnection():
 			check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
+			HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		ueIpStatus = self.GetAllUEIPAddresses()
 		if (ueIpStatus < 0):
-			self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE)
+			HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
 			self.AutoTerminateUEandeNB()
 			return
 		multi_jobs = []
@@ -2202,7 +1528,7 @@ class SSHConnection():
 			job.join()
 
 		if (status_queue.empty()):
-			self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK)
 			self.AutoTerminateUEandeNB()
 		else:
 			ping_status = True
@@ -2217,9 +1543,9 @@ class SSHConnection():
 				html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '</pre>'
 				html_queue.put(html_cell)
 			if (ping_status):
-				self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue)
 			else:
-				self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
 				self.AutoTerminateUEandeNB()
 
 	def Iperf_ComputeTime(self):
@@ -2255,8 +1581,8 @@ class SSHConnection():
 		return result
 
 	def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options):
-		self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
-		result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', str(self.ssh.before))
+		SSH.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+		result = re.search('Avg Bitrate : (?P<average>[0-9\.]+ Mbits\/sec) Max Bitrate : (?P<maximum>[0-9\.]+ Mbits\/sec) Min Bitrate : (?P<minimum>[0-9\.]+ Mbits\/sec)', SSH.getBefore())
 		if result is not None:
 			avgbitrate = result.group('average')
 			maxbitrate = result.group('maximum')
@@ -2285,9 +1611,9 @@ class SSHConnection():
 		if result is None:
 			return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options)
 
-		result = re.search('Server Report:', str(self.ssh.before))
+		result = re.search('Server Report:', SSH.getBefore())
 		if result is None:
-			result = re.search('read failed: Connection refused', str(self.ssh.before))
+			result = re.search('read failed: Connection refused', SSH.getBefore())
 			if result is not None:
 				logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m')
 			else:
@@ -2311,7 +1637,7 @@ class SSHConnection():
 				req_bandwidth = '%.1f Gbits/sec' % req_bw
 				req_bw = req_bw * 1000000000
 
-		result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', str(self.ssh.before))
+		result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore())
 		if result is not None:
 			bitrate = result.group('bitrate')
 			packetloss = result.group('packetloss')
@@ -2462,9 +1788,9 @@ class SSHConnection():
 
 
 	def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue):
-		result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', str(self.ssh.before))
+		result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore())
 		if result is None:
-			result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', str(self.ssh.before))
+			result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore())
 			lock.acquire()
 			statusQueue.put(-1)
 			statusQueue.put(device_id)
@@ -2513,7 +1839,7 @@ class SSHConnection():
 		# Launch iperf server on EPC side (true for ltebox and old open-air-cn0
 		# But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address
 		launchFromEpc = True
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
+		if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
 			launchFromEpc = False
 			cmd = 'hostname -I'
 			ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
@@ -2521,14 +1847,14 @@ class SSHConnection():
 				EPC_Iperf_UE_IPAddress = ret.stdout.strip()
 		port = 5001 + idx
 		if launchFromEpc:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-			self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+			SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
+			SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			if udpIperf:
-				self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5)
+				SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5)
 			else:
-				self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5)
-			self.close()
+				SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5)
+			SSH.close()
 		else:
 			if self.ueIperfVersion == self.dummyIperfVersion:
 				prefix = ''
@@ -2546,11 +1872,11 @@ class SSHConnection():
 
 		# Launch iperf client on UE
 		if (device_id == 'OAI-UE'):
-			self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-			self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
+			SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+			SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
 		else:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
-			self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
 		iperf_time = self.Iperf_ComputeTime()
 		time.sleep(0.5)
 
@@ -2561,50 +1887,50 @@ class SSHConnection():
 		modified_options = modified_options.replace('-R','')
 		time.sleep(0.5)
 
-		self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+		SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 		if (device_id == 'OAI-UE'):
-			iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
+			iperf_status = SSH.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
 		else:
 			if self.ADBCentralized:
-				iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
+				iperf_status = SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
 			else:
-				iperf_status = self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
-				self.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
-				self.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				iperf_status = SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
+				SSH.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				SSH.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 		# TIMEOUT Case
 		if iperf_status < 0:
-			self.close()
+			SSH.close()
 			message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !'
 			logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-			self.close()
+			SSH.close()
 			self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 			return
 		clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options)
-		self.close()
+		SSH.close()
 
 		# Kill iperf server on EPC side
 		if launchFromEpc:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('killall --signal SIGKILL iperf', self.EPCUserName, 5)
-			self.close()
+			SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+			SSH.command('killall --signal SIGKILL iperf', EPC.GetUserName(), 5)
+			SSH.close()
 		else:
 			cmd = 'killall --signal SIGKILL iperf'
 			logging.debug(cmd)
 			subprocess.run(cmd, shell=True)
 			time.sleep(1)
-			self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
+			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
 		# in case of failure, retrieve server log
 		if (clientStatus == -1) or (clientStatus == -2):
 			if launchFromEpc:
 				time.sleep(1)
 				if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
 					os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log')
-				self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+				SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 			self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options)
 		# in case of OAI-UE 
 		if (device_id == 'OAI-UE'):
-			self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
-			self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
+			SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.')
+			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
 
 	def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue):
 		try:
@@ -2616,48 +1942,48 @@ class SSHConnection():
 
 			self.ueIperfVersion = '2.0.5'
 			if (device_id != 'OAI-UE'):
-				self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+				SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 				# if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it
-				self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5)
-				self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
+				SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + EPC.GetSourceCodePath() + '/scripts ; fi', '\$', 5)
+				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
 				# Checking if iperf / iperf3 are installed
 				if self.ADBCentralized:
-					self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5)
+					SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5)
 				else:
-					self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60)
-				result = re.search('iperf3', str(self.ssh.before))
+					SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60)
+				result = re.search('iperf3', SSH.getBefore())
 				if result is None:
-					result = re.search('iperf', str(self.ssh.before))
+					result = re.search('iperf', SSH.getBefore())
 					if result is None:
 						message = 'Neither iperf nor iperf3 installed on UE!'
 						logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
-						self.close()
+						SSH.close()
 						self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 						return
 					else:
 						if self.ADBCentralized:
-							self.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5)
+							SSH.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5)
 						else:
-							self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60)
-						result = re.search('iperf version 2.0.5', str(self.ssh.before))
+							SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60)
+						result = re.search('iperf version 2.0.5', SSH.getBefore())
 						if result is not None:
 							self.ueIperfVersion = '2.0.5'
-						result = re.search('iperf version 2.0.10', str(self.ssh.before))
+						result = re.search('iperf version 2.0.10', SSH.getBefore())
 						if result is not None:
 							self.ueIperfVersion = '2.0.10'
 				else:
 					useIperf3 = True
-				self.close()
+				SSH.close()
 			else:
-				self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-				self.command('iperf --version', '\$', 5)
-				result = re.search('iperf version 2.0.5', str(self.ssh.before))
+				SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+				SSH.command('iperf --version', '\$', 5)
+				result = re.search('iperf version 2.0.5', SSH.getBefore())
 				if result is not None:
 					self.ueIperfVersion = '2.0.5'
-				result = re.search('iperf version 2.0.10', str(self.ssh.before))
+				result = re.search('iperf version 2.0.10', SSH.getBefore())
 				if result is not None:
 					self.ueIperfVersion = '2.0.10'
-				self.close()
+				SSH.close()
 			# in case of iperf, UL has its own function
 			if (not useIperf3):
 				result = re.search('-R', str(self.iperf_args))
@@ -2667,44 +1993,44 @@ class SSHConnection():
 
 			# Launch the IPERF server on the UE side for DL
 			if (device_id == 'OAI-UE'):
-				self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-				self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
-				self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+				SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
+				SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 				result = re.search('-u', str(self.iperf_args))
 				if result is None:
-					self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5)
+					SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5)
 					udpIperf = False
 				else:
-					self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5)
+					SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5)
 			else:
-				self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
-				self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
+				SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
 				if self.ADBCentralized:
 					if (useIperf3):
-						self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5)
+						SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5)
 					else:
-						self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+						SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 						result = re.search('-u', str(self.iperf_args))
 						if result is None:
-							self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5)
+							SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5)
 							udpIperf = False
 						else:
-							self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5)
+							SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5)
 				else:
-					self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
-					self.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60)
+					SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+					SSH.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60)
 
 			time.sleep(0.5)
-			self.close()
+			SSH.close()
 
 			# Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn
 			# But for OAI-Rel14-CUPS, we launch from python executor
 			launchFromEpc = True
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
+			if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE):
 				launchFromEpc = False
 			if launchFromEpc:
-				self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-				self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
+				SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+				SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5)
 			iperf_time = self.Iperf_ComputeTime()
 			time.sleep(0.5)
 
@@ -2715,18 +2041,18 @@ class SSHConnection():
 			time.sleep(0.5)
 
 			if launchFromEpc:
-				self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+				SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 			else:
 				if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')):
 					os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log')
 			if (useIperf3):
-				self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
+				SSH.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
 
 				clientStatus = 0
 				self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue)
 			else:
 				if launchFromEpc:
-					iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
+					iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0)
 				else:
 					if self.ueIperfVersion == self.dummyIperfVersion:
 						prefix = ''
@@ -2739,46 +2065,46 @@ class SSHConnection():
 					logging.debug(cmd)
 					ret = subprocess.run(cmd, shell=True)
 					iperf_status = ret.returncode
-					self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
-					self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-					self.command('cat ' + self.EPCSourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
+					SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
+					SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+					SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5)
 				if iperf_status < 0:
 					if launchFromEpc:
-						self.close()
+						SSH.close()
 					message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !'
 					logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
 					self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message)
 					return
 				clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options)
-			self.close()
+			SSH.close()
 
 			# Kill the IPERF server that runs in background
 			if (device_id == 'OAI-UE'):
-				self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-				self.command('killall iperf', '\$', 5)
+				SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+				SSH.command('killall iperf', '\$', 5)
 			else:
-				self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+				SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 				if self.ADBCentralized:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5)
 				else:
-					self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60)
-				result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before))
+					SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60)
+				result = re.search('shell +(?P<pid>\d+)', SSH.getBefore())
 				if result is not None:
 					pid_iperf = result.group('pid')
 					if self.ADBCentralized:
-						self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5)
+						SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5)
 					else:
-						self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60)
-			self.close()
+						SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60)
+			SSH.close()
 			# if the client report is absent, try to analyze the server log file
 			if (clientStatus == -1):
 				time.sleep(1)
 				if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
 					os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log')
 				if (device_id == 'OAI-UE'):
-					self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+					SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				else:
-					self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+					SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
 				# fromdos has to be called on the python executor not on ADB server
 				cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log'
 				subprocess.run(cmd, shell=True)
@@ -2788,29 +2114,29 @@ class SSHConnection():
 			if (device_id == 'OAI-UE'):
 				if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')):
 					if not launchFromEpc:
-						self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
+						SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
 				else:
-					self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
-					self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts')
+					SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.')
+					SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts')
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def IperfNoS1(self):
-		if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
-			Usage()
+		if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		check_OAI_UE = True
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
+			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		server_on_enb = re.search('-R', str(self.iperf_args))
 		if server_on_enb is not None:
-			iServerIPAddr = self.eNBIPAddress
-			iServerUser = self.eNBUserName
-			iServerPasswd = self.eNBPassword
+			iServerIPAddr = RAN.GeteNBIPAddress()
+			iServerUser = RAN.GeteNBUserName()
+			iServerPasswd = RAN.GeteNBPassword()
 			iClientIPAddr = self.UEIPAddress
 			iClientUser = self.UEUserName
 			iClientPasswd = self.UEPassword
@@ -2818,29 +2144,29 @@ class SSHConnection():
 			iServerIPAddr = self.UEIPAddress
 			iServerUser = self.UEUserName
 			iServerPasswd = self.UEPassword
-			iClientIPAddr = self.eNBIPAddress
-			iClientUser = self.eNBUserName
-			iClientPasswd = self.eNBPassword
+			iClientIPAddr = RAN.GeteNBIPAddress()
+			iClientUser = RAN.GeteNBUserName()
+			iClientPasswd = RAN.GeteNBPassword()
 		if self.iperf_options != 'sink':
 			# Starting the iperf server
-			self.open(iServerIPAddr, iServerUser, iServerPasswd)
+			SSH.open(iServerIPAddr, iServerUser, iServerPasswd)
 			# args SHALL be "-c client -u any"
 			# -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1
 			# -B 10.0.1.1 -u -s -i 1 -fm
 			server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args))
 			server_options = server_options.replace('-c','-B')
-			self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5)
-			self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5)
+			SSH.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5)
+			SSH.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5)
 			time.sleep(0.5)
-			self.close()
+			SSH.close()
 
 		# Starting the iperf client
 		modified_options = self.Iperf_ComputeModifiedBW(0, 1)
 		modified_options = modified_options.replace('-R','')
 		iperf_time = self.Iperf_ComputeTime()
-		self.open(iClientIPAddr, iClientUser, iClientPasswd)
-		self.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5)
-		iperf_status = self.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0)
+		SSH.open(iClientIPAddr, iClientUser, iClientPasswd)
+		SSH.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5)
+		iperf_status = SSH.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0)
 		status_queue = SimpleQueue()
 		lock = Lock()
 		if iperf_status < 0:
@@ -2856,28 +2182,29 @@ class SSHConnection():
 				status_queue.put('Sink Test : no check')
 			else:
 				clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
-		self.close()
+		SSH.close()
 
 		# Stopping the iperf server
 		if self.iperf_options != 'sink':
-			self.open(iServerIPAddr, iServerUser, iServerPasswd)
-			self.command('killall --signal SIGKILL iperf', '\$', 5)
+			SSH.open(iServerIPAddr, iServerUser, iServerPasswd)
+			SSH.command('killall --signal SIGKILL iperf', '\$', 5)
 			time.sleep(0.5)
-			self.close()
+			SSH.close()
+
 		if (clientStatus == -1):
 			if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')):
 				os.remove('iperf_server_' + self.testCase_id + '.log')
-			self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
+			SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
 			self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
 
 		# copying on the EPC server for logCollection
 		if (clientStatus == -1):
-			copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
+			copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
 			if (copyin_res == 0):
-				self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts')
-		copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log')
+				SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts')
+		copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log')
 		if (copyin_res == 0):
-			self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts')
+			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts')
 		iperf_noperf = False
 		if status_queue.empty():
 			iperf_status = False
@@ -2896,20 +2223,20 @@ class SSHConnection():
 			html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '</pre>'
 			html_queue.put(html_cell)
 		if (iperf_noperf and iperf_status):
-			self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue)
+			HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue)
 		elif (iperf_status):
-			self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
+			HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
 		else:
-			self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
+			HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
 			self.AutoTerminateUEandeNB()
 
 	def Iperf(self):
-		result = re.search('noS1', str(self.Initialize_eNB_args))
+		result = re.search('noS1', str(RAN.GetInitialize_eNB_args()))
 		if result is not None:
 			self.IperfNoS1()
 			return
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
-			Usage()
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
 		check_eNB = True
 		if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'):
@@ -2918,12 +2245,13 @@ class SSHConnection():
 			check_OAI_UE = False
 		pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
 		if (pStatus < 0):
-			self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
+			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
 			self.AutoTerminateUEandeNB()
 			return
 		ueIpStatus = self.GetAllUEIPAddresses()
 		if (ueIpStatus < 0):
-			self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE)
+			logging.debug('going here')
+			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE)
 			self.AutoTerminateUEandeNB()
 			return
 
@@ -2945,7 +2273,7 @@ class SSHConnection():
 		status_queue = SimpleQueue()
 		for UE_IPAddress in self.UEIPAddresses:
 			device_id = self.UEDevices[i]
-			p = Process(target = SSH.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,))
+			p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -2954,7 +2282,7 @@ class SSHConnection():
 			job.join()
 
 		if (status_queue.empty()):
-			self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK)
 			self.AutoTerminateUEandeNB()
 		else:
 			iperf_status = True
@@ -2972,11 +2300,11 @@ class SSHConnection():
 				html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '</pre>'
 				html_queue.put(html_cell)
 			if (iperf_noperf and iperf_status):
-				self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue)
 			elif (iperf_status):
-				self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue)
 			else:
-				self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
+				HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
 				self.AutoTerminateUEandeNB()
 
 	def CheckProcessExist(self, check_eNB, check_OAI_UE):
@@ -2984,17 +2312,17 @@ class SSHConnection():
 		status_queue = SimpleQueue()
 		# in noS1 config, no need to check status from EPC
 		# in gNB also currently no need to check
-		result = re.search('noS1|band78', str(self.Initialize_eNB_args))
+		result = re.search('noS1|band78', str(RAN.GetInitialize_eNB_args()))
 		if result is None:
-			p = Process(target = SSH.CheckHSSProcess, args = (status_queue,))
+			p = Process(target = EPC.CheckHSSProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
-			p = Process(target = SSH.CheckMMEProcess, args = (status_queue,))
+			p = Process(target = EPC.CheckMMEProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
-			p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,))
+			p = Process(target = EPC.CheckSPGWProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -3002,12 +2330,12 @@ class SSHConnection():
 			if (check_eNB == False) and (check_OAI_UE == False):
 				return 0
 		if check_eNB:
-			p = Process(target = SSH.CheckeNBProcess, args = (status_queue,))
+			p = Process(target = RAN.CheckeNBProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
 		if check_OAI_UE:
-			p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,))
+			p = Process(target = self.CheckOAIUEProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -3022,15 +2350,15 @@ class SSHConnection():
 				status = status_queue.get()
 				if (status < 0):
 					result = status
-			if result == ENB_PROCESS_FAILED:
-				fileCheck = re.search('enb_', str(self.eNBLogFiles[0]))
+			if result == CONST.ENB_PROCESS_FAILED:
+				fileCheck = re.search('enb_', str(RAN.GeteNBLogFile(0)))
 				if fileCheck is not None:
-					self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFiles[0], '.')
-					logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFiles[0])
+					SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/' + RAN.GeteNBLogFile(0), '.')
+					logStatus = RAN.AnalyzeLogFile_eNB(RAN.GeteNBLogFile[0])
 					if logStatus < 0:
 						result = logStatus
-					self.eNBLogFiles[0] = ''
-				if self.flexranCtrlInstalled and self.flexranCtrlStarted:
+					RAN.SeteNBLogFile('', 0)
+				if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
 					self.TerminateFlexranCtrl()
 			return result
 
@@ -3038,7 +2366,7 @@ class SSHConnection():
 		multi_jobs = []
 		status_queue = SimpleQueue()
 		if initialize_OAI_UE_flag == False:
-			p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,))
+			p = Process(target = self.CheckOAIUEProcess, args = (status_queue,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
@@ -3053,10 +2381,10 @@ class SSHConnection():
 				status = status_queue.get()
 				if (status < 0):
 					result = status
-			if result == OAI_UE_PROCESS_FAILED:
+			if result == CONST.OAI_UE_PROCESS_FAILED:
 				fileCheck = re.search('ue_', str(self.UELogFile))
 				if fileCheck is not None:
-					self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
+					SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
 					logStatus = self.AnalyzeLogFile_UE(self.UELogFile)
 					if logStatus < 0:
 						result = logStatus
@@ -3064,379 +2392,18 @@ class SSHConnection():
 
 	def CheckOAIUEProcess(self, status_queue):
 		try:
-			self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-			self.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-uesoftmodem | grep -v grep', '\$', 5)
-			result = re.search(self.air_interface + '-uesoftmodem', str(self.ssh.before))
+			SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+			SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.Getair_interface() + '-uesoftmodem | grep -v grep', '\$', 5)
+			result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore())
 			if result is None:
 				logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m')
-				status_queue.put(OAI_UE_PROCESS_FAILED)
-			else:
-				status_queue.put(OAI_UE_PROCESS_OK)
-			self.close()
-		except:
-			os.kill(os.getppid(),signal.SIGUSR1)
-
-	def CheckeNBProcess(self, status_queue):
-		try:
-			# At least the instance 0 SHALL be on!
-			if self.eNBstatuses[0] == 0:
-				lIpAddr = self.eNBIPAddress
-				lUserName = self.eNBUserName
-				lPassWord = self.eNBPassword
-			elif self.eNBstatuses[0] == 1:
-				lIpAddr = self.eNB1IPAddress
-				lUserName = self.eNB1UserName
-				lPassWord = self.eNB1Password
-			elif self.eNBstatuses[0] == 2:
-				lIpAddr = self.eNB2IPAddress
-				lUserName = self.eNB2UserName
-				lPassWord = self.eNB2Password
+				status_queue.put(CONST.OAI_UE_PROCESS_FAILED)
 			else:
-				lIpAddr = self.eNBIPAddress
-				lUserName = self.eNBUserName
-				lPassWord = self.eNBPassword
-			self.open(lIpAddr, lUserName, lPassWord)
-			self.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-softmodem | grep -v grep', '\$', 5)
-			result = re.search(self.air_interface + '-softmodem', str(self.ssh.before))
-			if result is None:
-				logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m')
-				status_queue.put(ENB_PROCESS_FAILED)
-			else:
-				status_queue.put(ENB_PROCESS_OK)
-			self.close()
+				status_queue.put(CONST.OAI_UE_PROCESS_OK)
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
-	def CheckHSSProcess(self, status_queue):
-		try:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5)
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-				result = re.search('oai_hss -j', str(self.ssh.before))
-			elif re.match('OAI', self.EPCType, re.IGNORECASE):
-				result = re.search('\/bin\/bash .\/run_', str(self.ssh.before))
-			elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-				result = re.search('hss_sim s6as diam_hss', str(self.ssh.before))
-			else:
-				logging.error('This should not happen!')
-			if result is None:
-				logging.debug('\u001B[1;37;41m HSS Process Not Found! \u001B[0m')
-				status_queue.put(HSS_PROCESS_FAILED)
-			else:
-				status_queue.put(HSS_PROCESS_OK)
-			self.close()
-		except:
-			os.kill(os.getppid(),signal.SIGUSR1)
-
-	def CheckMMEProcess(self, status_queue):
-		try:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5)
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-				result = re.search('mme -c', str(self.ssh.before))
-			elif re.match('OAI', self.EPCType, re.IGNORECASE):
-				result = re.search('\/bin\/bash .\/run_', str(self.ssh.before))
-			elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-				result = re.search('mme', str(self.ssh.before))
-			else:
-				logging.error('This should not happen!')
-			if result is None:
-				logging.debug('\u001B[1;37;41m MME Process Not Found! \u001B[0m')
-				status_queue.put(MME_PROCESS_FAILED)
-			else:
-				status_queue.put(MME_PROCESS_OK)
-			self.close()
-		except:
-			os.kill(os.getppid(),signal.SIGUSR1)
-
-	def CheckSPGWProcess(self, status_queue):
-		try:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-				self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5)
-				result = re.search('spgwu -c ', str(self.ssh.before))
-			elif re.match('OAI', self.EPCType, re.IGNORECASE):
-				self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5)
-				result = re.search('\/bin\/bash .\/run_', str(self.ssh.before))
-			elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-				self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5)
-				result = re.search('xGw', str(self.ssh.before))
-			else:
-				logging.error('This should not happen!')
-			if result is None:
-				logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m')
-				status_queue.put(SPGW_PROCESS_FAILED)
-			else:
-				status_queue.put(SPGW_PROCESS_OK)
-			self.close()
-		except:
-			os.kill(os.getppid(),signal.SIGUSR1)
-
-	def AnalyzeLogFile_eNB(self, eNBlogFile):
-		if (not os.path.isfile('./' + eNBlogFile)):
-			return -1
-		enb_log_file = open('./' + eNBlogFile, 'r')
-		exitSignalReceived = False
-		foundAssertion = False
-		msgAssertion = ''
-		msgLine = 0
-		foundSegFault = False
-		foundRealTimeIssue = False
-		rrcSetupComplete = 0
-		rrcReleaseRequest = 0
-		rrcReconfigRequest = 0
-		rrcReconfigComplete = 0
-		rrcReestablishRequest = 0
-		rrcReestablishComplete = 0
-		rrcReestablishReject = 0
-		rlcDiscardBuffer = 0
-		rachCanceledProcedure = 0
-		uciStatMsgCount = 0
-		pdcpFailure = 0
-		ulschFailure = 0
-		ulschOK = 0
-		cdrxActivationMessageCount = 0
-		dropNotEnoughRBs = 0
-		mbmsRequestMsg = 0
-		self.htmleNBFailureMsg = ''
-		isRRU = False
-		isSlave = False
-		slaveReceivesFrameResyncCmd = False
-		X2HO_state = X2_HO_REQ_STATE__IDLE
-		X2HO_inNbProcedures = 0
-		X2HO_outNbProcedures = 0
-		for line in enb_log_file.readlines():
-			if X2HO_state == X2_HO_REQ_STATE__IDLE:
-				result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ
-				result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK
-			if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ:
-				result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE
-			if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE:
-				result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ
-			if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ:
-				result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__IDLE
-					X2HO_inNbProcedures += 1
-			if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK:
-				result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line))
-				if result is not None:
-					X2HO_state = X2_HO_REQ_STATE__IDLE
-					X2HO_outNbProcedures += 1
-
-			if self.eNBOptions[int(self.eNB_instance)] != '':
-				res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)])
-				res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)',  str(line))
-				if res1 is not None and res2 is not None:
-					requested_option = int(res1.group('requested_option'))
-					applied_option = int(res2.group('applied_option'))
-					if requested_option == applied_option:
-						self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
-					else:
-						self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
-			result = re.search('Exiting OAI softmodem', str(line))
-			if result is not None:
-				exitSignalReceived = True
-			result = re.search('[Ss]egmentation [Ff]ault', str(line))
-			if result is not None and not exitSignalReceived:
-				foundSegFault = True
-			result = re.search('[Cc]ore [dD]ump', str(line))
-			if result is not None and not exitSignalReceived:
-				foundSegFault = True
-			result = re.search('./ran_build/build/lte-softmodem', str(line))
-			if result is not None and not exitSignalReceived:
-				foundSegFault = True
-			result = re.search('[Aa]ssertion', str(line))
-			if result is not None and not exitSignalReceived:
-				foundAssertion = True
-			result = re.search('LLL', str(line))
-			if result is not None and not exitSignalReceived:
-				foundRealTimeIssue = True
-			if foundAssertion and (msgLine < 3):
-				msgLine += 1
-				msgAssertion += str(line)
-			result = re.search('Setting function for RU', str(line))
-			if result is not None:
-				isRRU = True
-			if isRRU:
-				result = re.search('RU 0 is_slave=yes', str(line))
-				if result is not None:
-					isSlave = True
-				if isSlave:
-					result = re.search('Received RRU_frame_resynch command', str(line))
-					if result is not None:
-						slaveReceivesFrameResyncCmd = True
-			result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line))
-			if result is not None:
-				rrcSetupComplete += 1
-			result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line))
-			if result is not None:
-				rrcReleaseRequest += 1
-			result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line))
-			if result is not None:
-				rrcReconfigRequest += 1
-			result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line))
-			if result is not None:
-				rrcReconfigComplete += 1
-			result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line))
-			if result is not None:
-				rrcReestablishRequest += 1
-			result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line))
-			if result is not None:
-				rrcReestablishComplete += 1
-			result = re.search('LTE_RRCConnectionReestablishmentReject', str(line))
-			if result is not None:
-				rrcReestablishReject += 1
-			result = re.search('CDRX configuration activated after RRC Connection', str(line))
-			if result is not None:
-				cdrxActivationMessageCount += 1
-			result = re.search('uci->stat', str(line))
-			if result is not None:
-				uciStatMsgCount += 1
-			result = re.search('PDCP.*Out of Resources.*reason', str(line))
-			if result is not None:
-				pdcpFailure += 1
-			result = re.search('ULSCH in error in round', str(line))
-			if result is not None:
-				ulschFailure += 1
-			if self.air_interface == 'nr':
-				result = re.search('ULSCH received ok', str(line))
-				if result is not None:
-					ulschOK += 1
-			result = re.search('BAD all_segments_received', str(line))
-			if result is not None:
-				rlcDiscardBuffer += 1
-			result = re.search('Canceled RA procedure for UE rnti', str(line))
-			if result is not None:
-				rachCanceledProcedure += 1
-			result = re.search('dropping, not enough RBs', str(line))
-			if result is not None:
-				dropNotEnoughRBs += 1
-			if self.eNBmbmsEnables[int(self.eNB_instance)]:
-				result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line))
-				if result is not None:
-					mbmsRequestMsg += 1
-		enb_log_file.close()
-		logging.debug('   File analysis completed')
-		self.htmleNBFailureMsg = ''
-		if self.air_interface == 'lte':
-			nodeB_prefix = 'e'
-		else:
-			nodeB_prefix = 'g'
-		if uciStatMsgCount > 0:
-			statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
-			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += statMsg + '\n'
-		if pdcpFailure > 0:
-			statMsg = nodeB_prefix + 'NB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)'
-			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += statMsg + '\n'
-		if ulschFailure > 0:
-			statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
-			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += statMsg + '\n'
-		if self.air_interface == 'nr':
-			if ulschOK > 0:
-				statMsg = nodeB_prefix + 'NB showed ' + str(ulschOK) + ' "ULSCH received ok" message(s)'
-				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				self.htmleNBFailureMsg += statMsg + '\n'
-		if dropNotEnoughRBs > 0:
-			statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)'
-			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += statMsg + '\n'
-		if rrcSetupComplete > 0:
-			rrcMsg = nodeB_prefix + 'NB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-			rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if rrcReleaseRequest > 0:
-			rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if rrcReconfigRequest > 0 or rrcReconfigComplete > 0:
-			rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-			rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0:
-			rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-			rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-			rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if self.eNBmbmsEnables[int(self.eNB_instance)]:
-			if mbmsRequestMsg > 0:
-				rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE'
-				logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-				self.htmleNBFailureMsg += rrcMsg + '\n'
-		if X2HO_inNbProcedures > 0:
-			rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if X2HO_outNbProcedures > 0:
-			rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)'
-			logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rrcMsg + '\n'
-		if self.eNBOptions[int(self.eNB_instance)] != '':
-			res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)])
-			if res1 is not None:
-				if cdrxActivationMessageCount > 0:
-					rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)'
-					logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
-					self.htmleNBFailureMsg += rrcMsg + '\n'
-				else:
-					rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration'
-					logging.debug('\u001B[1;37;43m ' + rrcMsg + ' \u001B[0m')
-					self.htmleNBFailureMsg += rrcMsg + '\n'
-		if rachCanceledProcedure > 0:
-			rachMsg = nodeB_prefix + 'NB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)'
-			logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rachMsg + '\n'
-		if isRRU:
-			if isSlave:
-				if slaveReceivesFrameResyncCmd:
-					rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU'
-					logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m')
-					self.htmleNBFailureMsg += rruMsg + '\n'
-				else:
-					rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU'
-					logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m')
-					self.htmleNBFailureMsg += rruMsg + '\n'
-					self.prematureExit = True
-					return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED
-		if foundSegFault:
-			logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with a Segmentation Fault! \u001B[0m')
-			return ENB_PROCESS_SEG_FAULT
-		if foundAssertion:
-			logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with an assertion! \u001B[0m')
-			self.htmleNBFailureMsg += msgAssertion
-			return ENB_PROCESS_ASSERTION
-		if foundRealTimeIssue:
-			logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB faced real time issues! \u001B[0m')
-			self.htmleNBFailureMsg += nodeB_prefix + 'NB faced real time issues!\n'
-			#return ENB_PROCESS_REALTIME_ISSUE
-		if rlcDiscardBuffer > 0:
-			rlcMsg = nodeB_prefix + 'NB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)'
-			logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m')
-			self.htmleNBFailureMsg += rlcMsg + '\n'
-			return ENB_PROCESS_REALTIME_ISSUE
-		return 0
 
 	def AnalyzeLogFile_UE(self, UElogFile):
 		if (not os.path.isfile('./' + UElogFile)):
@@ -3464,7 +2431,7 @@ class SSHConnection():
 		nrFoundDCI = 0
 		nrCRCOK = 0
 		mbms_messages = 0
-		self.htmlUEFailureMsg = ''
+		HTML.SethtmlUEFailureMsg('')
 		for line in ue_log_file.readlines():
 			result = re.search('nr_synchro_time', str(line))
 			if result is not None:
@@ -3525,7 +2492,7 @@ class SSHConnection():
 			result = re.search('No cell synchronization found, abandoning', str(line))
 			if result is not None:
 				no_cell_sync_found = True
-			if self.eNBmbmsEnables[0]:
+			if RAN.GeteNBmbmsEnable(0):
 				result = re.search('TRIED TO PUSH MBMS DATA', str(line))
 				if result is not None:
 					mbms_messages += 1
@@ -3533,22 +2500,22 @@ class SSHConnection():
 			if result is not None and (not mib_found):
 				try:
 					mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2)
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    nidcell = " + result.group('nidcell')
-					self.htmlUEFailureMsg += mibMsg
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg)
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    n_rb_dl = " + result.group('n_rb_dl')
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    phich_duration = " + result.group('phich_duration')
-					self.htmlUEFailureMsg += mibMsg
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg)
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    phich_resource = " + result.group('phich_resource')
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mibMsg = "    tx_ant = " + result.group('tx_ant')
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					mib_found = True
 				except Exception as e:
@@ -3557,7 +2524,7 @@ class SSHConnection():
 			if result is not None and (not frequency_found):
 				try:
 					mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz'
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					frequency_found = True
 				except Exception as e:
@@ -3566,7 +2533,7 @@ class SSHConnection():
 			if result is not None and (not plmn_found):
 				try:
 					mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc')
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 					plmn_found = True
 				except Exception as e:
@@ -3575,7 +2542,7 @@ class SSHConnection():
 			if result is not None:
 				try:
 					mibMsg = "The operator is: " + result.group('operator')
-					self.htmlUEFailureMsg += mibMsg + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "Operator name not found" + '\033[0m')
@@ -3583,7 +2550,7 @@ class SSHConnection():
 			if result is not None:
 				try:
 					mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2)
-					self.htmlUEFailureMsg += mibMsg + ' -> '
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + ' -> ')
 					logging.debug('\033[94m' + mibMsg + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m')
@@ -3593,7 +2560,7 @@ class SSHConnection():
 					freq = result.group('carrier_frequency')
 					new_freq = re.sub('/[0-9]+','',freq)
 					float_freq = float(new_freq) / 1000000
-					self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz'
+					HTMLSethtmlUEFailureMsg(HTMLGethtmlUEFailureMsg() + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz')
 					logging.debug('\033[94m' + "    DL Carrier Frequency is: " + freq + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "    DL Carrier Frequency not found" + '\033[0m')
@@ -3601,7 +2568,7 @@ class SSHConnection():
 			if result is not None:
 				try:
 					prb = result.group('allowed_bandwidth')
-					self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n'
+					HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + ' -- PRB: ' + prb + '\n')
 					logging.debug('\033[94m' + "    AllowedMeasBandwidth: " + prb + '\033[0m')
 				except Exception as e:
 					logging.error('\033[91m' + "    AllowedMeasBandwidth not found" + '\033[0m')
@@ -3609,339 +2576,167 @@ class SSHConnection():
 		if rrcConnectionRecfgComplete > 0:
 			statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)'
 			logging.debug('\033[94m' + statMsg + '\033[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if nrUEFlag:
 			if nrDecodeMib > 0:
 				statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				self.htmlUEFailureMsg += statMsg + '\n'
+				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 			if nrFoundDCI > 0:
 				statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				self.htmlUEFailureMsg += statMsg + '\n'
+				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 			if nrCRCOK > 0:
 				statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				self.htmlUEFailureMsg += statMsg + '\n'
+				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 			if not frequency_found:
 				statMsg = 'NR-UE could NOT synch!'
 				logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-				self.htmlUEFailureMsg += statMsg + '\n'
+				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if uciStatMsgCount > 0:
 			statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if pdcpDataReqFailedCount > 0:
 			statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if badDciCount > 0:
 			statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if f1aRetransmissionCount > 0:
 			statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if fatalErrorCount > 0:
 			statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if macBsrTimerExpiredCount > 0:
 			statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)'
 			logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
-		if self.eNBmbmsEnables[0]:
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
+		if RAN.GeteNBmbmsEnable(0):
 			if mbms_messages > 0:
 				statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)'
 				logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
 			else:
 				statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)'
 				logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m')
-			self.htmlUEFailureMsg += statMsg + '\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n')
 		if foundSegFault:
 			logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
 			if not nrUEFlag:
-				return OAI_UE_PROCESS_SEG_FAULT
+				return CONST.OAI_UE_PROCESS_SEG_FAULT
 			else:
 				if not frequency_found:
-					return OAI_UE_PROCESS_SEG_FAULT
+					return CONST.OAI_UE_PROCESS_SEG_FAULT
 		if foundAssertion:
 			logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m')
-			self.htmlUEFailureMsg += 'UE showed an assertion!\n'
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE showed an assertion!\n')
 			if not nrUEFlag:
 				if not mib_found or not frequency_found:
-					return OAI_UE_PROCESS_ASSERTION
+					return CONST.OAI_UE_PROCESS_ASSERTION
 			else:
 				if not frequency_found:
-					return OAI_UE_PROCESS_ASSERTION
+					return CONST.OAI_UE_PROCESS_ASSERTION
 		if foundRealTimeIssue:
 			logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m')
-			self.htmlUEFailureMsg += 'UE faced real time issues!\n'
-			#return ENB_PROCESS_REALTIME_ISSUE
+			HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE faced real time issues!\n')
+			#return CONST.ENB_PROCESS_REALTIME_ISSUE
 		if nrUEFlag:
 			if not frequency_found:
-				return OAI_UE_PROCESS_COULD_NOT_SYNC
+				return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
 		else:
 			if no_cell_sync_found and not mib_found:
 				logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m')
-				self.htmlUEFailureMsg += 'UE could not synchronize!\n'
-				return OAI_UE_PROCESS_COULD_NOT_SYNC
+				HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE could not synchronize!\n')
+				return CONST.OAI_UE_PROCESS_COULD_NOT_SYNC
 		return 0
 
-	def TerminateeNB(self):
-		if self.eNB_serverId == '0':
-			lIpAddr = self.eNBIPAddress
-			lUserName = self.eNBUserName
-			lPassWord = self.eNBPassword
-			lSourcePath = self.eNBSourceCodePath
-		elif self.eNB_serverId == '1':
-			lIpAddr = self.eNB1IPAddress
-			lUserName = self.eNB1UserName
-			lPassWord = self.eNB1Password
-			lSourcePath = self.eNB1SourceCodePath
-		elif self.eNB_serverId == '2':
-			lIpAddr = self.eNB2IPAddress
-			lUserName = self.eNB2UserName
-			lPassWord = self.eNB2Password
-			lSourcePath = self.eNB2SourceCodePath
-		if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
-			Usage()
-			sys.exit('Insufficient Parameter')
-		self.open(lIpAddr, lUserName, lPassWord)
-		self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
-		if self.air_interface == 'lte':
-			nodeB_prefix = 'e'
-		else:
-			nodeB_prefix = 'g'
-		self.command('stdbuf -o0  ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-		result = re.search('-softmodem', str(self.ssh.before))
-		if result is not None:
-			self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
-			self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
-			time.sleep(10)
-			self.command('stdbuf -o0  ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-			result = re.search('-softmodem', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
-				time.sleep(5)
-		self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
-		self.close()
-		# If tracer options is on, stopping tshark on EPC side
-		result = re.search('T_stdout', str(self.Initialize_eNB_args))
-		if result is not None:
-			self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-			logging.debug('\u001B[1m Stopping tshark \u001B[0m')
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
-			time.sleep(1)
-			if self.EPC_PcapFileName != '':
-				self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5)
-				self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.')
-				self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.')
-			self.close()
-			logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
-			self.open(lIpAddr, lUserName, lPassWord)
-			self.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
-			enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
-			raw_record_file = enbLogFile.replace('.log', '_record.raw')
-			replay_log_file = enbLogFile.replace('.log', '_replay.log')
-			extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt')
-			extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log')
-			self.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
-			self.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5)
-			self.command('./textlog -d ' +  lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
-			self.close()
-			self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.')
-			logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
-			logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
-			self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-			self.eNBLogFiles[int(self.eNB_instance)] = ''
-		else:
-			analyzeFile = False
-			if self.eNBLogFiles[int(self.eNB_instance)] != '':
-				analyzeFile = True
-				fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
-				self.eNBLogFiles[int(self.eNB_instance)] = ''
-			if analyzeFile:
-				copyin_res = self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.')
-				if (copyin_res == -1):
-					logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
-					self.htmleNBFailureMsg = 'Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
-					self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
-					self.eNBmbmsEnables[int(self.eNB_instance)] = False
-					return
-				if self.eNB_serverId != '0':
-					self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
-				logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze)
-				logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze)
-				if (logStatus < 0):
-					self.CreateHtmlTestRow('N/A', 'KO', logStatus)
-					self.preamtureExit = True
-					self.eNBmbmsEnables[int(self.eNB_instance)] = False
-					return
-				else:
-					self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-			else:
-				self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-		self.eNBmbmsEnables[int(self.eNB_instance)] = False
-		self.eNBstatuses[int(self.eNB_instance)] = -1
-
-	def TerminateHSS(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT oai_hss || true', '\$', 5)
-			time.sleep(2)
-			self.command('stdbuf -o0  ps -aux | grep hss | grep -v grep', '\$', 5)
-			result = re.search('oai_hss -j', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL oai_hss || true', '\$', 5)
-			self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-hss.sh', '\$', 5)
-		elif re.match('OAI', self.EPCType, re.IGNORECASE):
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5)
-			time.sleep(2)
-			self.command('stdbuf -o0  ps -aux | grep hss | grep -v grep', '\$', 5)
-			result = re.search('\/bin\/bash .\/run_', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-			self.command('cd scripts', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5)
-			time.sleep(1)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5)
-		else:
-			logging.error('This should not happen!')
-		self.close()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-
-	def TerminateMME(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5)
-			time.sleep(2)
-			self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5)
-			result = re.search('mme -c', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5)
-			self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-mme.sh', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cd /opt/ltebox/tools', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_mme', '\$', 5)
-		else:
-			logging.error('This should not happen!')
-		self.close()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
-
-	def TerminateSPGW(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT spgwc spgwu || true', '\$', 5)
-			time.sleep(2)
-			self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5)
-			result = re.search('spgwc -c |spgwu -c ', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL spgwc spgwu || true', '\$', 5)
-			self.command('rm -f ' + self.EPCSourceCodePath + '/scripts/my-spgw*.sh', '\$', 5)
-			self.command('stdbuf -o0 ps -aux | grep tshark | grep -v grep', '\$', 5)
-			result = re.search('-w ', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT tshark || true', '\$', 5)
-				self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 ' + self.EPCSourceCodePath + '/scripts/*.pcap', '\$', 5)
-		elif re.match('OAI', self.EPCType, re.IGNORECASE):
-			self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5)
-			time.sleep(2)
-			self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5)
-			result = re.search('\/bin\/bash .\/run_', str(self.ssh.before))
-			if result is not None:
-				self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cd /opt/ltebox/tools', '\$', 5)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S ./stop_xGw', '\$', 5)
-		else:
-			logging.error('This should not happen!')
-		self.close()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
 
 	def TerminateFlexranCtrl(self):
-		if self.flexranCtrlInstalled == False or self.flexranCtrlStarted == False:
+		if RAN.GetflexranCtrlInstalled() == False or RAN.GetflexranCtrlStarted() == False:
 			return
-		if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '':
-			Usage()
+		if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('Insufficient Parameter')
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5)
+		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5)
 		time.sleep(1)
-		self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5)
+		SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5)
 		time.sleep(1)
-		self.close()
-		self.flexranCtrlStarted = False
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		SSH.close()
+		RAN.SetflexranCtrlStarted(False)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def TerminateUE_common(self, device_id, idx):
 		try:
-			self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+			SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
 			# back in airplane mode on (ie radio off)
 			if self.ADBCentralized:
 				if device_id == '84B7N16418004022':
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
 				else:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
 			logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m')
 
 			if self.ADBCentralized:
-				self.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5)
+				SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5)
 			else:
-				self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60)
-			result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before))
+				SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60)
+			result = re.search('shell +(?P<pid>\d+)', SSH.getBefore())
 			if result is not None:
 				pid_iperf = result.group('pid')
 				if self.ADBCentralized:
-					self.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5)
+					SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5)
 				else:
-					self.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60)
-			self.close()
+					SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60)
+			SSH.close()
 		except:
 			os.kill(os.getppid(),signal.SIGUSR1)
 
 	def TerminateUE(self):
-		terminate_ue_flag = True
+		terminate_ue_flag = False
 		self.GetAllUEDevices(terminate_ue_flag)
 		multi_jobs = []
 		i = 0
 		for device_id in self.UEDevices:
-			p = Process(target= SSH.TerminateUE_common, args = (device_id,i,))
+			p = Process(target= self.TerminateUE_common, args = (device_id,i,))
 			p.daemon = True
 			p.start()
 			multi_jobs.append(p)
 			i += 1
 		for job in multi_jobs:
 			job.join()
-		self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def TerminateOAIUE(self):
-		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-		self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
-		self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-		result = re.search('-uesoftmodem', str(self.ssh.before))
+		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
+		SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
+		result = re.search('-uesoftmodem', SSH.getBefore())
 		if result is not None:
-			self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5)
+			SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5)
 			time.sleep(10)
-			self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
-			result = re.search('-uesoftmodem', str(self.ssh.before))
+			SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5)
+			result = re.search('-uesoftmodem', SSH.getBefore())
 			if result is not None:
-				self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5)
+				SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5)
 				time.sleep(5)
-		self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
-		self.close()
+		SSH.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+		SSH.close()
 		result = re.search('ue_', str(self.UELogFile))
 		if result is not None:
-			copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
+			copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
 			if (copyin_res == -1):
 				logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m')
-				self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!'
-				self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE')
+				HTML.SethtmlUEFailureMsg('Could not copy UE logfile to analyze it!')
+				HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE')
 				self.UELogFile = ''
 				return
 			logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m')
@@ -3953,56 +2748,64 @@ class SSHConnection():
 				ueAction = 'Connection'
 			if (logStatus < 0):
 				logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m')
-				self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg
-				self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE')
-				if self.air_interface == 'lte':
+				HTML.SethtmlUEFailureMsg('<b>' + ueAction + ' Failed</b>\n' + HTML.GethtmlUEFailureMsg())
+				HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE')
+				if RAN.Getair_interface() == 'lte':
 					# In case of sniffing on commercial eNBs we have random results
 					# Not an error then
-					if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
+					if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'):
 						self.Initialize_OAI_UE_args = ''
 						self.AutoTerminateUEandeNB()
 				else:
-					if (logStatus == OAI_UE_PROCESS_COULD_NOT_SYNC):
+					if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC):
 						self.Initialize_OAI_UE_args = ''
 						self.AutoTerminateUEandeNB()
 			else:
 				logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m')
-				self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg
-				self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+				HTML.SethtmlUEFailureMsg('<b>' + ueAction + ' Completed</b>\n' + HTML.GethtmlUEFailureMsg())
+				HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 			self.UELogFile = ''
 		else:
-			self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
+			HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def AutoTerminateUEandeNB(self):
 		if (self.ADBIPAddress != 'none'):
 			self.testCase_id = 'AUTO-KILL-UE'
+			HTML.SettestCase_id(self.testCase_id)
 			self.desc = 'Automatic Termination of UE'
+			HTML.Setdesc('Automatic Termination of UE')
 			self.ShowTestID()
 			self.TerminateUE()
 		if (self.Initialize_OAI_UE_args != ''):
-			self.testCase_id = 'AUTO-KILL-UE'
-			self.desc = 'Automatic Termination of UE'
+			self.testCase_id = 'AUTO-KILL-OAI-UE'
+			HTML.SettestCase_id(self.testCase_id)
+			self.desc = 'Automatic Termination of OAI-UE'
+			HTML.Setdesc('Automatic Termination of OAI-UE')
 			self.ShowTestID()
 			self.TerminateOAIUE()
-		if (self.Initialize_eNB_args != ''):
+		if (RAN.GetInitialize_eNB_args() != ''):
 			self.testCase_id = 'AUTO-KILL-eNB'
+			HTML.SettestCase_id(self.testCase_id)
 			self.desc = 'Automatic Termination of eNB'
+			HTML.Setdesc('Automatic Termination of eNB')
 			self.ShowTestID()
-			self.eNB_instance = '0'
-			self.TerminateeNB()
-		if self.flexranCtrlInstalled and self.flexranCtrlStarted:
+			RAN.SeteNB_instance('0')
+			RAN.TerminateeNB()
+		if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
 			self.testCase_id = 'AUTO-KILL-flexran-ctl'
+			HTML.SettestCase_id(self.testCase_id)
 			self.desc = 'Automatic Termination of FlexRan CTL'
+			HTML.Setdesc('Automatic Termination of FlexRan CTL')
 			self.ShowTestID()
 			self.TerminateFlexranCtrl()
-		self.prematureExit = True
+		RAN.SetprematureExit(True)
 
 	def IdleSleep(self):
 		time.sleep(self.idle_sleep_time)
-		self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK)
+		HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK)
 
 	def X2_Status(self, idx, fileName):
-		cmd = "curl --silent http://" + self.EPCIPAddress + ":9999/stats | jq '.' > " + fileName
+		cmd = "curl --silent http://" + EPC.GetIPAddress() + ":9999/stats | jq '.' > " + fileName
 		message = cmd + '\n'
 		logging.debug(cmd)
 		subprocess.run(cmd, shell=True)
@@ -4051,7 +2854,7 @@ class SSHConnection():
 		logging.debug(msg)
 		fullMessage += msg + '\n'
 		if self.x2_ho_options == 'network':
-			if self.flexranCtrlInstalled and self.flexranCtrlStarted:
+			if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted():
 				self.x2ENBBsIds = []
 				self.x2ENBConnectedUEs = []
 				self.x2ENBBsIds.append([])
@@ -4066,7 +2869,7 @@ class SSHConnection():
 				eNB_cnt = self.x2NbENBs
 				cnt = 0
 				while cnt < eNB_cnt:
-					cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
+					cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
 					logging.debug(cmd)
 					fullMessage += cmd + '\n'
 					subprocess.run(cmd, shell=True)
@@ -4080,7 +2883,7 @@ class SSHConnection():
 				while cnt < eNB_cnt:
 					ueIdx = 0
 					while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]):
-						cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
+						cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
 						logging.debug(cmd)
 						fullMessage += cmd + '\n'
 						subprocess.run(cmd, shell=True)
@@ -4101,22 +2904,22 @@ class SSHConnection():
 					logging.debug(msg)
 					fullMessage += msg + '</pre>'
 					html_queue.put(fullMessage)
-					self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+					HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
 				else:
 					msg = "X2 Handover FAILED"
 					logging.error(msg)
 					fullMessage += msg + '</pre>'
 					html_queue.put(fullMessage)
-					self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+					HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
 			else:
-				self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK)
+				HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK)
 
 	def LogCollectBuild(self):
-		if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''):
-			IPAddress = self.eNBIPAddress
-			UserName = self.eNBUserName
-			Password = self.eNBPassword
-			SourceCodePath = self.eNBSourceCodePath
+		if (RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != ''):
+			IPAddress = RAN.GeteNBIPAddress()
+			UserName = RAN.GeteNBUserName()
+			Password = RAN.GeteNBPassword()
+			SourceCodePath = RAN.GeteNBSourceCodePath()
 		elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''):
 			IPAddress = self.UEIPAddress
 			UserName = self.UEUserName
@@ -4124,109 +2927,55 @@ class SSHConnection():
 			SourceCodePath = self.UESourceCodePath
 		else:
 			sys.exit('Insufficient Parameter')
-		self.open(IPAddress, UserName, Password)
-		self.command('cd ' + SourceCodePath, '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('rm -f build.log.zip', '\$', 5)
-		self.command('zip build.log.zip build_log_*/*', '\$', 60)
-		self.close()
-
-	def LogCollecteNB(self):
-		self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
-		self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
-		self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60)
-		self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5)
-		self.close()
-
+		SSH.open(IPAddress, UserName, Password)
+		SSH.command('cd ' + SourceCodePath, '\$', 5)
+		SSH.command('cd cmake_targets', '\$', 5)
+		SSH.command('rm -f build.log.zip', '\$', 5)
+		SSH.command('zip build.log.zip build_log_*/*', '\$', 60)
+		SSH.close()
 	def LogCollectPing(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-		self.command('cd scripts', '\$', 5)
-		self.command('rm -f ping.log.zip', '\$', 5)
-		self.command('zip ping.log.zip ping*.log', '\$', 60)
-		self.command('rm ping*.log', '\$', 5)
-		self.close()
+		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+		SSH.command('cd scripts', '\$', 5)
+		SSH.command('rm -f ping.log.zip', '\$', 5)
+		SSH.command('zip ping.log.zip ping*.log', '\$', 60)
+		SSH.command('rm ping*.log', '\$', 5)
+		SSH.close()
 
 	def LogCollectIperf(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
-		self.command('cd scripts', '\$', 5)
-		self.command('rm -f iperf.log.zip', '\$', 5)
-		self.command('zip iperf.log.zip iperf*.log', '\$', 60)
-		self.command('rm iperf*.log', '\$', 5)
-		self.close()
-
-	def LogCollectHSS(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-		self.command('rm -f hss.log.zip', '\$', 5)
-		if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('zip hss.log.zip hss*.log', '\$', 60)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm hss*.log', '\$', 5)
-			if re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-				self.command('zip hss.log.zip logs/hss*.* *.pcap', '\$', 60)
-				self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f logs/hss*.* *.pcap', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cp /opt/hss_sim0609/hss.log .', '\$', 60)
-			self.command('zip hss.log.zip hss.log', '\$', 60)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-
-	def LogCollectMME(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-		self.command('rm -f mme.log.zip', '\$', 5)
-		if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('zip mme.log.zip mme*.log', '\$', 60)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm mme*.log', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cp /opt/ltebox/var/log/*Log.0 .', '\$', 5)
-			self.command('zip mme.log.zip mmeLog.0 s1apcLog.0 s1apsLog.0 s11cLog.0 libLog.0 s1apCodecLog.0', '\$', 60)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-
-	def LogCollectSPGW(self):
-		self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
-		self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5)
-		self.command('rm -f spgw.log.zip', '\$', 5)
-		if re.match('OAI', self.EPCType, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.EPCType, re.IGNORECASE):
-			self.command('zip spgw.log.zip spgw*.log', '\$', 60)
-			self.command('echo ' + self.EPCPassword + ' | sudo -S rm spgw*.log', '\$', 5)
-		elif re.match('ltebox', self.EPCType, re.IGNORECASE):
-			self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5)
-			self.command('zip spgw.log.zip xGwLog.0', '\$', 60)
-		else:
-			logging.error('This option should not occur!')
-		self.close()
-
+		SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword())
+		SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5)
+		SSH.command('cd scripts', '\$', 5)
+		SSH.command('rm -f iperf.log.zip', '\$', 5)
+		SSH.command('zip iperf.log.zip iperf*.log', '\$', 60)
+		SSH.command('rm iperf*.log', '\$', 5)
+		SSH.close()
+	
 	def LogCollectOAIUE(self):
-		self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
-		self.command('cd ' + self.UESourceCodePath, '\$', 5)
-		self.command('cd cmake_targets', '\$', 5)
-		self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5)
-		self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60)
-		self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5)
-		self.close()
+		SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
+		SSH.command('cd ' + self.UESourceCodePath, '\$', 5)
+		SSH.command('cd cmake_targets', '\$', 5)
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5)
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60)
+		SSH.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5)
+		SSH.close()
 
 	def RetrieveSystemVersion(self, machine):
-		if self.eNBIPAddress == 'none' or self.UEIPAddress == 'none':
-			self.OsVersion = 'Ubuntu 16.04.5 LTS'
-			self.KernelVersion = '4.15.0-45-generic'
-			self.UhdVersion = '3.13.0.1-0'
-			self.UsrpBoard = 'B210'
-			self.CpuNb = '4'
-			self.CpuModel = 'Intel(R) Core(TM) i5-6200U'
-			self.CpuMHz = '2399.996 MHz'
+		if RAN.GeteNBIPAddress() == 'none' or self.UEIPAddress == 'none':
+			HTML.SetOsVersion('Ubuntu 16.04.5 LTS', 0)
+			HTML.SetKernelVersion('4.15.0-45-generic', 0)
+			HTML.SetUhdVersion('3.13.0.1-0', 0)
+			HTML.SetUsrpBoard('B210', 0)
+			HTML.SetCpuNb('4', 0)
+			HTML.SetCpuModel('Intel(R) Core(TM) i5-6200U', 0)
+			HTML.SetCpuMHz('2399.996 MHz', 0)
 			return 0
 		if machine == 'eNB':
-			if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '':
-				IPAddress = self.eNBIPAddress
-				UserName = self.eNBUserName
-				Password = self.eNBPassword
+			if RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != '':
+				IPAddress = RAN.GeteNBIPAddress()
+				UserName = RAN.GeteNBUserName()
+				Password = RAN.GeteNBPassword()
+				idx = 0
 			else:
 				return -1
 		if machine == 'UE':
@@ -4234,386 +2983,73 @@ class SSHConnection():
 				IPAddress = self.UEIPAddress
 				UserName = self.UEUserName
 				Password = self.UEPassword
+				idx = 1
 			else:
 				return -1
 
-		self.open(IPAddress, UserName, Password)
-		self.command('lsb_release -a', '\$', 5)
-		result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before))
+		SSH.open(IPAddress, UserName, Password)
+		SSH.command('lsb_release -a', '\$', 5)
+		result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore())
 		if result is not None:
-			self.OsVersion = result.group('os_type')
-			logging.debug('OS is: ' + self.OsVersion)
+			OsVersion = result.group('os_type')
+			logging.debug('OS is: ' + OsVersion)
+			HTML.SetOsVersion(OsVersion, idx)
 		else:
-			self.command('hostnamectl', '\$', 5)
-			result = re.search('Operating System: (?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before))
+			SSH.command('hostnamectl', '\$', 5)
+			result = re.search('Operating System: (?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore())
 			if result is not None:
-				self.OsVersion = result.group('os_type')
-				if self.OsVersion == 'CentOS Linux 7 ':
-					self.command('cat /etc/redhat-release', '\$', 5)
-					result = re.search('CentOS Linux release (?P<os_version>[0-9\.]+)', str(self.ssh.before))
+				OsVersion = result.group('os_type')
+				if OsVersion == 'CentOS Linux 7 ':
+					SSH.command('cat /etc/redhat-release', '\$', 5)
+					result = re.search('CentOS Linux release (?P<os_version>[0-9\.]+)', SSH.getBefore())
 					if result is not None:
-						self.OsVersion = self.OsVersion.replace('7 ', result.group('os_version'))
-				logging.debug('OS is: ' + self.OsVersion)
-		self.command('uname -r', '\$', 5)
-		result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before))
+						OsVersion = OsVersion.replace('7 ', result.group('os_version'))
+				logging.debug('OS is: ' + OsVersion)
+				HTML.SetOsVersion(OsVersion, idx)
+		SSH.command('uname -r', '\$', 5)
+		result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore())
 		if result is not None:
-			self.KernelVersion = result.group('kernel_version')
-			logging.debug('Kernel Version is: ' + self.KernelVersion)
-		self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
-		result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before))
+			KernelVersion = result.group('kernel_version')
+			logging.debug('Kernel Version is: ' + KernelVersion)
+			HTML.SetKernelVersion(KernelVersion, idx)
+		SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
+		result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore())
 		if result is not None:
-			self.UhdVersion = result.group('uhd_version')
-			logging.debug('UHD Version is: ' + self.UhdVersion)
+			UhdVersion = result.group('uhd_version')
+			logging.debug('UHD Version is: ' + UhdVersion)
+			HTML.SetUhdVersion(UhdVersion, idx)
 		else:
-			self.command('uhd_config_info --version', '\$', 5)
-			result = re.search('UHD (?P<uhd_version>[a-zA-Z0-9\.\-]+)', str(self.ssh.before))
+			SSH.command('uhd_config_info --version', '\$', 5)
+			result = re.search('UHD (?P<uhd_version>[a-zA-Z0-9\.\-]+)', SSH.getBefore())
 			if result is not None:
-				self.UhdVersion = result.group('uhd_version')
-				logging.debug('UHD Version is: ' + self.UhdVersion)
-		self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60)
-		usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before))
+				UhdVersion = result.group('uhd_version')
+				logging.debug('UHD Version is: ' + UhdVersion)
+				HTML.SetUhdVersion(UhdVersion, idx)
+		SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60)
+		usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore())
 		count = 0
 		for board in usrp_boards:
 			if count == 0:
-				self.UsrpBoard = board
+				UsrpBoard = board
 			else:
-				self.UsrpBoard += ',' + board
+				UsrpBoard += ',' + board
 			count += 1
 		if count > 0:
-			logging.debug('USRP Board(s) : ' + self.UsrpBoard)
-		self.command('lscpu', '\$', 5)
-		result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before))
+			logging.debug('USRP Board(s) : ' + UsrpBoard)
+			HTML.SetUsrpBoard(UsrpBoard, idx)
+		SSH.command('lscpu', '\$', 5)
+		result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore())
 		if result is not None:
-			self.CpuNb = result.group('nb_cpus')
-			logging.debug('nb_cpus: ' + self.CpuNb)
-			self.CpuModel = result.group('model')
-			logging.debug('model: ' + self.CpuModel)
-			self.CpuMHz = result.group('cpu_mhz') + ' MHz'
-			logging.debug('cpu_mhz: ' + self.CpuMHz)
-		self.close()
-
-#-----------------------------------------------------------
-# HTML Reporting....
-#-----------------------------------------------------------
-	def CreateHtmlHeader(self):
-		if (not self.htmlHeaderCreated):
-			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
-			logging.debug('\u001B[1m  Creating HTML header \u001B[0m')
-			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
-			self.htmlFile = open('test_results.html', 'w')
-			self.htmlFile.write('<!DOCTYPE html>\n')
-			self.htmlFile.write('<html class="no-js" lang="en-US">\n')
-			self.htmlFile.write('<head>\n')
-			self.htmlFile.write('  <meta name="viewport" content="width=device-width, initial-scale=1">\n')
-			self.htmlFile.write('  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n')
-			self.htmlFile.write('  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n')
-			self.htmlFile.write('  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n')
-			self.htmlFile.write('  <title>Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID</title>\n')
-			self.htmlFile.write('</head>\n')
-			self.htmlFile.write('<body><div class="container">\n')
-			self.htmlFile.write('  <br>\n')
-			self.htmlFile.write('  <table style="border-collapse: collapse; border: none;">\n')
-			self.htmlFile.write('    <tr style="border-collapse: collapse; border: none;">\n')
-			self.htmlFile.write('      <td style="border-collapse: collapse; border: none;">\n')
-			self.htmlFile.write('        <a href="http://www.openairinterface.org/">\n')
-			self.htmlFile.write('           <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n')
-			self.htmlFile.write('           </img>\n')
-			self.htmlFile.write('        </a>\n')
-			self.htmlFile.write('      </td>\n')
-			self.htmlFile.write('      <td style="border-collapse: collapse; border: none; vertical-align: center;">\n')
-			self.htmlFile.write('        <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n')
-			self.htmlFile.write('      </td>\n')
-			self.htmlFile.write('    </tr>\n')
-			self.htmlFile.write('  </table>\n')
-			self.htmlFile.write('  <br>\n')
-			self.htmlFile.write('  <div class="alert alert-info"><strong> <span class="glyphicon glyphicon-dashboard"></span> TEMPLATE_STAGE_NAME</strong></div>\n')
-			self.htmlFile.write('  <table border = "1">\n')
-			self.htmlFile.write('     <tr>\n')
-			self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-time"></span> Build Start Time (UTC) </td>\n')
-			self.htmlFile.write('       <td>TEMPLATE_BUILD_TIME</td>\n')
-			self.htmlFile.write('     </tr>\n')
-			self.htmlFile.write('     <tr>\n')
-			self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-cloud-upload"></span> GIT Repository </td>\n')
-			self.htmlFile.write('       <td><a href="' + self.ranRepository + '">' + self.ranRepository + '</a></td>\n')
-			self.htmlFile.write('     </tr>\n')
-			self.htmlFile.write('     <tr>\n')
-			self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-wrench"></span> Job Trigger </td>\n')
-			if (self.ranAllowMerge):
-				self.htmlFile.write('       <td>Merge-Request</td>\n')
-			else:
-				self.htmlFile.write('       <td>Push to Branch</td>\n')
-			self.htmlFile.write('     </tr>\n')
-			self.htmlFile.write('     <tr>\n')
-			if (self.ranAllowMerge):
-				self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-out"></span> Source Branch </td>\n')
-			else:
-				self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tree-deciduous"></span> Branch</td>\n')
-			self.htmlFile.write('       <td>' + self.ranBranch + '</td>\n')
-			self.htmlFile.write('     </tr>\n')
-			self.htmlFile.write('     <tr>\n')
-			if (self.ranAllowMerge):
-				self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Source Commit ID </td>\n')
-			else:
-				self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n')
-			self.htmlFile.write('       <td>' + self.ranCommitID + '</td>\n')
-			self.htmlFile.write('     </tr>\n')
-			if self.ranAllowMerge != '':
-				commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True)
-				commit_message = commit_message.strip()
-				self.htmlFile.write('     <tr>\n')
-				if (self.ranAllowMerge):
-					self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n')
-				else:
-					self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n')
-				self.htmlFile.write('       <td>' + commit_message + '</td>\n')
-				self.htmlFile.write('     </tr>\n')
-			if (self.ranAllowMerge):
-				self.htmlFile.write('     <tr>\n')
-				self.htmlFile.write('       <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n')
-				if (self.ranTargetBranch == ''):
-					self.htmlFile.write('       <td>develop</td>\n')
-				else:
-					self.htmlFile.write('       <td>' + self.ranTargetBranch + '</td>\n')
-				self.htmlFile.write('     </tr>\n')
-			self.htmlFile.write('  </table>\n')
-
-			if (self.ADBIPAddress != 'none'):
-				terminate_ue_flag = True
-				self.GetAllUEDevices(terminate_ue_flag)
-				self.GetAllCatMDevices(terminate_ue_flag)
-				self.htmlUEConnected = len(self.UEDevices)
-				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
-				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
-			else:
-				self.UEDevices.append('OAI-UE')
-				self.htmlUEConnected = len(self.UEDevices)
-				self.htmlFile.write('  <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' OAI UE(s) is(are) connected to CI bench</h2>\n')
-			self.htmlFile.write('  <br>\n')
-			self.htmlFile.write('  <ul class="nav nav-pills">\n')
-			count = 0
-			while (count < self.nbTestXMLfiles):
-				pillMsg = '    <li><a data-toggle="pill" href="#'
-				pillMsg += self.htmlTabRefs[count]
-				pillMsg += '">'
-				pillMsg += '__STATE_' + self.htmlTabNames[count] + '__'
-				pillMsg += self.htmlTabNames[count]
-				pillMsg += ' <span class="glyphicon glyphicon-'
-				pillMsg += self.htmlTabIcons[count]
-				pillMsg += '"></span></a></li>\n'
-				self.htmlFile.write(pillMsg)
-				count += 1
-			self.htmlFile.write('  </ul>\n')
-			self.htmlFile.write('  <div class="tab-content">\n')
-			self.htmlFile.close()
-
-	def CreateHtmlTabHeader(self):
-		if (not self.htmlHeaderCreated):
-			if (not os.path.isfile('test_results.html')):
-				self.CreateHtmlHeader()
-			self.htmlFile = open('test_results.html', 'a')
-			if (self.nbTestXMLfiles == 1):
-				self.htmlFile.write('  <div id="' + self.htmlTabRefs[0] + '" class="tab-pane fade">\n')
-				self.htmlFile.write('  <h3>Test Summary for <span class="glyphicon glyphicon-file"></span> ' + self.testXMLfiles[0] + '</h3>\n')
-			else:
-				self.htmlFile.write('  <div id="build-tab" class="tab-pane fade">\n')
-			self.htmlFile.write('  <table class="table" border = "1">\n')
-			self.htmlFile.write('      <tr bgcolor = "#33CCFF" >\n')
-			self.htmlFile.write('        <th>Relative Time (ms)</th>\n')
-			self.htmlFile.write('        <th>Test Id</th>\n')
-			self.htmlFile.write('        <th>Test Desc</th>\n')
-			self.htmlFile.write('        <th>Test Options</th>\n')
-			self.htmlFile.write('        <th>Test Status</th>\n')
-			if (self.htmlUEConnected == -1):
-				terminate_ue_flag = True
-				if (self.ADBIPAddress != 'none'):
-					self.GetAllUEDevices(terminate_ue_flag)
-					self.GetAllCatMDevices(terminate_ue_flag)
-				else:
-					self.UEDevices.append('OAI-UE')
-				self.htmlUEConnected = len(self.UEDevices)
-
-			i = 0
-			while (i < self.htmlUEConnected):
-				self.htmlFile.write('        <th>UE' + str(i) + ' Status</th>\n')
-				i += 1
-			self.htmlFile.write('      </tr>\n')
-		self.htmlHeaderCreated = True
-
-	def CreateHtmlTabFooter(self, passStatus):
-		if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
-			self.htmlFile.write('      <tr>\n')
-			self.htmlFile.write('        <th bgcolor = "#33CCFF" colspan=3>Final Tab Status</th>\n')
-			if passStatus:
-				self.htmlFile.write('        <th bgcolor = "green" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">PASS <span class="glyphicon glyphicon-ok"></span> </font></th>\n')
-			else:
-				self.htmlFile.write('        <th bgcolor = "red" colspan=' + str(2 + self.htmlUEConnected) + '><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
-			self.htmlFile.write('      </tr>\n')
-			self.htmlFile.write('  </table>\n')
-			self.htmlFile.write('  </div>\n')
-			self.htmlFile.close()
-			time.sleep(1)
-			if passStatus:
-				cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html"
-				subprocess.run(cmd, shell=True)
-			else:
-				cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<span class=\"glyphicon glyphicon-remove\"><\/span>/' test_results.html"
-				subprocess.run(cmd, shell=True)
-		self.htmlFooterCreated = False
-
-	def CreateHtmlFooter(self, passStatus):
-		if (os.path.isfile('test_results.html')):
-			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
-			logging.debug('\u001B[1m  Creating HTML footer \u001B[0m')
-			logging.debug('\u001B[1m----------------------------------------\u001B[0m')
-
-			self.htmlFile = open('test_results.html', 'a')
-			self.htmlFile.write('</div>\n')
-			self.htmlFile.write('  <p></p>\n')
-			self.htmlFile.write('  <table class="table table-condensed">\n')
-
-			machines = [ 'eNB', 'UE' ]
-			for machine in machines:
-				res = self.RetrieveSystemVersion(machine)
-				if res == -1:
-					continue
-				self.htmlFile.write('      <tr>\n')
-				self.htmlFile.write('        <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n')
-				self.htmlFile.write('      </tr>\n')
-				self.htmlFile.write('      <tr>\n')
-				self.htmlFile.write('        <td>OS Version</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.OsVersion + '</span></td>\n')
-				self.htmlFile.write('        <td>Kernel Version</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n')
-				self.htmlFile.write('        <td>UHD Version</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n')
-				self.htmlFile.write('        <td>USRP Board</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n')
-				self.htmlFile.write('      </tr>\n')
-				self.htmlFile.write('      <tr>\n')
-				self.htmlFile.write('        <td>Nb CPUs</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.CpuNb + '</span></td>\n')
-				self.htmlFile.write('        <td>CPU Model Name</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.CpuModel + '</span></td>\n')
-				self.htmlFile.write('        <td>CPU Frequency</td>\n')
-				self.htmlFile.write('        <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n')
-				self.htmlFile.write('        <td></td>\n')
-				self.htmlFile.write('        <td></td>\n')
-				self.htmlFile.write('      </tr>\n')
-
-			self.htmlFile.write('      <tr>\n')
-			self.htmlFile.write('        <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n')
-			if passStatus:
-				self.htmlFile.write('        <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n')
-			else:
-				self.htmlFile.write('        <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
-			self.htmlFile.write('      </tr>\n')
-			self.htmlFile.write('  </table>\n')
-			self.htmlFile.write('  <p></p>\n')
-			self.htmlFile.write('  <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2018 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n')
-			self.htmlFile.write('</div></body>\n')
-			self.htmlFile.write('</html>\n')
-			self.htmlFile.close()
-
-	def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'):
-		if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
-			currentTime = int(round(time.time() * 1000)) - self.startTime
-			self.htmlFile.write('      <tr>\n')
-			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n')
-			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + self.testCase_id  + '</td>\n')
-			self.htmlFile.write('        <td>' + self.desc  + '</td>\n')
-			self.htmlFile.write('        <td>' + str(options)  + '</td>\n')
-			if (str(status) == 'OK'):
-				self.htmlFile.write('        <td bgcolor = "lightgreen" >' + str(status)  + '</td>\n')
-			elif (str(status) == 'KO'):
-				if (processesStatus == 0):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >' + str(status)  + '</td>\n')
-				elif (processesStatus == ENB_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n')
-				elif (processesStatus == OAI_UE_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n')
-				elif (processesStatus == ENB_PROCESS_SEG_FAULT) or (processesStatus == OAI_UE_PROCESS_SEG_FAULT):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n')
-				elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == OAI_UE_PROCESS_ASSERTION):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n')
-				elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n')
-				elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE):
-					self.htmlFile.write('        <td bgcolor = "orange" >OK?</td>\n')
-				elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - ' + machine + ' Slave RRU could not synch</td>\n')
-				elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n')
-				elif (processesStatus == HSS_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n')
-				elif (processesStatus == MME_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - MME process not found</td>\n')
-				elif (processesStatus == SPGW_PROCESS_FAILED):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - SPGW process not found</td>\n')
-				elif (processesStatus == UE_IP_ADDRESS_ISSUE):
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >KO - Could not retrieve UE IP address</td>\n')
-				else:
-					self.htmlFile.write('        <td bgcolor = "lightcoral" >' + str(status)  + '</td>\n')
-			else:
-				self.htmlFile.write('        <td bgcolor = "orange" >' + str(status)  + '</td>\n')
-			if (len(str(self.htmleNBFailureMsg)) > 2):
-				cellBgColor = 'white'
-				result = re.search('ended with|faced real time issues', self.htmleNBFailureMsg)
-				if result is not None:
-					cellBgColor = 'red'
-				else:
-					result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg)
-					if result is not None:
-						cellBgColor = 'orange'
-				self.htmlFile.write('        <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n')
-				self.htmleNBFailureMsg = ''
-			elif (len(str(self.htmlUEFailureMsg)) > 2):
-				cellBgColor = 'white'
-				result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg)
-				if result is not None:
-					cellBgColor = 'red'
-				else:
-					result = re.search('showed|Could not copy UE logfile|oaitun_ue1 interface is either NOT mounted or NOT configured', self.htmlUEFailureMsg)
-					if result is not None:
-						cellBgColor = 'orange'
-				self.htmlFile.write('        <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n')
-				self.htmlUEFailureMsg = ''
-			else:
-				i = 0
-				while (i < self.htmlUEConnected):
-					self.htmlFile.write('        <td>-</td>\n')
-					i += 1
-			self.htmlFile.write('      </tr>\n')
-
-	def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue):
-		if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
-			currentTime = int(round(time.time() * 1000)) - self.startTime
-			addOrangeBK = False
-			self.htmlFile.write('      <tr>\n')
-			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + format(currentTime / 1000, '.1f') + '</td>\n')
-			self.htmlFile.write('        <td bgcolor = "lightcyan" >' + self.testCase_id  + '</td>\n')
-			self.htmlFile.write('        <td>' + self.desc  + '</td>\n')
-			self.htmlFile.write('        <td>' + str(options)  + '</td>\n')
-			if (str(status) == 'OK'):
-				self.htmlFile.write('        <td bgcolor = "lightgreen" >' + str(status)  + '</td>\n')
-			elif (str(status) == 'KO'):
-				self.htmlFile.write('        <td bgcolor = "lightcoral" >' + str(status)  + '</td>\n')
-			else:
-				addOrangeBK = True
-				self.htmlFile.write('        <td bgcolor = "orange" >' + str(status)  + '</td>\n')
-			i = 0
-			while (i < self.htmlUEConnected):
-				if (i < ue_status):
-					if (not ue_queue.empty()):
-						if (addOrangeBK):
-							self.htmlFile.write('        <td bgcolor = "orange" >' + str(ue_queue.get()).replace('white', 'orange') + '</td>\n')
-						else:
-							self.htmlFile.write('        <td>' + str(ue_queue.get()) + '</td>\n')
-					else:
-						self.htmlFile.write('        <td>-</td>\n')
-				else:
-					self.htmlFile.write('        <td>-</td>\n')
-				i += 1
-			self.htmlFile.write('      </tr>\n')
+			CpuNb = result.group('nb_cpus')
+			logging.debug('nb_cpus: ' + CpuNb)
+			HTML.SetCpuNb(CpuNb, idx)
+			CpuModel = result.group('model')
+			logging.debug('model: ' + CpuModel)
+			HTML.SetCpuModel(CpuModel, idx)
+			CpuMHz = result.group('cpu_mhz') + ' MHz'
+			logging.debug('cpu_mhz: ' + CpuMHz)
+			HTML.SetCpuMHz(CpuMHz, idx)
+		SSH.close()
 
 #-----------------------------------------------------------
 # ShowTestID()
@@ -4624,50 +3060,6 @@ class SSHConnection():
 		logging.debug('\u001B[1m' + self.desc + '\u001B[0m')
 		logging.debug('\u001B[1m----------------------------------------\u001B[0m')
 
-#-----------------------------------------------------------
-# Usage()
-#-----------------------------------------------------------
-def Usage():
-	print('----------------------------------------------------------------------------------------------------------------------')
-	print('main.py Ver:' + Version)
-	print('----------------------------------------------------------------------------------------------------------------------')
-	print('Usage: python main.py [options]')
-	print('  --help  Show this help.')
-	print('  --mode=[Mode]')
-	print('      TesteNB')
-	print('      InitiateHtml, FinalizeHtml')
-	print('      TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW')
-	print('      LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
-	print('---------------------------------------------------------------------------------------------------- Git Options --')
-	print('  --ranRepository=[OAI RAN Repository URL]')
-	print('  --ranBranch=[OAI RAN Repository Branch]')
-	print('  --ranCommitID=[OAI RAN Repository Commit SHA-1]')
-	print('  --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)]')
-	print('  --ranTargetBranch=[Target Branch in case of a Merge Request]')
-	print('--------------------------------------------------------------------------------------------- eNB Server Options --')
-	print('  --eNBIPAddress=[eNB\'s IP Address]')
-	print('  --eNBUserName=[eNB\'s Login User Name]')
-	print('  --eNBPassword=[eNB\'s Login Password]')
-	print('  --eNBSourceCodePath=[eNB\'s Source Code Path]')
-	print('------------------------------------------------------------------------------------------ OAI UE Server Options --')
-	print('  --UEIPAddress=[UE\'s IP Address]')
-	print('  --UEUserName=[UE\'s Login User Name]')
-	print('  --UEPassword=[UE\'s Login Password]')
-	print('  --UESourceCodePath=[UE\'s Source Code Path]')
-	print('--------------------------------------------------------------------------------------------- EPC Server Options --')
-	print('  --EPCIPAddress=[EPC\'s IP Address]')
-	print('  --EPCUserName=[EPC\'s Login User Name]')
-	print('  --EPCPassword=[EPC\'s Login Password]')
-	print('  --EPCSourceCodePath=[EPC\'s Source Code Path]')
-	print('  --EPCType=[EPC\'s Type: OAI or ltebox or OAI-Rel14-CUPS]')
-	print('--------------------------------------------------------------------------------------------- ABD Server Options --')
-	print('  --ADBIPAddress=[ADB\'s IP Address]')
-	print('  --ADBUserName=[ADB\'s Login User Name]')
-	print('  --ADBPassword=[ADB\'s Login Password]')
-	print('----------------------------------------------------------------------------------------------------------------------')
-	print('  --XMLTestFile=[XML Test File to be run]')
-	print('----------------------------------------------------------------------------------------------------------------------')
-
 def CheckClassValidity(action,id):
 	if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover':
 		logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
@@ -4676,143 +3068,145 @@ def CheckClassValidity(action,id):
 
 def GetParametersFromXML(action):
 	if action == 'Build_eNB':
-		SSH.Build_eNB_args = test.findtext('Build_eNB_args')
+		RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args'))
 		forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
 		if (forced_workspace_cleanup is None):
-			SSH.Build_eNB_forced_workspace_cleanup = False
+			RAN.SetBuild_eNB_forced_workspace_cleanup(False)
 		else:
 			if re.match('true', forced_workspace_cleanup, re.IGNORECASE):
-				SSH.Build_eNB_forced_workspace_cleanup = True
-			else:
-				SSH.Build_eNB_forced_workspace_cleanup = False
-		SSH.eNB_instance = test.findtext('eNB_instance')
-		if (SSH.eNB_instance is None):
-			SSH.eNB_instance = '0'
-		SSH.eNB_serverId = test.findtext('eNB_serverId')
-		if (SSH.eNB_serverId is None):
-			SSH.eNB_serverId = '0'
+				RAN.SetBuild_eNB_forced_workspace_cleanup(True)
+			else:
+				RAN.SetBuild_eNB_forced_workspace_cleanup(False)
+		RAN.SeteNB_instance(test.findtext('eNB_instance'))
+		if (RAN.GeteNB_instance() is None):
+			RAN.SeteNB_instance('0')
+		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
+		if (RAN.GeteNB_serverId() is None):
+			RAN.SeteNB_serverId('0')
 		xmlBgBuildField = test.findtext('backgroundBuild')
 		if (xmlBgBuildField is None):
-			SSH.backgroundBuild = False
+			RAN.SetbackgroundBuild(False)
 		else:
 			if re.match('true', xmlBgBuildField, re.IGNORECASE):
-				SSH.backgroundBuild = True
+				RAN.SetbackgroundBuild(True)
 			else:
-				SSH.backgroundBuild = False
+				RAN.SetbackgroundBuild(False)
 
 	if action == 'WaitEndBuild_eNB':
-		SSH.Build_eNB_args = test.findtext('Build_eNB_args')
-		SSH.eNB_instance = test.findtext('eNB_instance')
-		if (SSH.eNB_instance is None):
-			SSH.eNB_instance = '0'
-		SSH.eNB_serverId = test.findtext('eNB_serverId')
-		if (SSH.eNB_serverId is None):
-			SSH.eNB_serverId = '0'
+		RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args'))
+		RAN.SeteNB_instance(test.findtext('eNB_instance'))
+		if (RAN.GeteNB_instance() is None):
+			RAN.SeteNB_instance('0')
+		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
+		if (RAN.GeteNB_serverId() is None):
+			RAN.SeteNB_serverId('0')
 
 	if action == 'Initialize_eNB':
-		SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args')
-		SSH.eNB_instance = test.findtext('eNB_instance')
-		if (SSH.eNB_instance is None):
-			SSH.eNB_instance = '0'
-		SSH.eNB_serverId = test.findtext('eNB_serverId')
-		if (SSH.eNB_serverId is None):
-			SSH.eNB_serverId = '0'
-		SSH.air_interface = test.findtext('air_interface')
-		if (SSH.air_interface is None):
-			SSH.air_interface = 'lte'
-		else:
-			SSH.air_interface = SSH.air_interface.lower()
+		RAN.SetInitialize_eNB_args(test.findtext('Initialize_eNB_args'))
+		RAN.SeteNB_instance(test.findtext('eNB_instance'))
+		if (RAN.GeteNB_instance() is None):
+			RAN.SeteNB_instance('0')
+		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
+		if (RAN.GeteNB_serverId() is None):
+			RAN.SeteNB_serverId('0')
+		CiTestObj.air_interface = test.findtext('air_interface')
+		if (CiTestObj.air_interface is None):
+			CiTestObj.air_interface = 'lte'
+		else:
+			CiTestObj.air_interface = CiTestObj.air_interface.lower()
+		RAN.Setair_interface(CiTestObj.air_interface)
 
 	if action == 'Terminate_eNB':
-		SSH.eNB_instance = test.findtext('eNB_instance')
-		if (SSH.eNB_instance is None):
-			SSH.eNB_instance = '0'
-		SSH.eNB_serverId = test.findtext('eNB_serverId')
-		if (SSH.eNB_serverId is None):
-			SSH.eNB_serverId = '0'
-		SSH.air_interface = test.findtext('air_interface')
-		if (SSH.air_interface is None):
-			SSH.air_interface = 'lte'
-		else:
-			SSH.air_interface = SSH.air_interface.lower()
+		RAN.SeteNB_instance(test.findtext('eNB_instance'))
+		if (RAN.GeteNB_instance() is None):
+			RAN.SeteNB_instance('0')
+		RAN.SeteNB_serverId(test.findtext('eNB_serverId'))
+		if (RAN.GeteNB_serverId() is None):
+			RAN.SeteNB_serverId('0')
+		CiTestObj.air_interface = test.findtext('air_interface')
+		if (CiTestObj.air_interface is None):
+			CiTestObj.air_interface = 'lte'
+		else:
+			CiTestObj.air_interface = CiTestObj.air_interface.lower()
+		RAN.Setair_interface(CiTestObj.air_interface)
 
 	if action == 'Attach_UE':
 		nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
 		if (nbMaxUEtoAttach is None):
-			SSH.nbMaxUEtoAttach = -1
+			CiTestObj.nbMaxUEtoAttach = -1
 		else:
-			SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
+			CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
 
 	if action == 'CheckStatusUE':
 		expectedNBUE = test.findtext('expectedNbOfConnectedUEs')
 		if (expectedNBUE is None):
-			SSH.expectedNbOfConnectedUEs = -1
+			CiTestObj.expectedNbOfConnectedUEs = -1
 		else:
-			SSH.expectedNbOfConnectedUEs = int(expectedNBUE)
+			CiTestObj.expectedNbOfConnectedUEs = int(expectedNBUE)
 
 	if action == 'Build_OAI_UE':
-		SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
-		SSH.clean_repository = test.findtext('clean_repository')
-		if (SSH.clean_repository == 'false'):
-			SSH.clean_repository = False
+		CiTestObj.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
+		CiTestObj.clean_repository = test.findtext('clean_repository')
+		if (CiTestObj.clean_repository == 'false'):
+			CiTestObj.clean_repository = False
 		else:
-			SSH.clean_repository = True
+			CiTestObj.clean_repository = True
 
 	if action == 'Initialize_OAI_UE':
-		SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
-		SSH.UE_instance = test.findtext('UE_instance')
-		if (SSH.UE_instance is None):
-			SSH.UE_instance = '0'
-		SSH.air_interface = test.findtext('air_interface')
-		if (SSH.air_interface is None):
-			SSH.air_interface = 'lte'
+		CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
+		CiTestObj.UE_instance = test.findtext('UE_instance')
+		if (CiTestObj.UE_instance is None):
+			CiTestObj.UE_instance = '0'
+		CiTestObj.air_interface = test.findtext('air_interface')
+		if (CiTestObj.air_interface is None):
+			CiTestObj.air_interface = 'lte'
 		else:
-			SSH.air_interface = SSH.air_interface.lower()
+			CiTestObj.air_interface = CiTestObj.air_interface.lower()
 
 	if action == 'Terminate_OAI_UE':
-		SSH.eNB_instance = test.findtext('UE_instance')
-		if (SSH.UE_instance is None):
-			SSH.UE_instance = '0'
+		RAN.SeteNB_instance(test.findtext('UE_instance'))
+		if (CiTestObj.UE_instance is None):
+			CiTestObj.UE_instance = '0'
 
 	if action == 'Ping' or action == 'Ping_CatM_module':
-		SSH.ping_args = test.findtext('ping_args')
-		SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
+		CiTestObj.ping_args = test.findtext('ping_args')
+		CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
 
 	if action == 'Iperf':
-		SSH.iperf_args = test.findtext('iperf_args')
-		SSH.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
-		SSH.iperf_profile = test.findtext('iperf_profile')
-		if (SSH.iperf_profile is None):
-			SSH.iperf_profile = 'balanced'
-		else:
-			if SSH.iperf_profile != 'balanced' and SSH.iperf_profile != 'unbalanced' and SSH.iperf_profile != 'single-ue':
-				logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile)
-				SSH.iperf_profile = 'balanced'
-		SSH.iperf_options = test.findtext('iperf_options')
-		if (SSH.iperf_options is None):
-			SSH.iperf_options = 'check'
-		else:
-			if SSH.iperf_options != 'check' and SSH.iperf_options != 'sink':
-				logging.debug('ERROR: test-case has wrong option ' + SSH.iperf_options)
-				SSH.iperf_options = 'check'
+		CiTestObj.iperf_args = test.findtext('iperf_args')
+		CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
+		CiTestObj.iperf_profile = test.findtext('iperf_profile')
+		if (CiTestObj.iperf_profile is None):
+			CiTestObj.iperf_profile = 'balanced'
+		else:
+			if CiTestObj.iperf_profile != 'balanced' and CiTestObj.iperf_profile != 'unbalanced' and CiTestObj.iperf_profile != 'single-ue':
+				logging.debug('ERROR: test-case has wrong profile ' + CiTestObj.iperf_profile)
+				CiTestObj.iperf_profile = 'balanced'
+		CiTestObj.iperf_options = test.findtext('iperf_options')
+		if (CiTestObj.iperf_options is None):
+			CiTestObj.iperf_options = 'check'
+		else:
+			if CiTestObj.iperf_options != 'check' and CiTestObj.iperf_options != 'sink':
+				logging.debug('ERROR: test-case has wrong option ' + CiTestObj.iperf_options)
+				CiTestObj.iperf_options = 'check'
 
 	if action == 'IdleSleep':
 		string_field = test.findtext('idle_sleep_time_in_sec')
 		if (string_field is None):
-			SSH.idle_sleep_time = 5
+			CiTestObj.idle_sleep_time = 5
 		else:
-			SSH.idle_sleep_time = int(string_field)
+			CiTestObj.idle_sleep_time = int(string_field)
 
 	if action == 'Perform_X2_Handover':
 		string_field = test.findtext('x2_ho_options')
 		if (string_field is None):
-			SSH.x2_ho_options = 'network'
+			CiTestObj.x2_ho_options = 'network'
 		else:
 			if string_field != 'network':
 				logging.error('ERROR: test-case has wrong option ' + string_field)
-				SSH.x2_ho_options = 'network'
+				CiTestObj.x2_ho_options = 'network'
 			else:
-				SSH.x2_ho_options = string_field
+				CiTestObj.x2_ho_options = string_field
 
 
 #check if given test is in list
@@ -4831,7 +3225,23 @@ def receive_signal(signum, frame):
 # Parameter Check
 #-----------------------------------------------------------
 mode = ''
-SSH = SSHConnection()
+CiTestObj = OaiCiTest()
+
+import sshconnection 
+import epc
+import helpreadme as HELP
+import ran
+import html
+import constants
+ 
+SSH = sshconnection.SSHConnection()
+EPC = epc.EPCManagement()
+RAN = ran.RANManagement()
+HTML = html.HTMLManagement()
+
+EPC.SetHtmlObj(HTML)
+RAN.SetHtmlObj(HTML)
+RAN.SetEpcObj(EPC)
 
 argvs = sys.argv
 argc = len(argvs)
@@ -4839,8 +3249,9 @@ cwd = os.getcwd()
 
 while len(argvs) > 1:
 	myArgv = argvs.pop(1)	# 0th is this file's name
+
 	if re.match('^\-\-help$', myArgv, re.IGNORECASE):
-		Usage()
+		HELP.GenericHelp(CONST.Version)
 		sys.exit(0)
 	elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
@@ -4850,7 +3261,9 @@ while len(argvs) > 1:
 			matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
 		else:
 			matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
-		SSH.ranRepository = matchReg.group(1)
+		CiTestObj.ranRepository = matchReg.group(1)
+		RAN.SetranRepository(matchReg.group(1))
+		HTML.SetranRepository(matchReg.group(1))
 	elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
@@ -4858,259 +3271,289 @@ while len(argvs) > 1:
 			matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
 		doMerge = matchReg.group(1)
 		if ((doMerge == 'true') or (doMerge == 'True')):
-			SSH.ranAllowMerge = True
+			CiTestObj.ranAllowMerge = True
+			RAN.SetranAllowMerge(True)
+			HTML.SetranAllowMerge(True)
 	elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
 		else:
 			matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
-		SSH.ranBranch = matchReg.group(1)
+		CiTestObj.ranBranch = matchReg.group(1)
+		RAN.SetranBranch(matchReg.group(1))
+		HTML.SetranBranch(matchReg.group(1))
 	elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
 		else:
 			matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
-		SSH.ranCommitID = matchReg.group(1)
+		CiTestObj.ranCommitID = matchReg.group(1)
+		RAN.SetranCommitID(matchReg.group(1))
+		HTML.SetranCommitID(matchReg.group(1))
 	elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
 		else:
 			matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
-		SSH.ranTargetBranch = matchReg.group(1)
+		CiTestObj.ranTargetBranch = matchReg.group(1)
+		RAN.SetranTargetBranch(matchReg.group(1))
+		HTML.SetranTargetBranch(matchReg.group(1))
 	elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNBIPAddress = matchReg.group(1)
+			RAN.SeteNBIPAddress(matchReg.group(1))
 		elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB1IPAddress = matchReg.group(1)
+			RAN.SeteNB1IPAddress(matchReg.group(1))
 		elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB2IPAddress = matchReg.group(1)
+			RAN.SeteNB2IPAddress(matchReg.group(1))
 	elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNBUserName = matchReg.group(1)
+			RAN.SeteNBUserName(matchReg.group(1))
 		elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB1UserName = matchReg.group(1)
+			RAN.SeteNB1UserName(matchReg.group(1))
 		elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB2UserName = matchReg.group(1)
+			RAN.SeteNB2UserName(matchReg.group(1))
 	elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNBPassword = matchReg.group(1)
+			RAN.SeteNBPassword(matchReg.group(1))
 		elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB1Password = matchReg.group(1)
+			RAN.SeteNB1Password(matchReg.group(1))
 		elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB2Password = matchReg.group(1)
+			RAN.SeteNB2Password(matchReg.group(1))
 	elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 		if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNBSourceCodePath = matchReg.group(1)
+			RAN.SeteNBSourceCodePath(matchReg.group(1))
 		elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB1SourceCodePath = matchReg.group(1)
+			RAN.SeteNB1SourceCodePath(matchReg.group(1))
 		elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 			matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-			SSH.eNB2SourceCodePath = matchReg.group(1)
+			RAN.SeteNB2SourceCodePath(matchReg.group(1))
 	elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		SSH.EPCIPAddress = matchReg.group(1)
-	elif re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE):
-		matchReg = re.match('^\-\-EPCBranch=(.+)$', myArgv, re.IGNORECASE)
-		SSH.EPCBranch = matchReg.group(1)
+		EPC.SetIPAddress(matchReg.group(1))
 	elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE)
-		SSH.EPCUserName = matchReg.group(1)
+		EPC.SetUserName(matchReg.group(1))
 	elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE)
-		SSH.EPCPassword = matchReg.group(1)
+		EPC.SetPassword(matchReg.group(1))
 	elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-		SSH.EPCSourceCodePath = matchReg.group(1)
+		EPC.SetSourceCodePath(matchReg.group(1))
 	elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE)
-		if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE):
-			SSH.EPCType = matchReg.group(1)
+		if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE):
+			EPC.SetType(matchReg.group(1))
 		else:
-			sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS)')
+			sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)')
+	elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE):
+		matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE)
+		EPC.SetContainerPrefix(matchReg.group(1))
 	elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		SSH.ADBIPAddress = matchReg.group(1)
+		CiTestObj.ADBIPAddress = matchReg.group(1)
 	elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE)
-		SSH.ADBUserName = matchReg.group(1)
+		CiTestObj.ADBUserName = matchReg.group(1)
 	elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE)
 		if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE):
 			if re.match('distributed', matchReg.group(1), re.IGNORECASE):
-				SSH.ADBCentralized = False
+				CiTestObj.ADBCentralized = False
 			else:
-				SSH.ADBCentralized = True
+				CiTestObj.ADBCentralized = True
 		else:
 			sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)')
 	elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE)
-		SSH.ADBPassword = matchReg.group(1)
+		CiTestObj.ADBPassword = matchReg.group(1)
 	elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
-		SSH.testXMLfiles.append(matchReg.group(1))
-		SSH.nbTestXMLfiles += 1
+		CiTestObj.testXMLfiles.append(matchReg.group(1))
+		HTML.SettestXMLfiles(matchReg.group(1))
+		HTML.SetnbTestXMLfiles(HTML.GetnbTestXMLfiles()+1)
 	elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
-		SSH.UEIPAddress = matchReg.group(1)
+		CiTestObj.UEIPAddress = matchReg.group(1)
 	elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
-		SSH.UEUserName = matchReg.group(1)
+		CiTestObj.UEUserName = matchReg.group(1)
 	elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
-		SSH.UEPassword = matchReg.group(1)
+		CiTestObj.UEPassword = matchReg.group(1)
 	elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
-		SSH.UESourceCodePath = matchReg.group(1)
+		CiTestObj.UESourceCodePath = matchReg.group(1)
 	elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
 		matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
 		finalStatus = matchReg.group(1)
 		if ((finalStatus == 'true') or (finalStatus == 'True')):
-			SSH.finalStatus = True
+			CiTestObj.finalStatus = True
 	else:
-		Usage()
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Invalid Parameter: ' + myArgv)
 
 if re.match('^TerminateeNB$', mode, re.IGNORECASE):
-	if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '':
-		Usage()
+	if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.eNB_serverId = '0'
-	SSH.eNB_instance = '0'
-	SSH.eNBSourceCodePath = '/tmp/'
-	SSH.TerminateeNB()
+	RAN.SeteNB_serverId('0')
+	RAN.SeteNB_instance('0')
+	RAN.SeteNBSourceCodePath('/tmp/')
+	RAN.TerminateeNB()
 elif re.match('^TerminateUE$', mode, re.IGNORECASE):
-	if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
-		Usage()
+	if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''):
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	signal.signal(signal.SIGUSR1, receive_signal)
-	SSH.TerminateUE()
+	CiTestObj.TerminateUE()
 elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
-	if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '':
-		Usage()
+	if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	signal.signal(signal.SIGUSR1, receive_signal)
-	SSH.TerminateOAIUE()
+	CiTestObj.TerminateOAIUE()
 elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.TerminateHSS()
+	EPC.TerminateHSS()
 elif re.match('^TerminateMME$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.TerminateMME()
+	EPC.TerminateMME()
 elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.TerminateSPGW()
+	EPC.TerminateSPGW()
 elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
-	if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''):
-		Usage()
+	if (RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''):
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectBuild()
+	CiTestObj.LogCollectBuild()
 elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
-	if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '':
-		Usage()
+	if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollecteNB()
+	RAN.LogCollecteNB()
 elif re.match('^LogCollectHSS$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectHSS()
+	EPC.LogCollectHSS()
 elif re.match('^LogCollectMME$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectMME()
+	EPC.LogCollectMME()
 elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectSPGW()
+	EPC.LogCollectSPGW()
 elif re.match('^LogCollectPing$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectPing()
+	CiTestObj.LogCollectPing()
 elif re.match('^LogCollectIperf$', mode, re.IGNORECASE):
-	if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCSourceCodePath == '':
-		Usage()
+	if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectIperf()
+	CiTestObj.LogCollectIperf()
 elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE):
-	if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
-		Usage()
+	if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '':
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
-	SSH.LogCollectOAIUE()
+	CiTestObj.LogCollectOAIUE()
 elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
-	if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
-		Usage()
+	if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''):
+		HELP.GenericHelp(CONST.Version)
 		sys.exit('Insufficient Parameter')
 	count = 0
 	foundCount = 0
-	while (count < SSH.nbTestXMLfiles):
-		xml_test_file = cwd + "/" + SSH.testXMLfiles[count]
+	while (count < HTML.GetnbTestXMLfiles()):
+		#xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[count]
+		xml_test_file = sys.path[0] + "/" + CiTestObj.testXMLfiles[count]
 		if (os.path.isfile(xml_test_file)):
 			try:
 				xmlTree = ET.parse(xml_test_file)
 			except:
 				print("Error while parsing file: " + xml_test_file)
 			xmlRoot = xmlTree.getroot()
-			SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
-			SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count)))
-			SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
+			HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
+			HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='test-tab-' + str(count)))
+			HTML.SethtmlTabIcons(xmlRoot.findtext('htmlTabIcon',default='info-sign'))
 			foundCount += 1
 		count += 1
-	if foundCount != SSH.nbTestXMLfiles:
-		SSH.nbTestXMLfiles = foundCount
-	SSH.CreateHtmlHeader()
+	if foundCount != HTML.GetnbTestXMLfiles():
+		HTML.SetnbTestXMLfiles(foundcount)
+	
+	if (CiTestObj.ADBIPAddress != 'none'):
+		terminate_ue_flag = False
+		CiTestObj.GetAllUEDevices(terminate_ue_flag)
+		CiTestObj.GetAllCatMDevices(terminate_ue_flag)
+		HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
+		HTML.SethtmlNb_Smartphones(len(CiTestObj.UEDevices))
+		HTML.SethtmlNb_CATM_Modules(len(CiTestObj.CatMDevices))
+	HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress)
 elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
-	SSH.CreateHtmlFooter(SSH.finalStatus)
+	logging.debug('\u001B[1m----------------------------------------\u001B[0m')
+	logging.debug('\u001B[1m  Creating HTML footer \u001B[0m')
+	logging.debug('\u001B[1m----------------------------------------\u001B[0m')
+
+	CiTestObj.RetrieveSystemVersion('eNB')
+	CiTestObj.RetrieveSystemVersion('UE')
+	HTML.CreateHtmlFooter(CiTestObj.finalStatus)
 elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
 	if re.match('^TesteNB$', mode, re.IGNORECASE):
-		if SSH.eNBIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
-			Usage()
+		if RAN.GeteNBIPAddress() == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '':
+			HELP.GenericHelp(CONST.Version)
+			if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '':
+				HELP.EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType())
+			if RAN.GetranRepository() == '':
+				HELP.GitSrvHelp(RAN.GetranRepository(), RAN.GetranBranch(), RAN.GetranCommitID(), RAN.GetranAllowMerge(), RAN.GetranTargetBranch())
+			if RAN.GeteNBIPAddress() == ''  or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '':
+				HELP.eNBSrvHelp(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath())
 			sys.exit('Insufficient Parameter')
 
-		if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
-			SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp")
-			SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp")
+		if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'):
+			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/tcp_iperf_stats.awk", "/tmp")
+			SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/active_net_interfaces.awk", "/tmp")
 	else:
-		if SSH.UEIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
-			Usage()
+		if CiTestObj.UEIPAddress == '' or CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '':
+			HELP.GenericHelp(CONST.Version)
 			sys.exit('UE: Insufficient Parameter')
 
 	#read test_case_list.xml file
 	# if no parameters for XML file, use default value
-	if (SSH.nbTestXMLfiles != 1):
+	if (HTML.GetnbTestXMLfiles() != 1):
 		xml_test_file = cwd + "/test_case_list.xml"
 	else:
-		xml_test_file = cwd + "/" + SSH.testXMLfiles[0]
+		xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0]
 
 	xmlTree = ET.parse(xml_test_file)
 	xmlRoot = xmlTree.getroot()
 
 	exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='')
 	requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='')
-	if (SSH.nbTestXMLfiles == 1):
-		SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0'))
-		SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0'))
+	if (HTML.GetnbTestXMLfiles() == 1):
+		HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-0'))
+		HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='Test-0'))
 		repeatCount = xmlRoot.findtext('repeatCount',default='1')
-		SSH.repeatCounts.append(int(repeatCount))
+		CiTestObj.repeatCounts.append(int(repeatCount))
 	all_tests=xmlRoot.findall('testCase')
 
 	exclusion_tests=exclusion_tests.split()
@@ -5136,8 +3579,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 		else:
 			logging.debug('ERROR: requested test is invalidly formatted: ' + test)
 			sys.exit(1)
-	if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
-		SSH.CheckFlexranCtrlInstallation()
+	if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'):
+		CiTestObj.CheckFlexranCtrlInstallation()
+		EPC.SetMmeIPAddress()
 
 	#get the list of tests to be done
 	todo_tests=[]
@@ -5150,108 +3594,125 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
 
 	signal.signal(signal.SIGUSR1, receive_signal)
 
-	SSH.CreateHtmlTabHeader()
-
-	cnt = 0
-	SSH.prematureExit = True
-	SSH.startTime = int(round(time.time() * 1000))
-	while cnt < SSH.repeatCounts[0] and SSH.prematureExit:
-		SSH.prematureExit = False
+	if (CiTestObj.ADBIPAddress != 'none'):
+		terminate_ue_flag = False
+		CiTestObj.GetAllUEDevices(terminate_ue_flag)
+		CiTestObj.GetAllCatMDevices(terminate_ue_flag)
+	else:
+		CiTestObj.UEDevices.append('OAI-UE')
+	HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices))
+	HTML.CreateHtmlTabHeader()
+
+	CiTestObj.FailReportCnt = 0
+	RAN.SetprematureExit(True)
+	HTML.SetstartTime(int(round(time.time() * 1000)))
+	while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.GetprematureExit():
+		RAN.SetprematureExit(False)
+		# At every iteratin of the retry loop, a separator will be added
+		# pass CiTestObj.FailReportCnt as parameter of HTML.CreateHtmlRetrySeparator
+		HTML.CreateHtmlRetrySeparator(CiTestObj.FailReportCnt)
 		for test_case_id in todo_tests:
-			if SSH.prematureExit:
+			if RAN.GetprematureExit():
 				break
 			for test in all_tests:
-				if SSH.prematureExit:
+				if RAN.GetprematureExit():
 					break
 				id = test.get('id')
 				if test_case_id != id:
 					continue
-				SSH.testCase_id = id
-				SSH.desc = test.findtext('desc')
+				CiTestObj.testCase_id = id
+				HTML.SettestCase_id(CiTestObj.testCase_id)
+				EPC.SetTestCase_id(CiTestObj.testCase_id)
+				CiTestObj.desc = test.findtext('desc')
+				HTML.Setdesc(CiTestObj.desc)
 				action = test.findtext('class')
 				if (CheckClassValidity(action, id) == False):
 					continue
-				SSH.ShowTestID()
+				CiTestObj.ShowTestID()
 				GetParametersFromXML(action)
 				if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
-					if (SSH.ADBIPAddress != 'none'):
+					if (CiTestObj.ADBIPAddress != 'none'):
 						terminate_ue_flag = False
-						SSH.GetAllUEDevices(terminate_ue_flag)
+						CiTestObj.GetAllUEDevices(terminate_ue_flag)
 				if action == 'Build_eNB':
-					SSH.BuildeNB()
+					RAN.BuildeNB()
 				elif action == 'WaitEndBuild_eNB':
-					SSH.WaitBuildeNBisFinished()
+					RAN.WaitBuildeNBisFinished()
 				elif action == 'Initialize_eNB':
-					SSH.InitializeeNB()
+					check_eNB = False
+					check_OAI_UE = False
+					RAN.SetpStatus(CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE))
+
+					RAN.InitializeeNB()
 				elif action == 'Terminate_eNB':
-					SSH.TerminateeNB()
+					RAN.TerminateeNB()
 				elif action == 'Initialize_UE':
-					SSH.InitializeUE()
+					CiTestObj.InitializeUE()
 				elif action == 'Terminate_UE':
-					SSH.TerminateUE()
+					CiTestObj.TerminateUE()
 				elif action == 'Attach_UE':
-					SSH.AttachUE()
+					CiTestObj.AttachUE()
 				elif action == 'Detach_UE':
-					SSH.DetachUE()
+					CiTestObj.DetachUE()
 				elif action == 'DataDisable_UE':
-					SSH.DataDisableUE()
+					CiTestObj.DataDisableUE()
 				elif action == 'DataEnable_UE':
-					SSH.DataEnableUE()
+					CiTestObj.DataEnableUE()
 				elif action == 'CheckStatusUE':
-					SSH.CheckStatusUE()
+					CiTestObj.CheckStatusUE()
 				elif action == 'Build_OAI_UE':
-					SSH.BuildOAIUE()
+					CiTestObj.BuildOAIUE()
 				elif action == 'Initialize_OAI_UE':
-					SSH.InitializeOAIUE()
+					CiTestObj.InitializeOAIUE()
 				elif action == 'Terminate_OAI_UE':
-					SSH.TerminateOAIUE()
+					CiTestObj.TerminateOAIUE()
 				elif action == 'Initialize_CatM_module':
-					SSH.InitializeCatM()
+					CiTestObj.InitializeCatM()
 				elif action == 'Terminate_CatM_module':
-					SSH.TerminateCatM()
+					CiTestObj.TerminateCatM()
 				elif action == 'Attach_CatM_module':
-					SSH.AttachCatM()
+					CiTestObj.AttachCatM()
 				elif action == 'Detach_CatM_module':
-					SSH.TerminateCatM()
+					CiTestObj.TerminateCatM()
 				elif action == 'Ping_CatM_module':
-					SSH.PingCatM()
+					CiTestObj.PingCatM()
 				elif action == 'Ping':
-					SSH.Ping()
+					CiTestObj.Ping()
 				elif action == 'Iperf':
-					SSH.Iperf()
+					CiTestObj.Iperf()
 				elif action == 'Reboot_UE':
-					SSH.RebootUE()
+					CiTestObj.RebootUE()
 				elif action == 'Initialize_HSS':
-					SSH.InitializeHSS()
+					EPC.InitializeHSS()
 				elif action == 'Terminate_HSS':
-					SSH.TerminateHSS()
+					EPC.TerminateHSS()
 				elif action == 'Initialize_MME':
-					SSH.InitializeMME()
+					EPC.InitializeMME()
 				elif action == 'Terminate_MME':
-					SSH.TerminateMME()
+					EPC.TerminateMME()
 				elif action == 'Initialize_SPGW':
-					SSH.InitializeSPGW()
+					EPC.InitializeSPGW()
 				elif action == 'Terminate_SPGW':
-					SSH.TerminateSPGW()
+					EPC.TerminateSPGW()
 				elif action == 'Initialize_FlexranCtrl':
-					SSH.InitializeFlexranCtrl()
+					CiTestObj.InitializeFlexranCtrl()
 				elif action == 'Terminate_FlexranCtrl':
-					SSH.TerminateFlexranCtrl()
+					CiTestObj.TerminateFlexranCtrl()
 				elif action == 'IdleSleep':
-					SSH.IdleSleep()
+					CiTestObj.IdleSleep()
 				elif action == 'Perform_X2_Handover':
-					SSH.Perform_X2_Handover()
+					CiTestObj.Perform_X2_Handover()
 				else:
 					sys.exit('Invalid action')
-		cnt += 1
-	if cnt == SSH.repeatCounts[0] and SSH.prematureExit:
-		logging.debug('Testsuite failed ' + str(cnt) + ' time(s)')
-		SSH.CreateHtmlTabFooter(False)
+		CiTestObj.FailReportCnt += 1
+	if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.GetprematureExit():
+		logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)')
+		HTML.CreateHtmlTabFooter(False)
 		sys.exit('Failed Scenario')
 	else:
-		logging.info('Testsuite passed after ' + str(cnt) + ' time(s)')
-		SSH.CreateHtmlTabFooter(True)
+		logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)')
+		HTML.CreateHtmlTabFooter(True)
 else:
-	Usage()
+	HELP.GenericHelp(CONST.Version)
 	sys.exit('Invalid mode')
 sys.exit(0)
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index 54372ac6ba7..0a75ff25b7b 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -492,6 +492,77 @@ function report_build {
             awk '{print "      <tr><td>"$1"</td></tr>"}' ./oai_rules_result_list.txt >> ./build_results.html
             echo "   </table>" >> ./build_results.html
             echo "   </div>" >> ./build_results.html
+            echo "   <br>" >> ./build_results.html
+        fi
+        if [ -f ./header-files-w-incorrect-define.txt ]
+        then
+            NB_FILES_IN_ERROR=`wc -l ./header-files-w-incorrect-define.txt | sed -e "s@ .*@@"`
+            if [ $NB_FILES_IN_ERROR -eq 0 ]
+            then
+                echo "   <div class=\"alert alert-success\">" >> ./build_results.html
+                if [ $MR_TRIG -eq 1 ]; then echo "   <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in modified files</strong>" >> ./build_results.html; fi
+                if [ $PU_TRIG -eq 1 ]; then echo "   <strong>No Issue for CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
+                echo "   </div>" >> ./build_results.html
+            else
+                echo "   <div class=\"alert alert-warning\">" >> ./build_results.html
+                if [ $MR_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} modified files MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION</strong>" >> ./build_results.html; fi
+                if [ $PU_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} files in repository MAY NOT HAVE CIRCULAR DEPENDENCY PROTECTION in the whole repository</strong>" >> ./build_results.html; fi
+                echo "   </div>" >> ./build_results.html
+                echo "   <button data-toggle=\"collapse\" data-target=\"#oai-circular-details\">More details on circular dependency protection check</button>" >> ./build_results.html
+                echo "   <div id=\"oai-circular-details\" class=\"collapse\">" >> ./build_results.html
+                echo "   <table border = 1>" >> ./build_results.html
+                echo "      <tr>" >> ./build_results.html
+                echo "        <th bgcolor = \"lightcyan\" >Potential Issue</th>" >> ./build_results.html
+                echo "        <th bgcolor = \"lightcyan\" >Impacted File</th>" >> ./build_results.html
+                echo "        <th bgcolor = \"lightcyan\" >Incorrect Macro</th>" >> ./build_results.html
+                echo "      </tr>" >> ./build_results.html
+                awk '{if($0 ~/error in/){print "      <tr><td>error in declaration</td><td>"$4"</td><td>"$5"</td></tr>"};if($0 ~/files with same/){print "      <tr><td>files with same #define</td><td>"$5"</td><td>"$6"</td></tr>"}}' ./header-files-w-incorrect-define.txt >> ./build_results.html
+                echo "   </table>" >> ./build_results.html
+                echo "   </div>" >> ./build_results.html
+                echo "   <br>" >> ./build_results.html
+            fi
+        fi
+        if [ -f ./files-w-gnu-gpl-license-banner.txt ]
+        then
+            NB_FILES_IN_ERROR=`wc -l ./files-w-gnu-gpl-license-banner.txt | sed -e "s@ .*@@"`
+            if [ $NB_FILES_IN_ERROR -ne 0 ]
+            then
+                echo "   <div class=\"alert alert-danger\">" >> ./build_results.html
+                if [ $MR_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} modified files HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
+                if [ $PU_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} files in repository HAVE a GNU GPL license banner</strong>" >> ./build_results.html; fi
+                echo "   </div>" >> ./build_results.html
+                echo "   <button data-toggle=\"collapse\" data-target=\"#oai-license-gpl\">More details on GNU GPL license banner issue</button>" >> ./build_results.html
+                echo "   <div id=\"oai-license-gpl\" class=\"collapse\">" >> ./build_results.html
+                echo "   <table border = 1>" >> ./build_results.html
+                echo "      <tr>" >> ./build_results.html
+                echo "        <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
+                echo "      </tr>" >> ./build_results.html
+                awk '{print "      <tr><td>"$1"</td></tr>"}' ./files-w-gnu-gpl-license-banner.txt >> ./build_results.html
+                echo "   </table>" >> ./build_results.html
+                echo "   </div>" >> ./build_results.html
+                echo "   <br>" >> ./build_results.html
+            fi
+        fi
+        if [ -f ./files-w-suspect-banner.txt ]
+        then
+            NB_FILES_IN_ERROR=`wc -l ./files-w-suspect-banner.txt | sed -e "s@ .*@@"`
+            if [ $NB_FILES_IN_ERROR -ne 0 ]
+            then
+                echo "   <div class=\"alert alert-warning\">" >> ./build_results.html
+                if [ $MR_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} modified files HAVE a suspect license banner</strong>" >> ./build_results.html; fi
+                if [ $PU_TRIG -eq 1 ]; then echo "   <strong>${NB_FILES_IN_ERROR} files in repository HAVE a suspect license banner</strong>" >> ./build_results.html; fi
+                echo "   </div>" >> ./build_results.html
+                echo "   <button data-toggle=\"collapse\" data-target=\"#oai-license-suspect\">More details on suspect banner files</button>" >> ./build_results.html
+                echo "   <div id=\"oai-license-suspect\" class=\"collapse\">" >> ./build_results.html
+                echo "   <table border = 1>" >> ./build_results.html
+                echo "      <tr>" >> ./build_results.html
+                echo "        <th bgcolor = \"lightcyan\" >Filename</th>" >> ./build_results.html
+                echo "      </tr>" >> ./build_results.html
+                awk '{print "      <tr><td>"$1"</td></tr>"}' ././files-w-suspect-banner.txt >> ./build_results.html
+                echo "   </table>" >> ./build_results.html
+                echo "   </div>" >> ./build_results.html
+                echo "   <br>" >> ./build_results.html
+            fi
         fi
     fi
 
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 502c1a5d479..64af11c8ba6 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -342,34 +342,8 @@ function check_iperf {
         local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt`
         if [ $FILE_COMPLETE -eq 0 ]
         then
-            # This part will become obsolete once we have UL
-            if [[ $LOC_IS_RF_SIM -eq 1 ]] && [[ $LOC_IS_NR -eq 1 ]]
-            then
-                echo "no UL integration right now --> normal to have no server report"
-                if [ -f ${LOC_BASE_LOG}_server.txt ]
-                then
-                    local EFFECTIVE_BANDWIDTH=`tail -n1 ${LOC_BASE_LOG}_server.txt | sed -e "s#^.*MBytes *##" -e "s#^.*KBytes *##" -e "s#sec.*#sec#"`
-                    if [[ $2 =~ .*K.* ]]
-                    then
-                        local BW_PREFIX="K"
-                    else
-                        local BW_PREFIX="M"
-                    fi
-                    if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_PREFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_PREFIX}bits.* ]]
-                    then
-                        echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH"
-                    else
-                        echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH"
-                        IPERF_STATUS=-1
-                    fi
-                else
-                    IPERF_STATUS=-1
-                    echo "Server File Report not found"
-                fi
-            else
-                IPERF_STATUS=-1
-                echo "File Report not found"
-            fi
+            IPERF_STATUS=-1
+            echo "File Report not found"
         else
             if [ `egrep -c "Mbits/sec" ${LOC_BASE_LOG}_client.txt` -ne 0 ]
             then
@@ -2044,81 +2018,117 @@ function run_test_on_vm {
 
     if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]]
     then
-        NR_STATUS=0
-        PING_STATUS=0
-        IPERF_STATUS=0
-
         CN_CONFIG="noS1"
         CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
         S1_NOS1_CFG=0
         PRB=106
         FREQUENCY=3510
 
+        local try_cnt="0"
+        NR_STATUS=0
+
         ######### start of loop
+        while [ $try_cnt -lt 5 ]
+        do
+            SYNC_STATUS=0
+            PING_STATUS=0
+            IPERF_STATUS=0
 
-        echo "############################################################"
-        echo "${CN_CONFIG} : Starting the gNB"
-        echo "############################################################"
-        CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
-        start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the gNB"
+            echo "############################################################"
+            CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
+            start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG
 
-        echo "############################################################"
-        echo "${CN_CONFIG} : Starting the NR-UE"
-        echo "############################################################"
-        CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
-        start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG
-        if [ $NR_UE_SYNC -eq 0 ]
-        then
-            echo "Problem w/ gNB and NR-UE not syncing"
-            terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
-            terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
-            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
-            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
-            echo "5G-NR RFSIM seems to FAIL"
-            echo "5G-NR: TEST_KO" >> $ARCHIVES_LOC/test_final_status.log
-            STATUS=-1
-            return
-        fi
+            echo "############################################################"
+            echo "${CN_CONFIG} : Starting the NR-UE"
+            echo "############################################################"
+            CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
+            start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG
+            if [ $NR_UE_SYNC -eq 0 ]
+            then
+                echo "Problem w/ gNB and NR-UE not syncing"
+                terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
+                terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+                SYNC_STATUS=-1
+                try_cnt=$[$try_cnt+1]
+                continue
+            fi
 
-        echo "############################################################"
-        echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client"
-        echo "############################################################"
-        THROUGHPUT="30K"
-        CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl
-        get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
-        get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
-        generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 
-        scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
-        scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
-        check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT
+            echo "############################################################"
+            echo "${CN_CONFIG} : Pinging the gNB from NR-UE"
+            echo "############################################################"
+            get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
+            PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log
+            ping_epc_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0
+            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+            check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
 
-        echo "############################################################"
-        echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client"
-        echo "############################################################"
-        THROUGHPUT="30K"
-        CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul
-        get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
-        get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
-        generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0
-        scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
-        scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
-        check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT
+            echo "############################################################"
+            echo "${CN_CONFIG} : Pinging the NR-UE from gNB"
+            echo "############################################################"
+            get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
+            PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
+            ping_enb_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0
+            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+            check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
 
-        echo "############################################################"
-        echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators"
-        echo "############################################################"
-        terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
-        terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
-        scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
-        scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
+            echo "############################################################"
+            echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client"
+            echo "############################################################"
+            THROUGHPUT="30K"
+            CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl
+            get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
+            get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
+            generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 
+            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
+            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
+            check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT
+            if [ $IPERF_STATUS -ne 0 ]
+            then
+                echo "DL test not OK"
+                terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
+                terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+                try_cnt=$[$try_cnt+1]
+                continue
+            fi
 
+            echo "############################################################"
+            echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client"
+            echo "############################################################"
+            THROUGHPUT="30K"
+            CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul
+            get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
+            get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
+            generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0
+            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
+            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
+            check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT
+
+            echo "############################################################"
+            echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators"
+            echo "############################################################"
+            terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
+            terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+            scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+            scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
+            if [ $IPERF_STATUS -ne 0 ]
+            then
+                echo "UL test not OK"
+                try_cnt=$[$try_cnt+1]
+            else
+                try_cnt=$[$try_cnt+10]
+            fi
+        done
         ######### end of loop
         full_l2_sim_destroy
 
+
         echo "############################################################"
         echo "Checking run status"
         echo "############################################################"
 
+        if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi
         if [ $NR_STATUS -eq 0 ]
diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml
index 680f09c435e..611492b0bcd 100644
--- a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml
@@ -24,7 +24,7 @@
 	<htmlTabRef>test-lte-m-10-tm1</htmlTabRef>
 	<htmlTabName>Test-LTE-M-10MHz-TM1</htmlTabName>
 	<htmlTabIcon>tasks</htmlTabIcon>
-	<repeatCount>2</repeatCount>
+	<repeatCount>1</repeatCount>
 	<TestCaseRequestedList>
  030201
  040102
diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
index 2a035396c57..09aa0b04a2a 100644
--- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
@@ -25,7 +25,7 @@
 	<htmlTabRef>test-05-tm2</htmlTabRef>
 	<htmlTabName>Test-05MHz-TM2</htmlTabName>
 	<htmlTabIcon>tasks</htmlTabIcon>
-	<repeatCount>3</repeatCount>
+	<repeatCount>2</repeatCount>
         <TestCaseRequestedList>
  030201
  040101
diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
index a28a81d970c..41e746bc85d 100644
--- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xml
@@ -33,8 +33,8 @@
 
 	<testCase id="000001">
 		<class>IdleSleep</class>
-		<desc>Waiting for 35 seconds</desc>
-		<idle_sleep_time_in_sec>35</idle_sleep_time_in_sec>
+		<desc>Waiting for 55 seconds</desc>
+		<idle_sleep_time_in_sec>55</idle_sleep_time_in_sec>
 	</testCase>
 
 	<testCase id="000002">
diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml
index 07cd8fbb304..6ee9247ef34 100644
--- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_w_flexran.xml
@@ -36,8 +36,8 @@
 
 	<testCase id="000001">
 		<class>IdleSleep</class>
-		<desc>Waiting for 45 seconds</desc>
-		<idle_sleep_time_in_sec>45</idle_sleep_time_in_sec>
+		<desc>Waiting for 55 seconds</desc>
+		<idle_sleep_time_in_sec>55</idle_sleep_time_in_sec>
 	</testCase>
 
 	<testCase id="000002">
diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml
index 0196bf1ab65..ae348b6b259 100644
--- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml
+++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1.xml
@@ -46,7 +46,7 @@
 	<testCase id="030102">
 		<class>Initialize_eNB</class>
 		<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95</Initialize_eNB_args>
 	</testCase>
 
 	<testCase id="030201">
diff --git a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml
index c2835d04615..b77c6273e68 100644
--- a/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml
+++ b/ci-scripts/xml_files/inria/enb_ue_usrp210_band7_test_05mhz_tm1_nos1.xml
@@ -52,7 +52,7 @@
 	<testCase id="030101">
 		<class>Initialize_eNB</class>
 		<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95</Initialize_eNB_args>
 	</testCase>
 
 	<testCase id="030201">
diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml
index 964550d872b..df41385f838 100644
--- a/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml
+++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_test_05mhz_tm1.xml
@@ -93,7 +93,7 @@
 	<testCase id="030103">
 		<class>Initialize_eNB</class>
 		<desc>Initialize eNB (FDD/Band7/5MHz)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95</Initialize_eNB_args>
 	</testCase>
 
 	<testCase id="030201">
diff --git a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml
index 22f8b632660..852f48c370e 100644
--- a/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml
+++ b/ci-scripts/xml_files/inria/enb_usrp210_band7_x2_ho_test_05Mhz_tm1.xml
@@ -64,7 +64,7 @@
 	<testCase id="030104">
 		<class>Initialize_eNB</class>
 		<desc>Initialize eNB #0 (FDD/Band7/5MHz)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 123456</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 123456</Initialize_eNB_args>
 		<eNB_instance>0</eNB_instance>
 		<eNB_serverId>0</eNB_serverId>
 	</testCase>
@@ -72,7 +72,7 @@
 	<testCase id="030105">
 		<class>Initialize_eNB</class>
 		<desc>Initialize eNB #1 (FDD/Band7/5MHz)</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --THREAD_STRUCT.[0].parallel_config PARALLEL_RU_L1_TRX_SPLIT --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 98765</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf --eNBs.[0].rrc_inactivity_threshold 0 --RUs.[0].max_rxgain 120 --eNBs.[0].component_carriers.[0].pusch_p0_Nominal -90 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --eNBs.[0].tracking_area_code 600 --eNBs.[0].plmn_list.[0].mnc 95 --eNBs.[0].enable_measurement_reports yes --eNBs.[0].enable_x2 yes --eNBs.[0].nr_cellid 98765</Initialize_eNB_args>
 		<eNB_instance>1</eNB_instance>
 		<eNB_serverId>1</eNB_serverId>
 	</testCase>
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 72c7d319db4..bb8f9024f95 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -20,9 +20,15 @@
 # */
 
 # Author: laurent THOMAS, Lionel GAUTHIER
-
+###################### FOR CUDA#############################
+# author NCTU OpinConnect Terng-Yin Hsu,WEI-YING,LIN:
+# Add for PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
+# email tyhsu@cs.nctu.edu.tw
+###################### FOR CUDA#############################
 cmake_minimum_required (VERSION 3.0)
 
+
+
 ##############################################
 # Base CUDA setting
 ##############################################
@@ -33,7 +39,7 @@ message ("cuda library ${CUDA_LIBRARY_DIRS}")
 add_definitions("-L/usr/local/cuda/lib64")
 
 SET(CUDA_NVCC_FLAGS
-  "${CUDA_NVCC_FLAGS};-arch=sm_60")
+  "${CUDA_NVCC_FLAGS};-arch=sm_75;")
 
 # Disable warnings for CUDA
 SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-lpthread;-w;-O3;--default-stream;per-thread;-I/usr/local/cuda/inc;-L/usr/local/cuda/lib -lcutil;-rdc=true;-lcudadevrt")
@@ -186,14 +192,14 @@ endif()
 
 #
 set(CMAKE_C_FLAGS
-  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC")
+  "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -pipe -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC")
 # add autotools definitions that were maybe used!
-set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
+# set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
 set(CMAKE_C_FLAGS
-	"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}"
+	"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP "
 )
 set(CMAKE_CXX_FLAGS
-	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11" #-D${MKVER}
+	"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic -std=c++11 "
 )
 
 add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -746,7 +752,6 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}")
 ##############################################################
 
 add_boolean_option(NO_RRM                  True  "DO WE HAVE A RADIO RESSOURCE MANAGER: NO")
-add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the default bearer")
 
 add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????")
 add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
@@ -847,7 +852,7 @@ add_boolean_option(TRACE_RLC_UM_TX_STATUS  False "TRACE for RLC UM, TO BE CHANGE
 ##########################
 # RRC LAYER OPTIONS
 ##########################
-add_boolean_option(RRC_DEFAULT_RAB_IS_AM       False  "Otherwise it is UM, configure params are actually set in rrc_eNB.c:rrc_eNB_generate_defaultRRCConnectionReconfiguration(...)")
+add_boolean_option(RRC_DEFAULT_RAB_IS_AM       True   "set the RLC mode to AM for the default bearer, otherwise it is UM.")
 
 
 ##########################
@@ -903,6 +908,7 @@ include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0")
 include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
 include_directories("${OPENAIR2_DIR}/RRC/LTE")
 include_directories("${OPENAIR_DIR}/common/utils")
+include_directories("${OPENAIR_DIR}/common/utils/collection")
 include_directories("${OPENAIR_DIR}/common/utils/ocp_itti")
 include_directories("${OPENAIR3_DIR}/NAS/COMMON")
 include_directories("${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK")
@@ -1323,7 +1329,6 @@ set(PHY_TURBOIF
 
 set(PHY_LDPC_ORIG_SRC
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
-  ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c
 )
 
@@ -1350,6 +1355,9 @@ add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
 
 add_library(coding MODULE ${PHY_TURBOSRC} )
 
+add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c )
+
+
 set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -1390,7 +1398,7 @@ set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
   ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
   ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
-  ${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
+  ${OPENAIR1_DIR}/PHY/TOOLS/dfts_load.c
   ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
   ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
   ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
@@ -1515,6 +1523,7 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
+  ${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
@@ -1536,6 +1545,7 @@ set(PHY_SRC_UE
   ${PHY_SMALLBLOCKSRC}
   ${PHY_NR_CODINGIF}
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c 
+  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
   )
   set(PHY_NR_UE_SRC
   ${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
@@ -1559,6 +1569,7 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
+  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -1605,7 +1616,9 @@ endif ()
 
 add_library(PHY_COMMON ${PHY_SRC_COMMON})
 add_dependencies(PHY_COMMON rrc_flag)
+add_dependencies(PHY_COMMON dfts)
 add_library(PHY ${PHY_SRC})
+
 add_dependencies(PHY rrc_flag)
 add_library(PHY_UE ${PHY_SRC_UE})
 add_dependencies(PHY_UE rrc_flag)
@@ -1656,7 +1669,7 @@ set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR)
 set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE)
 set(PDCP_DIR  ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0)
 
-set(LTE_RLC_SRC
+set(RLC_V1
   ${RLC_AM_DIR}/rlc_am.c
   ${RLC_AM_DIR}/rlc_am_init.c
   ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
@@ -1686,6 +1699,17 @@ set(LTE_RLC_SRC
   ${RLC_DIR}/rlc_mpls.c
   )
 
+set(RLC_V2
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_oai_api.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/asn1_utils.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_ue_manager.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity_am.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_entity_um.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_pdu.c
+  ${OPENAIR2_DIR}/LAYER2/rlc_v2/rlc_sdu.c
+  )
+
 set(NR_RLC_SRC
   ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c
   ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c
@@ -1720,7 +1744,7 @@ set(L2_SRC
   )
 
 set(L2_LTE_SRC
-  ${LTE_RLC_SRC}
+  ${RLC_V2}
   )
 
 set(L2_NR_SRC
@@ -1757,7 +1781,7 @@ set(LTE_NR_L2_SRC_UE
   ${PDCP_DIR}/pdcp_util.c
   ${PDCP_DIR}/pdcp_security.c
   ${PDCP_DIR}/pdcp_netlink.c
-  ${LTE_RLC_SRC}
+  ${RLC_V2}
   )
 
 set(NR_L2_SRC_UE
@@ -2441,9 +2465,9 @@ endif (${T_TRACER})
 #This rule and the following deal with it.
 add_custom_command (
   OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h
-  COMMAND $(MAKE) clean
-  COMMAND $(MAKE)
-  COMMAND $(MAKE) check_vcd
+  COMMAND make clean
+  COMMAND make
+  COMMAND make check_vcd
   WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
   DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt
           ${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
@@ -2497,6 +2521,7 @@ add_executable(lte-softmodem
   ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
   ${OPENAIR_TARGETS}/RT/USER/ru_control.c
   ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${OPENAIR_DIR}/executables/softmodem-common.c
   ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
@@ -2532,6 +2557,43 @@ target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_L
 target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
 target_link_libraries (lte-softmodem ${T_LIB})
 
+
+add_executable(ocp-enb
+  ${OPENAIR_DIR}/executables/main-ocp.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
+  ${OPENAIR_DIR}/executables/softmodem-common.c
+  ${OPENAIR_DIR}/executables/main-fs6.c
+  ${OPENAIR_DIR}/executables/transport_split.c
+  ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
+  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
+  ${OPENAIR_TARGETS}/COMMON/create_tasks.c
+  ${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c
+  ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+  ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
+  ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
+  ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
+  ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
+  ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
+  ${OPENAIR_DIR}/common/utils/utils.c
+  ${OPENAIR_DIR}/common/utils/system.c
+  ${GTPU_need_ITTI}
+  ${XFORMSINTERFACE_SOURCE}
+  ${T_SOURCE}
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
+  )
+add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer)
+
+target_link_libraries (ocp-enb
+  -Wl,--start-group
+  RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB 
+  PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
+  ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
+  -Wl,--end-group z dl)
+target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB}  ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
+
 add_executable(cu_test
   ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c
   ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c
@@ -2763,46 +2825,38 @@ target_link_libraries(smallblocktest
   m pthread ${ATLAS_LIBRARIES} dl
   )
 
-<<<<<<< HEAD
 ###################################################
 # For CUDA library 
 ###################################################
 CUDA_ADD_LIBRARY(LDPC_CU 
   ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu
   )
-
+CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU)
 cuda_add_executable(ldpctest
-=======
-add_executable(ldpctest  
-  ${PHY_NR_CODINGIF}
->>>>>>> origin/develop
   ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
   )
-<<<<<<< HEAD
 
 target_link_libraries(ldpctest -ldl
   -Wl,--start-group 
   LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB 
   -Wl,--end-group
-=======
+  m pthread ${ATLAS_LIBRARIES} dl
+  )
+
+# add_executable(ldpctest  
+  # ${PHY_NR_CODINGIF}
+  # ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
+  # ${T_SOURCE}
+  # ${SHLIB_LOADER_SOURCES}
+  # )
 add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) 
 
 target_link_libraries(ldpctest
   -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
->>>>>>> origin/develop
   m pthread ${ATLAS_LIBRARIES} dl
   )
-#add_executable(ldpctest  
-#  ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c
-#  ${T_SOURCE}
-#  ${SHLIB_LOADER_SOURCES}
-#  )
-#target_link_libraries(ldpctest
-#  -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group
-#  m pthread ${ATLAS_LIBRARIES} dl
-#  )
 
 add_executable(nr_dlschsim  
   ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c 
@@ -2900,6 +2954,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
   
   add_executable(${myExe}
     ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
+    ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
     ${OPENAIR_DIR}/common/utils/backtrace.c
     ${OPENAIR_DIR}/common/utils/system.c
     ${XFORMS_SOURCE}
@@ -2990,7 +3045,7 @@ if (${T_TRACER})
         PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
         L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
         CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB
-        ldpc_orig ldpc_optim ldpc_optim8seg ldpc)
+        ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT)
     if (TARGET ${i})
       add_dependencies(${i} generate_T)
     endif()
@@ -3033,7 +3088,7 @@ function(make_driver name dir)
   endforeach()
   CONFIGURE_FILE(${OPENAIR_CMAKE}/tools/Kbuild.cmake ${OPENAIR_BIN_DIR}/${name}/Kbuild)
   add_custom_command(OUTPUT ${name}.ko
-    COMMAND $(MAKE) -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name}
+    COMMAND make -C ${module_build_path} M=${OPENAIR_BIN_DIR}/${name}
     WORKING_DIRECTORY ${OPENAIR_BIN_DIR}/${name}
     COMMENT "building ${module}.ko"
     VERBATIM
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index b3954db1fd2..882670727b7 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1104,9 +1104,8 @@
                   -n100 -R217 -a80 -s5
                   -n100 -R217 -a110 -s5 -b100
                   -n100 -e27 -s30 
-                  -n100 -e16 -s10 
-      </main_exec_args>
-      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 </tags>
+                  -n100 -e16 -s10</main_exec_args>
+      <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10</tags>
       <search_expr_true>PDSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1177,21 +1176,38 @@
 
     <testCase id="015109">
       <class>execution</class>
-      <desc>nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB),
-                                    (Test2: Format 1 ACK miss 106 PRB),
-				                    (Test3: Format 1 ACK miss 273 PRB),
-			                        (Test4: Format 1 NACKtoACK 106 PRB)</desc>
+      <desc>nr_pucchsim Test cases. (Test1: Format 0 1-bit ACK miss 106 PRB),
+                                    (Test2: Format 0 2-bit ACK miss 106 PRB),
+                                    (Test3: Format 0 2-bit ACK miss, 1-bit SR 106 PRB),
+				    (Test4: Format 2 3-bit 106 PRB),
+                                    (Test5: Format 2 4-bit 106 PRB),
+                                    (Test6: Format 2 5-bit 106 PRB),
+                                    (Test7: Format 2 6-bit 106 PRB),
+                                    (Test8: Format 2 7-bit 106 PRB),
+                                    (Test9: Format 2 8-bit 106 PRB),
+                                    (Test10: Format 2 9-bit 106 PRB),
+                                    (Test11: Format 2 10-bit 106 PRB),
+                                    (Test12: Format 2 11-bit 106 PRB)</desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
       <compile_prog_args> --phy_simulators  -c </compile_prog_args>
       <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
       <pre_exec_args></pre_exec_args>
       <main_exec> $OPENAIR_DIR/targets/bin/nr_pucchsim.Rel15</main_exec>
-      <main_exec_args>-R 106 -i 1 -P 0 -b 1 -s3 -n100
-	                  -R 106 -i 14 -P 1 -b 1 -s-6 -n100
-                      -R 273 -i 14 -P 1 -b 1 -s-6 -n100
-                      -R 106 -i 14 -P 1 -b 1 -s-6 -T 0.001 -n1000</main_exec_args>
-      <tags>nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4</tags>
+      <main_exec_args>-R 106 -i 1 -P 0 -b 1 -s-2 -n1000
+                      -R 106 -i 1 -P 0 -b 2 -s-2 -n1000
+		      -R 106 -i 1 -P 0 -b 2 -s-2 -c -n1000
+                      -R 106 -i 1 -P 2 -b 3 -s0 -n1000
+		      -R 106 -i 1 -P 2 -b 4 -s0 -n1000
+		      -R 106 -i 1 -P 2 -b 5 -s1 -n1000
+		      -R 106 -i 1 -P 2 -b 6 -s2 -n1000
+		      -R 106 -i 1 -P 2 -b 7 -s3 -n1000
+		      -R 106 -i 1 -P 2 -b 8 -s4 -n1000
+		      -R 106 -i 1 -P 2 -b 9 -s5 -n1000
+		      -R 106 -i 1 -P 2 -b 10 -s6 -n1000
+		      -R 106 -i 1 -P 2 -b 11 -s6 -n1000
+                      </main_exec_args>
+      <tags>nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4 nr_pucchsim.test5 nr_pucchsim.test6 nr_pucchsim.test7 nr_pucchsim.test8 nr_pucchsim.test9 nr_pucchsim.test10 nr_pucchsim.test11 nr_pucchsim.test12 </tags>
       <search_expr_true>PUCCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
       <nruns>3</nruns>
@@ -1248,11 +1264,11 @@
       <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
       <pre_exec_args></pre_exec_args>
       <main_exec> $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15</main_exec>
-      <main_exec_args>-n100 -m9 -r106 -s0
+      <main_exec_args>-n100 -m9 -r106 -s5
                       -n100 -m16 -s10
                       -n100 -m28 -s20
-                      -n100 -m9 -R217 -r217 -s0
-                      -n100 -m9 -R273 -r273 -s0</main_exec_args>
+                      -n100 -m9 -R217 -r217 -s5
+                      -n100 -m9 -R273 -r273 -s5</main_exec_args>
       <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5</tags>
       <search_expr_true>PUSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 78769ed8d43..9a5d5f370c4 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -408,6 +408,10 @@ function main() {
             SKIP_SHARED_LIB_FLAG="True"
             echo_info "Skipping build of shared libraries, rfsimulator, basicsimulator and transport protocol libraries"
             shift;;
+    --ninja)
+        CMAKE_CMD="$CMAKE_CMD -GNinja"
+	MAKE_CMD=ninja
+	shift;;
         -h | --help)
             print_help
             exit 1;;
@@ -697,12 +701,7 @@ function main() {
   if [ "$SIMUS_PHY" = "1" ] ; then
     echo_info "Compiling physical unitary tests simulators"
     # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
-<<<<<<< HEAD
-#simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim"
-simlist="ldpctest"
-=======
     simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
->>>>>>> origin/develop
     for f in $simlist ; do
       compilations \
         phy_simulators $f \
diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt
index c1a0bb419b7..308c71be4c2 100644
--- a/cmake_targets/nas_sim_tools/CMakeLists.txt
+++ b/cmake_targets/nas_sim_tools/CMakeLists.txt
@@ -14,6 +14,7 @@ set(CMAKE_C_FLAGS
 
 set(OPENAIR_DIR     $ENV{OPENAIR_DIR})
 set(OPENAIR3_DIR    $ENV{OPENAIR_DIR}/openair3)
+include_directories (${OPENAIR_DIR}/openair2/COMMON)
 
 set(CONF2UEDATA_LIB_SRC
     ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
diff --git a/cmake_targets/phy_simulators/CMakeLists.txt b/cmake_targets/phy_simulators/CMakeLists.txt
index b43f7dd3897..5f2d34883ee 100644
--- a/cmake_targets/phy_simulators/CMakeLists.txt
+++ b/cmake_targets/phy_simulators/CMakeLists.txt
@@ -1,13 +1,19 @@
 cmake_minimum_required(VERSION 2.8)
-set(PACKAGE_NAME "unitary_tests_simulators")
-set(PHYSIM True)
-set(RF_BOARD None)
-set(XFORMS True)
-set(ENABLE_ITTI True)
-set(DEBUG_PHY False)
-set(MU_RECIEVER False)
-set(NAS_UE False)
-set(MESSAGE_CHART_GENERATOR False)
-set(RRC_ASN1_VERSION "Rel15")
-set(T_TRACER True)
-include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
\ No newline at end of file
+set ( CMAKE_BUILD_TYPE  )
+set ( CFLAGS_PROCESSOR_USER "" )
+set ( UE_EXPANSION False )
+set ( PRE_SCD_THREAD False )
+set ( UESIM_EXPANSION False )
+set ( ENABLE_VCD_FIFO False )
+set ( RF_BOARD "OAI_USRP")
+set ( TRANSP_PRO "None")
+set ( PACKAGE_NAME "")
+set ( DEADLINE_SCHEDULER "False" )
+set ( CPU_AFFINITY "False" )
+set ( T_TRACER True )
+set ( UE_AUTOTEST_TRACE False )
+set ( UE_DEBUG_TRACE False )
+set ( UE_TIMING_TRACE False )
+set ( USRP_REC_PLAY False )
+set ( SKIP_SHARED_LIB_FLAG False )
+include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 818b1fd79c7..20bc5dc2b9d 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -183,11 +183,15 @@ compilations() {
     else
         COV_SCAN_PREFIX=""
     fi
+    if [ "$MAKE_CMD" != "" ]; then
+       $MAKE_CMD $2
+    else 
     if [ "$VERBOSE_COMPILE" == "1" ]; then
        $COV_SCAN_PREFIX make -j`nproc` $2 VERBOSE=$VERBOSE_COMPILE
     else
        $COV_SCAN_PREFIX make -j`nproc` $2
     fi
+    fi
 
   } > $dlog/$2.$REL.txt 2>&1
   set -e
@@ -217,7 +221,7 @@ install_protobuf_from_source(){
     #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
     #cd protobuf-2.6.1/
     rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
-    wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
+    wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
     tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner
     cd protobuf-3.3.0/
     ./configure
@@ -353,8 +357,8 @@ install_bladerf_driver_from_source(){
     $SUDO ldconfig
     echo "Downloading FPGA and firmware images"
     cd /tmp/bladeRF
-    wget https://www.nuand.com/fx3/bladeRF_fw_latest.img
-    wget https://www.nuand.com/fpga/hostedx40-latest.rbf
+    wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img
+    wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf
     sudo mkdir -p /usr/share/Nuand/bladeRF
     sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img
     sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf
@@ -567,7 +571,7 @@ check_install_additional_tools (){
     echo_info "Installing Netinterfaces package. The logfile for installation is in $log_netiface"
     (
     $SUDO rm -fr /tmp/netifaces-0.10.4.tar.gz /tmp/netifaces
-    wget -P /tmp  https://pypi.python.org/packages/18/fa/dd13d4910aea339c0bb87d2b3838d8fd923c11869b1f6e741dbd0ff3bc00/netifaces-0.10.4.tar.gz
+    wget --tries=3 --retry-connrefused -P /tmp  https://pypi.python.org/packages/18/fa/dd13d4910aea339c0bb87d2b3838d8fd923c11869b1f6e741dbd0ff3bc00/netifaces-0.10.4.tar.gz
     tar -xzvf /tmp/netifaces-0.10.4.tar.gz -C /tmp
     cd /tmp/netifaces-0.10.4
     $SUDO python setup.py install
@@ -619,6 +623,7 @@ check_install_oai_software() {
 	build-essential \
 	cmake \
 	cmake-curses-gui  \
+        ninja-build \
 	doxygen \
 	doxygen-gui \
 	texlive-latex-base \
diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c
index 0043eb32380..79db7f1c0eb 100644
--- a/common/utils/LOG/vcd_signal_dumper.c
+++ b/common/utils/LOG/vcd_signal_dumper.c
@@ -248,7 +248,8 @@ const char* eurecomVariablesNames[] = {
   "slot_number_TX1_gNB",
   "slot_number_RX0_gNB",
   "slot_number_RX1_gNB",
-  "ru_tx_ofdm_mask"
+  "ru_tx_ofdm_mask",
+  "usrp_send_return"
 };
 
 const char* eurecomFunctionsNames[] = {
@@ -282,6 +283,8 @@ const char* eurecomFunctionsNames[] = {
   "lock_mutex_ru",
   "lock_mutex_ru1",
   "lock_mutex_ru2",
+  /* uhd signals */
+  "trx_write_thread",
   /* simulation signals */
   "do_DL_sig",
   "do_UL_sig",
diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h
index 20588bb8286..88655977bba 100644
--- a/common/utils/LOG/vcd_signal_dumper.h
+++ b/common/utils/LOG/vcd_signal_dumper.h
@@ -226,6 +226,7 @@ typedef enum {
   VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,
   VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,
   VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK,
+  VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN,
 
 
   VCD_SIGNAL_DUMPER_VARIABLES_END
@@ -262,6 +263,8 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU,
   VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU1,
   VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU2,
+  /* uhd signals */
+  VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD,
   /* SIMULATION signals */ 
   VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_DL_SIGNAL,
   VCD_SIGNAL_DUMPER_FUNCTIONS_SIM_DO_UL_SIGNAL,
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index 4cb4bf2bbaf..2221dbbcac9 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -73,10 +73,10 @@ typedef struct {
 } T_cache_t;
 
 /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS (248)
+#define VCD_NUM_FUNCTIONS (249)
 
 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_VARIABLES (186)
+#define VCD_NUM_VARIABLES (187)
 
 /* first VCD function (to be kept up to date! see in T_messages.txt) */
 #define VCD_FIRST_FUNCTION    ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index f8b746669c8..38385188346 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -2138,6 +2138,11 @@ ID = VCD_VARIABLE_RU_TX_OFDM_MASK
     GROUP = ALL:VCD:ENB:VCD_VARIABLE
     FORMAT = ulong,value
     VCD_NAME = ru_tx_ofdm_mask
+ID = VCD_VARIABLE_USRP_SEND_RETURN
+    DESC = VCD variable USRP_SEND_RETURN
+    GROUP = ALL:VCD:ENB:VCD_VARIABLE
+    FORMAT = ulong,value
+    VCD_NAME = usrp_send_return
 
 #functions
 
@@ -2286,6 +2291,11 @@ ID = VCD_FUNCTION_LOCK_MUTEX_RU2
     GROUP = ALL:VCD:UE:VCD_FUNCTION
     FORMAT = int,value
     VCD_NAME = lock_mutex_ru2
+ID = VCD_FUNCTION_TRX_WRITE_THREAD
+    DESC = VCD function TRX_WRITE_THREAD
+    GROUP = ALL:VCD:ENB:VCD_FUNCTION
+    FORMAT = int,value
+    VCD_NAME = trx_write_thread
 ID = VCD_FUNCTION_SIM_DO_DL_SIGNAL
     DESC = VCD function SIM_DO_DL_SIGNAL
     GROUP = ALL:VCD:ENB:VCD_FUNCTION
diff --git a/common/utils/T/tracer/config.h b/common/utils/T/tracer/config.h
index 07290c71a35..765b1261334 100644
--- a/common/utils/T/tracer/config.h
+++ b/common/utils/T/tracer/config.h
@@ -1,5 +1,5 @@
-#ifndef _CONFIG_H_
-#define _CONFIG_H_
+#ifndef __COMMON_UTILS_T_TRACER_CONFIG__H__
+#define __COMMON_UTILS_T_TRACER_CONFIG__H__
 
 void clear_remote_config(void);
 void append_received_config_chunk(char *buf, int length);
@@ -7,4 +7,4 @@ void load_config_file(char *filename);
 void verify_config(void);
 void get_local_config(char **txt, int *len);
 
-#endif /* _CONFIG_H_ */
+#endif /* __COMMON_UTILS_T_TRACER_CONFIG__H__ */
diff --git a/common/utils/T/tracer/hacks/time_meas.c b/common/utils/T/tracer/hacks/time_meas.c
index 6bd29503011..408189cd80c 100644
--- a/common/utils/T/tracer/hacks/time_meas.c
+++ b/common/utils/T/tracer/hacks/time_meas.c
@@ -13,7 +13,8 @@ void usage(void)
 "options:\n"
 "    -d <database file>        this option is mandatory\n"
 "    -ip <host>                connect to given IP address (default %s)\n"
-"    -p <port>                 connect to given port (default %d)\n",
+"    -p <port>                 connect to given port (default %d)\n"
+"    -e <event>                event to trace (default VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER)\n",
   DEFAULT_REMOTE_IP,
   DEFAULT_REMOTE_PORT
   );
@@ -47,6 +48,7 @@ int main(int n, char **v)
   int ev_fun;
   int start_valid = 0;
   struct timespec start_time, stop_time, delta_time;
+  char *name = "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER";
 
   for (i = 1; i < n; i++) {
     if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
@@ -55,6 +57,7 @@ int main(int n, char **v)
     if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
     if (!strcmp(v[i], "-p"))
       { if (i > n-2) usage(); port = atoi(v[++i]); continue; }
+    if (!strcmp(v[i], "-e")) { if (i > n-2) usage(); name = v[++i]; continue; }
     usage();
   }
 
@@ -71,10 +74,9 @@ int main(int n, char **v)
   is_on = calloc(number_of_events, sizeof(int));
   if (is_on == NULL) abort();
 
-  on_off(database, "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER", is_on, 1);
+  on_off(database, name, is_on, 1);
 
-  ev_fun = event_id_from_name(database,
-      "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER");
+  ev_fun = event_id_from_name(database, name);
 
   socket = connect_to(ip, port);
 
diff --git a/common/utils/T/tracer/hacks/timeplot.c b/common/utils/T/tracer/hacks/timeplot.c
index 79905d16f99..a1ddb2a1c92 100644
--- a/common/utils/T/tracer/hacks/timeplot.c
+++ b/common/utils/T/tracer/hacks/timeplot.c
@@ -28,6 +28,7 @@ int bins[50];
 
 #define N 1000
 int data[N];
+long start = 100;
 
 void plot(void)
 {
@@ -45,7 +46,8 @@ void plot(void)
     if (data[i] < vmin) vmin = data[i];
     if (data[i] > vmax) vmax = data[i];
     vavg += data[i];
-    int ms2 = data[i]/binsize_ns;
+    int ms2 = (data[i] - start * 1000)/binsize_ns;
+    if (ms2 < 0) ms2 = 0;
     if (ms2 > 49) ms2 = 49;
     bins[ms2]++;
     if (bins[ms2] > max) max = bins[ms2];
@@ -55,7 +57,7 @@ void plot(void)
 
   GOTO(1,1);
   for (i = 0; i < 50; i++) {
-    double binend = (i+1) * binsize_ns / 1000.;
+    double binend = (i+1) * binsize_ns / 1000. + start;
     int k;
     int width = bins[i] * 70 / max;
     /* force at least width of 1 if some point is there */
@@ -68,11 +70,23 @@ void plot(void)
   printf("min %d ns    max %d ns    avg %ld ns\n", vmin, vmax, vavg);
 }
 
+void up(int x)
+{
+  start += 5;
+}
+
+void down(int x)
+{
+  start -= 5;
+}
+
 int main(void)
 {
   int i;
   int pos = 0;
   signal(SIGINT, sig);
+  signal(SIGUSR1, up);
+  signal(SIGUSR2, down);
   RESET();
   HIDE_CURSOR();
   while (!feof(stdin)) {
diff --git a/common/utils/T/tracer/packet-mac-lte.h b/common/utils/T/tracer/packet-mac-lte.h
index 1bc6df632b7..54e6d1a09bb 100644
--- a/common/utils/T/tracer/packet-mac-lte.h
+++ b/common/utils/T/tracer/packet-mac-lte.h
@@ -33,6 +33,9 @@
  * SUCH DAMAGE
  */
 
+#ifndef __COMMON_UTILS_T_TRACER_PACKET_MAC_LTE__H__
+#define __COMMON_UTILS_T_TRACER_PACKET_MAC_LTE__H__
+
 //#include "ws_symbol_export.h"
 
 /* radioType */
@@ -139,3 +142,4 @@
    continues until the end of the frame) */
 #define MAC_LTE_PAYLOAD_TAG 0x01
 
+#endif
diff --git a/common/utils/assertions.h b/common/utils/assertions.h
index 97f18662748..48d8df401ce 100644
--- a/common/utils/assertions.h
+++ b/common/utils/assertions.h
@@ -19,6 +19,9 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __COMMON_UTILS_ASSERTIONS__H__
+#define __COMMON_UTILS_ASSERTIONS__H__
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -30,9 +33,6 @@
 # include "backtrace.h"
 #endif
 
-#ifndef ASSERTIONS_H_
-#define ASSERTIONS_H_
-
 void output_log_mem(void);
 #define _Assert_Exit_                           \
     fprintf(stderr, "\nExiting execution\n");   \
@@ -83,4 +83,4 @@ do {                                                            \
     }                                                           \
 } while(0)
 
-#endif /* ASSERTIONS_H_ */
+#endif /* __COMMON_UTILS_ASSERTIONS__H__ */
diff --git a/common/utils/itti_analyzer/common/queue.h b/common/utils/itti_analyzer/common/queue.h
deleted file mode 100644
index 294d4851108..00000000000
--- a/common/utils/itti_analyzer/common/queue.h
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)queue.h	8.5 (Berkeley) 8/20/94
- */
-
-#ifndef	_SYS_QUEUE_H_
-#define	_SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * lists, simple queues, tail queues, and circular queues.
- *
- * A singly-linked list is headed by a single forward pointer. The
- * elements are singly linked for minimum space and pointer manipulation
- * overhead at the expense of O(n) removal for arbitrary elements. New
- * elements can be added to the list after an existing element or at the
- * head of the list.  Elements being removed from the head of the list
- * should use the explicit macro for this purpose for optimum
- * efficiency. A singly-linked list may only be traversed in the forward
- * direction.  Singly-linked lists are ideal for applications with large
- * datasets and few or no removals or for implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *                      SLIST   LIST    STAILQ  TAILQ   CIRCLEQ
- * _HEAD                +       +       +       +       +
- * _HEAD_INITIALIZER    +       +       +       +       +
- * _ENTRY               +       +       +       +       +
- * _INIT                +       +       +       +       +
- * _EMPTY               +       +       +       +       +
- * _FIRST               +       +       +       +       +
- * _NEXT                +       +       +       +       +
- * _PREV                -       -       -       +       +
- * _LAST                -       -       +       +       +
- * _FOREACH             +       +       +       +       +
- * _FOREACH_REVERSE     -       -       -       +       +
- * _INSERT_HEAD         +       +       +       +       +
- * _INSERT_BEFORE       -       +       -       +       +
- * _INSERT_AFTER        +       +       +       +       +
- * _INSERT_TAIL         -       -       +       +       +
- * _REMOVE_HEAD         +       -       +       -       -
- * _REMOVE              +       +       +       +       +
- */
-
-/*
- * List definitions.
- */
-#define	LIST_HEAD(name, type)						\
-struct name {								\
-	struct type *lh_first;	/* first element */			\
-}
-
-#define	LIST_HEAD_INITIALIZER(head)					\
-	{ NULL }
-
-#define	LIST_ENTRY(type)						\
-struct {								\
-	struct type *le_next;	/* next element */			\
-	struct type **le_prev;	/* address of previous next element */	\
-}
-
-/*
- * List functions.
- */
-#define	LIST_INIT(head) do {						\
-	(head)->lh_first = NULL;					\
-} while (/*CONSTCOND*/0)
-
-#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
-	if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)	\
-		(listelm)->field.le_next->field.le_prev =		\
-		    &(elm)->field.le_next;				\
-	(listelm)->field.le_next = (elm);				\
-	(elm)->field.le_prev = &(listelm)->field.le_next;		\
-} while (/*CONSTCOND*/0)
-
-#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
-	(elm)->field.le_prev = (listelm)->field.le_prev;		\
-	(elm)->field.le_next = (listelm);				\
-	*(listelm)->field.le_prev = (elm);				\
-	(listelm)->field.le_prev = &(elm)->field.le_next;		\
-} while (/*CONSTCOND*/0)
-
-#define	LIST_INSERT_HEAD(head, elm, field) do {				\
-	if (((elm)->field.le_next = (head)->lh_first) != NULL)		\
-		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-	(head)->lh_first = (elm);					\
-	(elm)->field.le_prev = &(head)->lh_first;			\
-} while (/*CONSTCOND*/0)
-
-#define	LIST_REMOVE(elm, field) do {					\
-	if ((elm)->field.le_next != NULL)				\
-		(elm)->field.le_next->field.le_prev = 			\
-		    (elm)->field.le_prev;				\
-	*(elm)->field.le_prev = (elm)->field.le_next;			\
-} while (/*CONSTCOND*/0)
-
-#define	LIST_FOREACH(var, head, field)					\
-	for ((var) = ((head)->lh_first);				\
-		(var);							\
-		(var) = ((var)->field.le_next))
-
-/*
- * List access methods.
- */
-#define	LIST_EMPTY(head)		((head)->lh_first == NULL)
-#define	LIST_FIRST(head)		((head)->lh_first)
-#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
-
-
-/*
- * Singly-linked List definitions.
- */
-#define	SLIST_HEAD(name, type)						\
-struct name {								\
-	struct type *slh_first;	/* first element */			\
-}
-
-#define	SLIST_HEAD_INITIALIZER(head)					\
-	{ NULL }
-
-#define	SLIST_ENTRY(type)						\
-struct {								\
-	struct type *sle_next;	/* next element */			\
-}
-
-/*
- * Singly-linked List functions.
- */
-#define	SLIST_INIT(head) do {						\
-	(head)->slh_first = NULL;					\
-} while (/*CONSTCOND*/0)
-
-#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
-	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
-	(slistelm)->field.sle_next = (elm);				\
-} while (/*CONSTCOND*/0)
-
-#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
-	(elm)->field.sle_next = (head)->slh_first;			\
-	(head)->slh_first = (elm);					\
-} while (/*CONSTCOND*/0)
-
-#define	SLIST_REMOVE_HEAD(head, field) do {				\
-	(head)->slh_first = (head)->slh_first->field.sle_next;		\
-} while (/*CONSTCOND*/0)
-
-#define	SLIST_REMOVE(head, elm, type, field) do {			\
-	if ((head)->slh_first == (elm)) {				\
-		SLIST_REMOVE_HEAD((head), field);			\
-	}								\
-	else {								\
-		struct type *curelm = (head)->slh_first;		\
-		while(curelm->field.sle_next != (elm))			\
-			curelm = curelm->field.sle_next;		\
-		curelm->field.sle_next =				\
-		    curelm->field.sle_next->field.sle_next;		\
-	}								\
-} while (/*CONSTCOND*/0)
-
-#define	SLIST_FOREACH(var, head, field)					\
-	for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-/*
- * Singly-linked List access methods.
- */
-#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
-#define	SLIST_FIRST(head)	((head)->slh_first)
-#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-
-
-/*
- * Singly-linked Tail queue declarations.
- */
-#define	STAILQ_HEAD(name, type)					\
-struct name {								\
-	struct type *stqh_first;	/* first element */			\
-	struct type **stqh_last;	/* addr of last next element */		\
-}
-
-#define	STAILQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).stqh_first }
-
-#define	STAILQ_ENTRY(type)						\
-struct {								\
-	struct type *stqe_next;	/* next element */			\
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define	STAILQ_INIT(head) do {						\
-	(head)->stqh_first = NULL;					\
-	(head)->stqh_last = &(head)->stqh_first;				\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
-	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
-		(head)->stqh_last = &(elm)->field.stqe_next;		\
-	(head)->stqh_first = (elm);					\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.stqe_next = NULL;					\
-	*(head)->stqh_last = (elm);					\
-	(head)->stqh_last = &(elm)->field.stqe_next;			\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
-		(head)->stqh_last = &(elm)->field.stqe_next;		\
-	(listelm)->field.stqe_next = (elm);				\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_REMOVE_HEAD(head, field) do {				\
-	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
-		(head)->stqh_last = &(head)->stqh_first;			\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_REMOVE(head, elm, type, field) do {			\
-	if ((head)->stqh_first == (elm)) {				\
-		STAILQ_REMOVE_HEAD((head), field);			\
-	} else {							\
-		struct type *curelm = (head)->stqh_first;		\
-		while (curelm->field.stqe_next != (elm))			\
-			curelm = curelm->field.stqe_next;		\
-		if ((curelm->field.stqe_next =				\
-			curelm->field.stqe_next->field.stqe_next) == NULL) \
-			    (head)->stqh_last = &(curelm)->field.stqe_next; \
-	}								\
-} while (/*CONSTCOND*/0)
-
-#define	STAILQ_FOREACH(var, head, field)				\
-	for ((var) = ((head)->stqh_first);				\
-		(var);							\
-		(var) = ((var)->field.stqe_next))
-
-#define	STAILQ_CONCAT(head1, head2) do {				\
-	if (!STAILQ_EMPTY((head2))) {					\
-		*(head1)->stqh_last = (head2)->stqh_first;		\
-		(head1)->stqh_last = (head2)->stqh_last;		\
-		STAILQ_INIT((head2));					\
-	}								\
-} while (/*CONSTCOND*/0)
-
-/*
- * Singly-linked Tail queue access methods.
- */
-#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
-#define	STAILQ_FIRST(head)	((head)->stqh_first)
-#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
-
-
-/*
- * Simple queue definitions.
- */
-#define	SIMPLEQ_HEAD(name, type)					\
-struct name {								\
-	struct type *sqh_first;	/* first element */			\
-	struct type **sqh_last;	/* addr of last next element */		\
-}
-
-#define	SIMPLEQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).sqh_first }
-
-#define	SIMPLEQ_ENTRY(type)						\
-struct {								\
-	struct type *sqe_next;	/* next element */			\
-}
-
-/*
- * Simple queue functions.
- */
-#define	SIMPLEQ_INIT(head) do {						\
-	(head)->sqh_first = NULL;					\
-	(head)->sqh_last = &(head)->sqh_first;				\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
-	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
-		(head)->sqh_last = &(elm)->field.sqe_next;		\
-	(head)->sqh_first = (elm);					\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.sqe_next = NULL;					\
-	*(head)->sqh_last = (elm);					\
-	(head)->sqh_last = &(elm)->field.sqe_next;			\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
-		(head)->sqh_last = &(elm)->field.sqe_next;		\
-	(listelm)->field.sqe_next = (elm);				\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
-	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
-		(head)->sqh_last = &(head)->sqh_first;			\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
-	if ((head)->sqh_first == (elm)) {				\
-		SIMPLEQ_REMOVE_HEAD((head), field);			\
-	} else {							\
-		struct type *curelm = (head)->sqh_first;		\
-		while (curelm->field.sqe_next != (elm))			\
-			curelm = curelm->field.sqe_next;		\
-		if ((curelm->field.sqe_next =				\
-			curelm->field.sqe_next->field.sqe_next) == NULL) \
-			    (head)->sqh_last = &(curelm)->field.sqe_next; \
-	}								\
-} while (/*CONSTCOND*/0)
-
-#define	SIMPLEQ_FOREACH(var, head, field)				\
-	for ((var) = ((head)->sqh_first);				\
-		(var);							\
-		(var) = ((var)->field.sqe_next))
-
-/*
- * Simple queue access methods.
- */
-#define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == NULL)
-#define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
-#define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define	_TAILQ_HEAD(name, type, qual)					\
-struct name {								\
-	qual type *tqh_first;		/* first element */		\
-	qual type *qual *tqh_last;	/* addr of last next element */	\
-}
-#define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)
-
-#define	TAILQ_HEAD_INITIALIZER(head)					\
-	{ NULL, &(head).tqh_first }
-
-#define	_TAILQ_ENTRY(type, qual)					\
-struct {								\
-	qual type *tqe_next;		/* next element */		\
-	qual type *qual *tqe_prev;	/* address of previous next element */\
-}
-#define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define	TAILQ_INIT(head) do {						\
-	(head)->tqh_first = NULL;					\
-	(head)->tqh_last = &(head)->tqh_first;				\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
-	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
-		(head)->tqh_first->field.tqe_prev =			\
-		    &(elm)->field.tqe_next;				\
-	else								\
-		(head)->tqh_last = &(elm)->field.tqe_next;		\
-	(head)->tqh_first = (elm);					\
-	(elm)->field.tqe_prev = &(head)->tqh_first;			\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.tqe_next = NULL;					\
-	(elm)->field.tqe_prev = (head)->tqh_last;			\
-	*(head)->tqh_last = (elm);					\
-	(head)->tqh_last = &(elm)->field.tqe_next;			\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-		(elm)->field.tqe_next->field.tqe_prev = 		\
-		    &(elm)->field.tqe_next;				\
-	else								\
-		(head)->tqh_last = &(elm)->field.tqe_next;		\
-	(listelm)->field.tqe_next = (elm);				\
-	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
-	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
-	(elm)->field.tqe_next = (listelm);				\
-	*(listelm)->field.tqe_prev = (elm);				\
-	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_REMOVE(head, elm, field) do {				\
-	if (((elm)->field.tqe_next) != NULL)				\
-		(elm)->field.tqe_next->field.tqe_prev = 		\
-		    (elm)->field.tqe_prev;				\
-	else								\
-		(head)->tqh_last = (elm)->field.tqe_prev;		\
-	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
-} while (/*CONSTCOND*/0)
-
-#define	TAILQ_FOREACH(var, head, field)					\
-	for ((var) = ((head)->tqh_first);				\
-		(var);							\
-		(var) = ((var)->field.tqe_next))
-
-#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
-	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));	\
-		(var);							\
-		(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
-
-#define	TAILQ_CONCAT(head1, head2, field) do {				\
-	if (!TAILQ_EMPTY(head2)) {					\
-		*(head1)->tqh_last = (head2)->tqh_first;		\
-		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
-		(head1)->tqh_last = (head2)->tqh_last;			\
-		TAILQ_INIT((head2));					\
-	}								\
-} while (/*CONSTCOND*/0)
-
-/*
- * Tail queue access methods.
- */
-#define	TAILQ_EMPTY(head)		((head)->tqh_first == NULL)
-#define	TAILQ_FIRST(head)		((head)->tqh_first)
-#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
-
-#define	TAILQ_LAST(head, headname) \
-	(*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define	TAILQ_PREV(elm, headname, field) \
-	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-
-/*
- * Circular queue definitions.
- */
-#define	CIRCLEQ_HEAD(name, type)					\
-struct name {								\
-	struct type *cqh_first;		/* first element */		\
-	struct type *cqh_last;		/* last element */		\
-}
-
-#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
-	{ (void *)&head, (void *)&head }
-
-#define	CIRCLEQ_ENTRY(type)						\
-struct {								\
-	struct type *cqe_next;		/* next element */		\
-	struct type *cqe_prev;		/* previous element */		\
-}
-
-/*
- * Circular queue functions.
- */
-#define	CIRCLEQ_INIT(head) do {						\
-	(head)->cqh_first = (void *)(head);				\
-	(head)->cqh_last = (void *)(head);				\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
-	(elm)->field.cqe_prev = (listelm);				\
-	if ((listelm)->field.cqe_next == (void *)(head))		\
-		(head)->cqh_last = (elm);				\
-	else								\
-		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
-	(listelm)->field.cqe_next = (elm);				\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
-	(elm)->field.cqe_next = (listelm);				\
-	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
-	if ((listelm)->field.cqe_prev == (void *)(head))		\
-		(head)->cqh_first = (elm);				\
-	else								\
-		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
-	(listelm)->field.cqe_prev = (elm);				\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
-	(elm)->field.cqe_next = (head)->cqh_first;			\
-	(elm)->field.cqe_prev = (void *)(head);				\
-	if ((head)->cqh_last == (void *)(head))				\
-		(head)->cqh_last = (elm);				\
-	else								\
-		(head)->cqh_first->field.cqe_prev = (elm);		\
-	(head)->cqh_first = (elm);					\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
-	(elm)->field.cqe_next = (void *)(head);				\
-	(elm)->field.cqe_prev = (head)->cqh_last;			\
-	if ((head)->cqh_first == (void *)(head))			\
-		(head)->cqh_first = (elm);				\
-	else								\
-		(head)->cqh_last->field.cqe_next = (elm);		\
-	(head)->cqh_last = (elm);					\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
-	if ((elm)->field.cqe_next == (void *)(head))			\
-		(head)->cqh_last = (elm)->field.cqe_prev;		\
-	else								\
-		(elm)->field.cqe_next->field.cqe_prev =			\
-		    (elm)->field.cqe_prev;				\
-	if ((elm)->field.cqe_prev == (void *)(head))			\
-		(head)->cqh_first = (elm)->field.cqe_next;		\
-	else								\
-		(elm)->field.cqe_prev->field.cqe_next =			\
-		    (elm)->field.cqe_next;				\
-} while (/*CONSTCOND*/0)
-
-#define	CIRCLEQ_FOREACH(var, head, field)				\
-	for ((var) = ((head)->cqh_first);				\
-		(var) != (const void *)(head);				\
-		(var) = ((var)->field.cqe_next))
-
-#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
-	for ((var) = ((head)->cqh_last);				\
-		(var) != (const void *)(head);				\
-		(var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define	CIRCLEQ_EMPTY(head)		((head)->cqh_first == (void *)(head))
-#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
-#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
-#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
-#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
-
-#define CIRCLEQ_LOOP_NEXT(head, elm, field)				\
-	(((elm)->field.cqe_next == (void *)(head))			\
-	    ? ((head)->cqh_first)					\
-	    : (elm->field.cqe_next))
-#define CIRCLEQ_LOOP_PREV(head, elm, field)				\
-	(((elm)->field.cqe_prev == (void *)(head))			\
-	    ? ((head)->cqh_last)					\
-	    : (elm->field.cqe_prev))
-
-#endif	/* sys/queue.h */
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index 979cf863436..5601c0fcbf8 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __COMMON_UTILS_NR_NR_COMMON__H__
+#define __COMMON_UTILS_NR_NR_COMMON__H__
+
 #include <stdint.h>
 #include "assertions.h"
 
@@ -63,3 +66,5 @@ void SLIV2SL(int SLIV,int *S,int *L);
 #define max(a,b) cmax(a,b)
 #define min(a,b) cmin(a,b)
 #endif
+
+#endif
diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp
index 89e19074bf9..3d4d356dcf6 100644
--- a/common/utils/ocp_itti/intertask_interface.cpp
+++ b/common/utils/ocp_itti/intertask_interface.cpp
@@ -1,12 +1,32 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
+
 #include <vector>
 #include <map>
 #include <sys/eventfd.h>
 
 
+extern "C" {
 #include <intertask_interface.h>
 #include <common/utils/system.h>
 
@@ -35,7 +55,6 @@ typedef struct task_list_s {
 int timer_expired(int fd);
 task_list_t tasks[TASK_MAX];
 
-extern "C" {
   void *pool_buffer_init (void) {
     return 0;
   }
@@ -86,6 +105,9 @@ extern "C" {
     temp->ittiMsgHeader.messageId = message_id;
     temp->ittiMsgHeader.originTaskId = origin_task_id;
     temp->ittiMsgHeader.ittiMsgSize = size;
+    temp->ittiMsgHeader.destinationTaskId=TASK_UNKNOWN;
+    temp->ittiMsgHeader.instance=0;
+    temp->ittiMsgHeader.lte_time={0};
     return temp;
     //return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size);
   }
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 52c733752de..0cd25ee2319 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -1,7 +1,26 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  Copyleft: OpenAirInterface software alliance and it's license
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
+
 #ifndef INTERTASK_INTERFACE_H_
 #define INTERTASK_INTERFACE_H_
 #include <stdint.h>
@@ -275,7 +294,7 @@ typedef struct {
 //TASK_DEF(TASK_RRC_ENB,  TASK_PRIORITY_MED,  200, NULL, NULL)
 //TASK_DEF(TASK_GTPV1_U,  TASK_PRIORITY_MED,  1000,NULL, NULL)
 //TASK_DEF(TASK_UDP,      TASK_PRIORITY_MED,  1000, NULL, NULL)
-
+void * rrc_enb_process_msg(void*);
 #define FOREACH_TASK(TASK_DEF) \
   TASK_DEF(TASK_UNKNOWN,  TASK_PRIORITY_MED, 50, NULL, NULL)  \
   TASK_DEF(TASK_TIMER,    TASK_PRIORITY_MED, 10, NULL, NULL)   \
diff --git a/common/utils/system.c b/common/utils/system.c
index 3a8fe7be3d8..1bd5c7d39bc 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -243,6 +243,8 @@ void configure_linux(void) {
 
   // Set CPU frequency to it's maximum
   if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
-	  LOG_W(HW,"Can't set cpu frequency\n");
-  
+	  LOG_E(HW,"Can't set cpu frequency\n");
+
+  mlockall(MCL_CURRENT | MCL_FUTURE);
+
 }
diff --git a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
index 89ced509a45..7a45b351f32 100644
--- a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
+++ b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h
@@ -32,6 +32,8 @@
  * \warning
  */
 
+#ifndef __TELNETSRV_CPUMEASUR_DEF__H__
+#define __TELNETSRV_CPUMEASUR_DEF__H__
 
 #define CPU_PHYENB_MEASURE \
 { \
@@ -97,3 +99,5 @@
   {"pdcp_ip",                &(pdcpvars->pdcp_ip),0},\
   {"ip_pdcp",                &(pdcpvars->ip_pdcp),0},\
 }
+
+#endif
diff --git a/common/utils/telnetsrv/telnetsrv_enb_measurements.c b/common/utils/telnetsrv/telnetsrv_enb_measurements.c
index 9c5c5b675bb..8830173e6d5 100644
--- a/common/utils/telnetsrv/telnetsrv_enb_measurements.c
+++ b/common/utils/telnetsrv/telnetsrv_enb_measurements.c
@@ -110,13 +110,13 @@ void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt) {
 
 
 void measurcmd_display_macstats_ue(telnet_printfunc_t prnt) {
-  UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list);
+  UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info);
 
-  for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
-    for (int i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
-      int CC_id = UE_list->ordered_CCids[i][UE_id];
+  for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
+    for (int i=0; i<UE_info->numactiveCCs[UE_id]; i++) {
+      int CC_id = UE_info->ordered_CCids[i][UE_id];
       prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR);
-      eNB_UE_STATS *macuestatptr = &(UE_list->eNB_UE_stats[CC_id][UE_id]);
+      eNB_UE_STATS *macuestatptr = &(UE_info->eNB_UE_stats[CC_id][UE_id]);
       telnet_ltemeasurdef_t  statsptr[]=LTEMAC_UEMEASURE;
       measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t));
     }
@@ -155,7 +155,7 @@ void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_lt
 
 void measurcmd_display_rlcstats(telnet_printfunc_t prnt) {
   protocol_ctxt_t      ctxt;
-  UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list);
+  UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info);
   telnet_ltemeasurdef_t  statsptr[]=LTE_RLCMEASURE;
   int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t );
   unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int));
@@ -165,9 +165,9 @@ void measurcmd_display_rlcstats(telnet_printfunc_t prnt) {
     statsptr[i].vptr = rlcstats + i;
   }
 
-  for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+  for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
 #define NB_eNB_INST 1
-    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_list->eNB_UE_stats[0][UE_id].crnti,
+    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_info->eNB_UE_stats[0][UE_id].crnti,
                                    eNB->frame,eNB->subframe,eNB_id);
     measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH);
     measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO,  DTCH-2);
diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
index 160111f15e8..c1aab51e23d 100644
--- a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
+++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
@@ -32,6 +32,8 @@
  * \warning
  */
 
+#ifndef __TELNETSRV_LTEMEASUR_DEF__H__
+#define __TELNETSRV_LTEMEASUR_DEF__H__
 
 #define LTEMAC_MEASURE \
 { \
@@ -125,3 +127,5 @@
   {"timer_poll_retrans_tout",         NULL, TELNET_VARTYPE_UINT, 0},\
   {"timer_status_prohibit_tout",      NULL, TELNET_VARTYPE_UINT, 0},\
 }
+
+#endif
diff --git a/common/utils/telnetsrv/telnetsrv_measurements.h b/common/utils/telnetsrv/telnetsrv_measurements.h
index 80276bc2d03..08136df0fda 100644
--- a/common/utils/telnetsrv/telnetsrv_measurements.h
+++ b/common/utils/telnetsrv/telnetsrv_measurements.h
@@ -31,6 +31,10 @@
  * \note
  * \warning
  */
+
+#ifndef __TELNETSRV_MEASUREMENTS__H__
+#define __TELNETSRV_MEASUREMENTS__H__
+
 #include <dlfcn.h>
 #include "telnetsrv.h"
 #include "openair1/PHY/defs_eNB.h"
@@ -97,3 +101,4 @@ extern uint64_t measurcmd_getstatvalue(telnet_ltemeasurdef_t *measur,telnet_prin
 extern void     measurcmd_display_measures(telnet_printfunc_t prnt, telnet_ltemeasurdef_t  *statsptr, int stats_size);
 
 #endif  /* TELNETSRV_MEASURCMD_MAIN */
+#endif
diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h
index e35b2a53ab4..0d574027fbf 100644
--- a/common/utils/telnetsrv/telnetsrv_phycmd.h
+++ b/common/utils/telnetsrv/telnetsrv_phycmd.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __TELNETSRV_PHYCMD__H__
+#define __TELNETSRV_PHYCMD__H__
+
 #ifdef TELNETSRV_PHYCMD_MAIN
 
 #include "common/utils/LOG/log.h"
@@ -61,3 +64,4 @@ extern void add_phy_cmds(void);
 
 /*-------------------------------------------------------------------------------------*/
 
+#endif
diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h
index 1a0a8d25dc4..f130606b6c3 100644
--- a/common/utils/telnetsrv/telnetsrv_proccmd.h
+++ b/common/utils/telnetsrv/telnetsrv_proccmd.h
@@ -30,6 +30,10 @@
  * \note
  * \warning
  */
+
+#ifndef __TELNETSRV_PROCCMD__H__
+#define __TELNETSRV_PROCCMD__H__
+
 #include <dlfcn.h>
 #include "telnetsrv.h"
 
@@ -79,3 +83,4 @@ telnetshell_cmddef_t proc_cmdarray[] = {
 extern void add_proccmd_cmds(void);
 #endif  /* TELNETSRV_PROCCMD_MAIN */
 
+#endif
diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c
index 8f6e2c239a2..0f5a3e0f69c 100644
--- a/common/utils/threadPool/measurement_display.c
+++ b/common/utils/threadPool/measurement_display.c
@@ -1,7 +1,26 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
+
 #include <common/utils/simple_executable.h>
 
 #include "thread-pool.h"
diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c
index dd3d16d717b..cbb2dbe3d91 100644
--- a/common/utils/threadPool/thread-pool.c
+++ b/common/utils/threadPool/thread-pool.c
@@ -1,8 +1,27 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* 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
 */
 
+
 #define _GNU_SOURCE
 #include <sched.h>
 #include <sys/types.h>
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index 9a2681a828e..0ed8715811e 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -1,8 +1,27 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
 
+
 #ifndef THREAD_POOL_H
 #define THREAD_POOL_H
 #include <stdbool.h>
@@ -217,11 +236,11 @@ static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
 
 static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
   notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
-
+  AssertFatal(t->traceFd, "Thread pool used while not initialized");
   if (t->measurePerf)
     msg->returnTime=rdtsc();
 
-  if (t->traceFd >= 0)
+  if (t->traceFd > 0)
     if(write(t->traceFd, msg, sizeof(*msg)));
 
   return msg;
@@ -229,7 +248,7 @@ static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_
 
 static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
   notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
-
+  AssertFatal(t->traceFd, "Thread pool used while not initialized");
   if (msg == NULL)
     return NULL;
 
diff --git a/doc/L2NFAPI.md b/doc/L2NFAPI.md
index 4dcaaef3bcf..137e4847e4b 100644
--- a/doc/L2NFAPI.md
+++ b/doc/L2NFAPI.md
@@ -14,19 +14,24 @@
 
 This simulator allows to test L2 and above Layers using the nFAPI interface.
 
-**This simulator is available starting the `v1.0.0` release on the `master` branch.**
-
-Currently the only validated deployment by CI and developers is *with S1 interface and eNB / UEs are on the same machine*.
-
-Others deployments will be supported later after bug fixes and validation in the CI process.
-
-1. [With S1 -- eNB and UE on same machine](L2NFAPI_S1.md)
+The UE executable is able to "simulate" multiple UEs in order to stimulate the scheduler in the eNB.
 
+**This simulator is available starting the `v1.0.0` release on the `master` branch.**
 
+Currently the Continuous Integration process is validating this simulator the following way:
 
+*  the LTE modem executable is run on one host (in our CI deployment it is a **Xenial Virtual Machine**)
+*  the UE(s) modem executable is run on another host (in our CI deployment it is also a **Xenial Virtual Machine**)
+*  We are testing:
+   *   in S1 mode (ie we are connected to a 3rd-party EPC)
+   *   in noS1 mode (no need for an EPC)
 
+Normally it should be fine to run both executables on the same host using the `loopback` interface to communicate. **But we are not guaranting it**
 
+1. [With S1 -- eNB and UE on 2 hosts](L2NFAPI_S1.md)
+2. [No S1 -- eNB and UE on 2 hosts](L2NFAPI_NOS1.md)
 
+----
 
 [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
 
diff --git a/doc/L2NFAPI_S1.md b/doc/L2NFAPI_S1.md
index b9156e93796..9fd6d518180 100644
--- a/doc/L2NFAPI_S1.md
+++ b/doc/L2NFAPI_S1.md
@@ -7,7 +7,7 @@
       </a>
     </td>
     <td style="border-collapse: collapse; border: none; vertical-align: center;">
-      <b><font size = "5">L2 nFAPI Simulator (with S1 / same machine deployment)</font></b>
+      <b><font size = "5">L2 nFAPI Simulator (with S1 / 2-host deployment)</font></b>
     </td>
   </tr>
 </table>
@@ -21,25 +21,24 @@
 5.   [Setup of the Configuration files](#5-setup-of-the-configuration-files)
      1.   [The eNB Configuration file](#51-the-enb-configuration-file)
      2.   [The UE Configuration file](#52-the-ue-configuration-file)
-6.   [Bring Up a second loopback interface](#6-bring-up-a-second-loopback-interface)
-7.   [Build the eNB](#7-build-the-enb)
-8.   [Build the UE](#8-build-the-ue)
-9.   [Initialize the NAS UE Layer](#9-initialize-the-nas-ue-layer)
-10.   [Start the eNB](#10-start-the-enb)
-11.   [Start the UE](#11-start-the-ue)
-12.   [Test with ping](#12-test-with-ping)
-13.   [Limitations](#13-limitations)
+6.   [Build OAI UE and eNodeB](#6-build-oai-ue-and-enodeb)
+7.   [Start EPC](#7-start-epc)
+8.   [Start the eNB](#8-start-the-enb)
+9.   [Start the UE](#9-start-the-ue)
+10.   [Test with ping](#10-test-with-ping)
+11.   [Limitations](#11-limitations)
 
 # 1. Environment #
 
-2 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
+3 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process.
 
 *  Machine A contains the EPC.
-*  Machine B contains the OAI eNB and the OAI UE(s)
+*  Machine B contains the OAI eNB executable (`lte-softmodem`)
+*  Machine C contains the OAI UE(s) executable (`lte-uesoftmodem`)
 
 Example of L2 nFAPI Simulator testing environment:
 
-<img src="../l2-nfapi-simulator/L2-sim-single-server-deployment.png" alt="" border=3>
+<img src="./images/L2-sim-S1-3-host-deployment.png" alt="" border=3>
 
 Note that the IP addresses are indicative and need to be adapted to your environment.
 
@@ -47,26 +46,35 @@ Note that the IP addresses are indicative and need to be adapted to your environ
 
 Create the environment for the EPC and register all **USIM** information into the **HSS** database.
 
-If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-cn)), build **HSS/MME/SPGW** and create config files.
+If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-epc-fed)), build **HSS/MME/SPGW** and create config files.
 
 # 3. Retrieve the OAI eNB-UE source code #
 
-The eNB and the UE executables will compiled into 2 separate folders on the same machine `B`.
+At the time of writing, the tag used in the `develop` branch to do this documentation was `2020.w16`.
+
+The tutorial should be valid for the `master` branch tags such as `v1.2.0` or `v1.2.1`. But you may face issues that could be fixed in newer `develop` tags.
+
+Please try to use the same commit ID on both eNB/UE hosts.
 
 ```bash
 $ ssh sudousername@machineB
-$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g/ enb_folder
-$ cd enb_folder
-$ git checkout -f v1.0.0
-$ cd ..
-$ cp -Rf enb_folder ue_folder
+git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git enb_folder
+cd enb_folder
+git checkout develop
+```
+
+```bash
+$ ssh sudousername@machineC
+git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ue_folder
+cd ue_folder
+git checkout develop
 ```
 
 # 4. Setup of the USIM information in UE folder #
 
 ```bash
-$ ssh sudousername@machineB
-$ cd ue_folder
+$ ssh sudousername@machineC
+cd ue_folder
 # Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor
 ```
 
@@ -126,19 +134,19 @@ You can repeat the operation for as many users you want to test with.
 
 ```bash
 $ ssh sudousername@machineB
-$ cd enb_folder
+cd enb_folder
 # Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor
 ```
 
-First verify the nFAPI interface setup on the 2nd loopback interface.
+First verify the nFAPI interface setup on the physical ethernet interface of machineB and put the proper IP addresses for both hosts.
 
 ```
 MACRLCs = (
         {
         num_cc = 1;
-        local_s_if_name  = "lo:";            // <-- HERE
-        remote_s_address = "127.0.0.1";      // <-- HERE
-        local_s_address  = "127.0.0.2";      // <-- HERE
+        local_s_if_name  = "ens3";             // <-- HERE
+        remote_s_address = "192.168.122.169";  // <-- HERE
+        local_s_address  = "192.168.122.31";   // <-- HERE
         local_s_portc    = 50001;
         remote_s_portc   = 50000;
         local_s_portd    = 50011;
@@ -171,7 +179,7 @@ Last, the S1 interface shall be properly set.
 
 ```
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR"; // replace with 192.168.10.20
+    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR"; // replace with 192.168.122.195
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -181,11 +189,11 @@ Last, the S1 interface shall be properly set.
     NETWORK_INTERFACES :
     {
         ENB_INTERFACE_NAME_FOR_S1_MME            = "ens3";            // replace with the proper interface name
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";  // replace with 192.168.122.31
         ENB_INTERFACE_NAME_FOR_S1U               = "ens3";            // replace with the proper interface name
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";  // replace with 192.168.122.31
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
-        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";  // replace with 192.168.10.10
+        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";  // replace with 192.168.122.31
         ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
 
     };
@@ -195,7 +203,7 @@ Last, the S1 interface shall be properly set.
 
 ```bash
 $ ssh sudousername@machineB
-$ cd ue_folder
+cd ue_folder
 # Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor
 ```
 
@@ -206,9 +214,9 @@ L1s = (
         {
         num_cc = 1;
         tr_n_preference = "nfapi";
-        local_n_if_name  = "lo";         // <- HERE
-        remote_n_address = "127.0.0.2";  // <- HERE
-        local_n_address  = "127.0.0.1";  // <- HERE
+        local_n_if_name  = "ens3";            // <- HERE
+        remote_n_address = "192.168.122.31";  // <- HERE
+        local_n_address  = "192.168.122.169"; // <- HERE
         local_n_portc    = 50000;
         remote_n_portc   = 50001;
         local_n_portd    = 50010;
@@ -217,20 +225,11 @@ L1s = (
 );
 ```
 
-# 6. Bring Up a second loopback interface #
-
-A second loopback interface is used to connect the eNB and the UEs.
-
-```bash
-$ ssh sudousername@machineB
-$ sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up
-```
-
-# 7. [Build OAI UE and eNodeB](BUILD.md) #
+# 6. Build OAI UE and eNodeB #
 
+See [Build documentation](./BUILD.md).
 
-
-# 8. Initialize the NAS UE Layer #
+# 7. Start EPC #
 
 Start the EPC on machine `A`.
 
@@ -239,61 +238,89 @@ $ ssh sudousername@machineA
 # Start the EPC
 ```
 
-# 9. Start the eNB #
+# 8. Start the eNB #
 
 In the first terminal (the one you used to build the eNB):
 
 ```bash
 $ ssh sudousername@machineB
-$ cd enb_folder/cmake_targets
-$ sudo -E ./ran_build/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1
+cd enb_folder/cmake_targets
+sudo -E ./ran_build/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1
 ```
 
 If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator.
 
 We do recommend the redirection in steady mode once your setup is correct.
 
-# 10. Start the UE #
+# 9. Start the UE #
 
 In the second terminal (the one you used to build the UE):
 
 ```bash
-$ ssh sudousername@machineB
-$ cd ue_folder/cmake_targets
-# Test 64 UEs, 64 threads in FDD mode
-$ sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 > ue.log 2>&1
-# Test 64 UEs, 64 threads in TDD mode
-$ sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 -T 1 > ue.log 2>&1
+$ ssh sudousername@machineC
+cd ue_folder/cmake_targets
+# Test 64 UEs, 1 thread in FDD mode
+sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
+# Test 64 UEs, 1 thread in TDD mode
+sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 -T 1 > ue.log 2>&1
 # The "-T 1" option means TDD config
 ```
 
 -   The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16).
--   The umber of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
+-   The number of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs.
+    * At the time of writing, it seems to be enough to run on a single thread.
+-   The `--nokrnmod 1` option makes use of the preferred and supported tunnel interface.
 -   How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment.
 
-# 11. Test with ping #
-
-In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB:
+For example, running with 4 UEs:
 
 ```bash
-$ ssh sudousername@machineA
-# Ping UE0 IP address based on the EPC pool used: in this example:
-$ ping -c 20 192.168.200.2
-# Ping UE1 IP address based on the EPC pool used: in this example:
-$ ping -c 20 192.168.200.4
+$ ssh sudousername@machineC
+cd ue_folder/cmake_targets
+sudo -E ./ran_build/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums_ue_thread 1 --nokrnmod 1 > ue.log 2>&1
+sleep 10
+ifconfig
+ens3      Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX
+          inet addr:192.168.122.169  Bcast:192.168.122.255  Mask:255.255.255.0
+....
+oaitun_ue1 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          inet addr:192.172.0.2  P-t-P:192.172.0.2  Mask:255.255.255.0
+....
+oaitun_ue2 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          inet addr:192.172.0.3  P-t-P:192.172.0.3  Mask:255.255.255.0
+....
+oaitun_ue3 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          inet addr:192.172.0.4  P-t-P:192.172.0.4  Mask:255.255.255.0
+....
+oaitun_ue4 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          inet addr:192.172.0.5  P-t-P:192.172.0.5  Mask:255.255.255.0
+....
+oaitun_uem1 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+          inet addr:10.0.2.2  P-t-P:10.0.2.2  Mask:255.255.255.0
+....
+....
 ```
 
-# 12. Limitations #
-
-Testing on the CI process is currently limited at time of writing. Improvements will be made soon.
-
+Having the 4 oaitun_ue tunnel interfaces up and with an allocated address means the connection with EPC went alright.
 
+# 10. Test with ping #
 
+In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB: Check with ifconfig
 
+```bash
+$ ssh sudousername@machineA
+# Ping UE1 IP address based on the EPC pool used: in this example:
+$ ping -c 20 192.172.0.2
+# Ping UE4 IP address based on the EPC pool used: in this example:
+$ ping -c 20 192.172.0.5
+```
 
+iperf operations can also be performed.
 
+# 11. Limitations #
 
 
+----
 
 [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
 
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index e03700e4f52..aa16c771ae2 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -62,9 +62,7 @@
 #include "PHY/phy_extern.h"
 
 
-#include "LAYER2/MAC/mac.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
 #include "common/utils/LOG/log_extern.h"
@@ -161,7 +159,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
     oai_subframe_ind(frame_rx, slot_rx);
     stop_meas(&nfapi_meas);
 
-    if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
+    /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
         gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
         gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
         gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
@@ -175,7 +173,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
             gNB->UL_INFO.cqi_ind.number_of_cqis,
             frame_rx, slot_rx,
             frame_tx, slot_tx);
-    }
+    }*/
   }
   // ****************************************
 
@@ -187,8 +185,8 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
     wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
   }
   */
-
   // Call the scheduler
+
   pthread_mutex_lock(&gNB->UL_INFO_mutex);
   gNB->UL_INFO.frame     = frame_rx;
   gNB->UL_INFO.slot      = slot_rx;
@@ -326,7 +324,7 @@ static void *gNB_L1_thread( void *param ) {
   gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
   //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
   char thread_name[100];
-
+  // set default return value
   // set default return value
   gNB_thread_rxtx_status = 0;
 
@@ -423,7 +421,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
 
   int waitret = 0, ret = 0, time_ns = 1000*1000;
   struct timespec now, abstime;
-
+  // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
   // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
   time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
@@ -445,27 +443,27 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
 
   if (waitret == ETIMEDOUT) {
-     LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
+    LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
 
-     AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
-     gNB->proc.RU_mask_tx = 0;
-     AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-     AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
-     proc->instance_cnt_RUs = 0;
-     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
-     AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
+    AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
+    gNB->proc.RU_mask_tx = 0;
+    AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
+    AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
+    proc->instance_cnt_RUs = 0;
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
+    AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
 
-     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
-     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
+
+    return(-1);
+  }
 
-     return(-1);
-  } 
- 
   for(int i=0; i<gNB->num_RU; i++)
   {
     ru      = gNB->RU_list[i];
     ru_proc = &ru->proc;
-    
+
 
     if (ru_proc->instance_cnt_gNBs == 0) {
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
@@ -486,10 +484,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
 
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
 
-    LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);  
+    LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
     // the thread can now be woken up
     AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0,
-               "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
+                "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
     AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret);
 
   }
@@ -507,7 +505,7 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
   AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
 
 
-  while(L1_proc_tx->instance_cnt == 0){
+  while(L1_proc_tx->instance_cnt == 0) {
     pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
   }
 
@@ -523,7 +521,7 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
  
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
- 
+  // the thread can now be woken up
   // the thread can now be woken up
   AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
   
@@ -543,11 +541,11 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
   int time_ns = 50000;
   
   AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
-  for (i=0;i<gNB->num_RU;i++) {
+  for (i=0; i<gNB->num_RU; i++) {
     if (ru == gNB->RU_list[i]) {
       if ((proc->RU_mask&(1<<i)) > 0)
-	LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
-	      gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
+        LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
+              gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
       proc->RU_mask |= (1<<i);
     }
   }
@@ -574,16 +572,16 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
   AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
 
   if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
-   AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
-   LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); 
-   return(-1);
+    AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
+    LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
+    return(-1);
   }
- 
+
   ++L1_proc->instance_cnt;
-  
-  // We have just received and processed the common part of a subframe, say n. 
-  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
+  // We have just received and processed the common part of a subframe, say n.
+  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
   // transmitted timestamp of the next TX slot (first).
+
   // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, 
   // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
   // and proc->slot_tx = proc->slot_rx+sf_ahead
@@ -603,7 +601,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
     exit_fun( "ERROR pthread_cond_signal" );
     return(-1);
   }
-  
+
   return(0);
 }
 /*
@@ -707,9 +705,9 @@ static void* gNB_thread_prach( void* param ) {
 extern void init_td_thread(PHY_VARS_gNB *);
 extern void init_te_thread(PHY_VARS_gNB *);
 
-static void* process_stats_thread(void* param) {
+static void *process_stats_thread(void *param) {
 
-  PHY_VARS_gNB *gNB  = (PHY_VARS_gNB*)param;
+  PHY_VARS_gNB *gNB  = (PHY_VARS_gNB *)param;
 
   reset_meas(&gNB->dlsch_encoding_stats);
   reset_meas(&gNB->dlsch_scrambling_stats);
@@ -736,9 +734,7 @@ void init_gNB_proc(int inst) {
   gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
 //  LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
   gNB = RC.gNB[inst];
-#ifndef OCP_FRAMEWORK
   LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
-#endif
   
   proc = &gNB->proc;
   L1_proc                        = &proc->L1_proc;
@@ -952,9 +948,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
       NR_POLAR_PBCH_PAYLOAD_BITS,
       NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
     LOG_I(PHY,"Initializing gNB %d single_thread_flag:%d\n",inst,gNB->single_thread_flag);
-#ifndef OCP_FRAMEWORK
     LOG_I(PHY,"Initializing gNB %d\n",inst);
-#endif
 
     LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst);
     AssertFatal((gNB->if_inst         = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
@@ -963,12 +957,12 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
     gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
     memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
     LOG_I(PHY,"Setting indication lists\n");
-    gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list   = gNB->rx_pdu_list;
-    gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
-    gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
+    gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list;
+    gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list;
+    /*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
     gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
     gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
-    gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
+    gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
     gNB->prach_energy_counter = 0;
   }
   
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index fe109884629..3ea026f6e62 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -1,41 +1,24 @@
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2014 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-    included in this distribution in the file called "COPYING". If not,
-    see <http://www.gnu.org/licenses/>.
-
-   Contact Information
-   OpenAirInterface Admin: openair_admin@eurecom.fr
-   OpenAirInterface Tech : openair_tech@eurecom.fr
-   OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
-
-*******************************************************************************/
-
-/*! \file lte-enb.c
- * \brief Top-level threads for eNodeB
- * \author R. Knopp, F. Kaltenberger, Navid Nikaein
- * \date 2012
- * \version 0.1
- * \company Eurecom
- * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
- * \note
- * \warning
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
  */
+
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -72,9 +55,7 @@
 #include "SCHED/sched_eNB.h"
 #include "SCHED_NR/sched_nr.h"
 
-#include "LAYER2/MAC/mac.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
 
@@ -93,7 +74,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 static int DEFBANDS[] = {7};
 static int DEFENBS[] = {0};
 static int DEFBFW[] = {0x00007fff};
- 
+
 //static int DEFNRBANDS[] = {7};
 //static int DEFGNBS[] = {0};
 
@@ -713,7 +694,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
 }
 
 
-void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { 
+void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
   RU_proc_t *proc = &ru->proc;
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
   nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
@@ -792,7 +773,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
       LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx,
 	    (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
-      AssertFatal(txs ==  siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen);
+      //AssertFatal(txs == 0,"trx write function error %d\n", txs);
   }
 }
 
@@ -884,7 +865,7 @@ void *ru_thread_prach( void *param ) {
                 0,0
           );
     }
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ 
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
     if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
   }
 
@@ -1111,16 +1092,16 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
       }
     } else if(N_RB == 106) {
       if (fp->threequarter_fs) {
-	cfg->sample_rate=46.08e6;
-	cfg->samples_per_frame = 460800;
-	cfg->tx_bw = 40e6;
-	cfg->rx_bw = 40e6;
+        cfg->sample_rate=46.08e6;
+        cfg->samples_per_frame = 460800;
+        cfg->tx_bw = 40e6;
+        cfg->rx_bw = 40e6;
       }
       else {
-	cfg->sample_rate=61.44e6;
-	cfg->samples_per_frame = 614400;
-	cfg->tx_bw = 40e6;
-	cfg->rx_bw = 40e6;
+        cfg->sample_rate=61.44e6;
+        cfg->samples_per_frame = 614400;
+        cfg->tx_bw = 40e6;
+        cfg->rx_bw = 40e6;
       }
     } else {
       AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
@@ -1242,7 +1223,7 @@ void *ru_stats_thread(void *param) {
 
       if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
 
-      if (ru->feptx_ofdm){
+      if (ru->feptx_ofdm) {
         print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
         print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL);
         print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
@@ -1251,7 +1232,7 @@ void *ru_stats_thread(void *param) {
 
       if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
 
-        print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
+      print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
       if (ru->fh_north_out) {
         print_meas(&ru->compression,"compression",NULL,NULL);
         print_meas(&ru->transport,"transport",NULL,NULL);
@@ -1382,7 +1363,7 @@ void *ru_thread_tx( void *param ) {
           L1_proc->instance_cnt_RUs = 0;
           VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
           AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
-                       "ERROR pthread_cond_signal for gNB_L1_thread\n");
+                      "ERROR pthread_cond_signal for gNB_L1_thread\n");
         } //else AssertFatal(1==0,"gNB TX thread is not ready\n");
         ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
         AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
@@ -1482,6 +1463,16 @@ void *ru_thread( void *param ) {
 
     // if this is a slave RRU, try to synchronize on the DL frequency
     if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
+
+    // start trx write thread
+    if (ru->start_write_thread){
+      if(ru->start_write_thread(ru) != 0){
+        LOG_E(HW,"Could not start tx write thread\n");
+      }
+      else{
+        LOG_I(PHY,"tx write thread ready\n");
+      }
+    }
   }
 
   pthread_mutex_lock(&proc->mutex_FH1);
@@ -1691,14 +1682,15 @@ int stop_rf(RU_t *ru) {
   return 0;
 }
 
+int start_write_thread(RU_t *ru) {
+  return(ru->rfdevice.trx_write_init(&ru->rfdevice));
+}
 
 void init_RU_proc(RU_t *ru) {
   int i=0;
   RU_proc_t *proc;
   char name[100];
-#ifndef OCP_FRAMEWORK
   LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
-#endif
   proc = &ru->proc;
   memset((void *)proc,0,sizeof(RU_proc_t));
   proc->ru = ru;
@@ -2086,6 +2078,7 @@ void set_function_spec_param(RU_t *ru) {
       ru->fh_south_out           = tx_rf;                               // local synchronous RF TX
       ru->start_rf               = start_rf;                            // need to start the local RF interface
       ru->stop_rf                = stop_rf;
+      ru->start_write_thread     = start_write_thread;                  // starting RF TX in different thread
       printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf);
       /*
           if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
@@ -2111,6 +2104,7 @@ void set_function_spec_param(RU_t *ru) {
       ru->fh_south_asynch_in     = NULL;                // no asynchronous UL
       ru->start_rf               = NULL;                // no local RF
       ru->stop_rf                = NULL;
+      ru->start_write_thread     = NULL;
       ru->nr_start_if            = nr_start_if;         // need to start if interface for IF5
       ru->ifdevice.host_type     = RAU_HOST;
       ru->ifdevice.eth_params    = &ru->eth_params;
@@ -2137,6 +2131,7 @@ void set_function_spec_param(RU_t *ru) {
       ru->fh_north_asynch_in     = NULL;
       ru->start_rf               = NULL;                // no local RF
       ru->stop_rf                = NULL;
+      ru->start_write_thread     = NULL;
       ru->nr_start_if            = nr_start_if;         // need to start if interface for IF4p5
       ru->ifdevice.host_type     = RAU_HOST;
       ru->ifdevice.eth_params    = &ru->eth_params;
@@ -2166,7 +2161,6 @@ void init_NR_RU(char *rf_config_file)
   PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL;
   NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL;
   int i;
-  int CC_id;
   // create status mask
   RC.ru_mask = 0;
   pthread_mutex_init(&RC.ru_mutex,NULL);
@@ -2295,9 +2289,27 @@ void RCconfig_RU(void)
         }
       }
       else {
-	RC.ru[j]->openair0_cfg.clock_source = unset;
+        RC.ru[j]->openair0_cfg.clock_source = unset;
       }
 
+      if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) {
+        if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = internal;
+          LOG_D(PHY, "RU time source set as internal\n");
+        } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = external;
+          LOG_D(PHY, "RU time source set as external\n");
+        } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = gpsdo;
+          LOG_D(PHY, "RU time source set as gpsdo\n");
+        } else {
+          LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
+        }
+      }
+      else {
+	RC.ru[j]->openair0_cfg.time_source = unset;
+      }
+      
       if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
         if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
           RC.ru[j]->if_south                        = LOCAL_RF;
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 04c515e556b..f473d0161b6 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -49,8 +49,6 @@
 #include "PHY/phy_vars.h"
 #include "SCHED/sched_common_vars.h"
 #include "LAYER2/MAC/mac_vars.h"
-#include "LAYER2/MAC/mac.h"
-#include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_vars.h"
 #include "PHY_INTERFACE/phy_interface_vars.h"
 #include "gnb_config.h"
@@ -108,7 +106,7 @@ static int wait_for_sync = 0;
 unsigned int mmapped_dma=0;
 int single_thread_flag=1;
 
-static int8_t threequarter_fs=0;
+int8_t threequarter_fs=0;
 
 uint64_t downlink_frequency[MAX_NUM_CCs][4];
 int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
@@ -171,6 +169,10 @@ uint32_t target_ul_mcs = 20;
 uint32_t timing_advance = 0;
 uint64_t num_missed_slots=0; // counter for the number of missed slots
 
+int split73=0;
+void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
 
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
@@ -706,7 +708,6 @@ int stop_L1L2(module_id_t gnb_id) {
  */
 int restart_L1L2(module_id_t gnb_id) {
   RU_t *ru = RC.ru[gnb_id];
-  int cc_id;
   MessageDef *msg_p = NULL;
   LOG_W(GNB_APP, "restarting nr-softmodem\n");
   /* block threads */
@@ -721,13 +722,9 @@ int restart_L1L2(module_id_t gnb_id) {
   memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
   set_function_spec_param(RC.ru[gnb_id]);
   LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
-
-  if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
-    LOG_E(RRC, "Create task for RRC eNB failed\n");
-    return -1;
-  } else {
-    LOG_I(RRC, "Re-created task for RRC gNB successfully\n");
-  }
+  // No more rrc thread, as many race conditions are hidden behind
+  rrc_enb_init();
+  itti_mark_task_ready(TASK_RRC_ENB);
 
   if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
     LOG_E(PDCP, "Create task for L2L1 failed\n");
@@ -770,23 +767,23 @@ static  void wait_nfapi_init(char *thread_name) {
 
 void init_pdcp(void) {
   //if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
-    pdcp_layer_init();
-    uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
-                             (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
+  pdcp_layer_init();
+  uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
+                           (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
 
-    if (IS_SOFTMODEM_NOS1){
-    	printf("IS_SOFTMODEM_NOS1 option enabled \n");
-      pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT  ;
-    }
+  if (IS_SOFTMODEM_NOS1) {
+    printf("IS_SOFTMODEM_NOS1 option enabled \n");
+    pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT  ;
+  }
 
-    pdcp_module_init(pdcp_initmask);
+  pdcp_module_init(pdcp_initmask);
 
-    /*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
-      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
-    } else {*/
-      pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
-      pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
-    //}
+  /*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
+    pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
+  } else {*/
+  pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
+  pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
+  //}
   /*} else {
     pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
   }*/
@@ -840,7 +837,7 @@ int main( int argc, char **argv )
   MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
 
 
-init_opt();
+  init_opt();
 
 
 #ifdef PDCP_USE_NETLINK
@@ -857,7 +854,7 @@ if(!IS_SOFTMODEM_NOS1)
   LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
 
   if(IS_SOFTMODEM_NOS1)
-	  init_pdcp();
+    init_pdcp();
 
   if (RC.nb_nr_inst > 0)  {
     // don't create if node doesn't connect to RRC/S1/GTP
@@ -987,27 +984,27 @@ if(!IS_SOFTMODEM_NOS1)
   printf("oai_exit=%d\n",oai_exit);
 
   // stop threads
-/*#ifdef XFORMS
+  /*#ifdef XFORMS
 
-    printf("waiting for XFORMS thread\n");
+      printf("waiting for XFORMS thread\n");
 
-    if (do_forms==1) {
-      pthread_join(forms_thread,&status);
-      fl_hide_form(form_stats->stats_form);
-      fl_free_form(form_stats->stats_form);
+      if (do_forms==1) {
+        pthread_join(forms_thread,&status);
+        fl_hide_form(form_stats->stats_form);
+        fl_free_form(form_stats->stats_form);
 
-        fl_hide_form(form_stats_l2->stats_form);
-        fl_free_form(form_stats_l2->stats_form);
+          fl_hide_form(form_stats_l2->stats_form);
+          fl_free_form(form_stats_l2->stats_form);
 
-        for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
-    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      fl_hide_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
-      fl_free_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
-    }
-        }
-    }
+          for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
+      for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+        fl_hide_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
+        fl_free_form(form_enb[CC_id][UE_id]->phy_scope_gNB);
+      }
+          }
+      }
 
-#endif*/
+  #endif*/
   printf("stopping MODEM threads\n");
   // cleanup
   stop_gNB(NB_gNB_INST);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 131710ee020..dbee6f1e6fc 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -357,10 +357,11 @@ static void UE_synch(void *arg) {
 }
 
 void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
-  uint32_t nb_rb, start_rb;
-  uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx;
-  uint16_t n_rnti;
 
+  uint32_t rb_size, rb_start;
+  uint16_t rnti, l_prime_mask, n_rb0, n_rb1, pdu_bit_map;
+  uint8_t nr_of_symbols, start_symbol_index, mcs_index, mcs_table, nrOfLayers, harq_process_id, rv_index, dmrs_config_type;
+  uint8_t ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ptrs_time_density, ptrs_freq_density;
   nr_dcireq_t dcireq;
   nr_scheduled_response_t scheduled_response;
 
@@ -381,30 +382,53 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
     scheduled_response.frame = proc->frame_rx;
     scheduled_response.slot  = proc->nr_tti_rx;
     //--------------------------Temporary configuration-----------------------------//
-    n_rnti = 0x1234;
-    nb_rb = 50;
-    start_rb = 0;
-    nb_symb_sch = 12;
-    start_symbol = 2;
-    precod_nbr_layers = 1;
-    mcs = 9;
-    harq_pid = 0;
-    rvidx = 0;
+    rnti = 0x1234;
+    rb_size = 50;
+    rb_start = 0;
+    nr_of_symbols = 12;
+    start_symbol_index = 2;
+    nrOfLayers = 1;
+    mcs_index = 9;
+    mcs_table = 0;
+    harq_process_id = 0;
+    rv_index = 0;
+    l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
+    dmrs_config_type = 0;
+    ptrs_mcs1 = 2;
+    ptrs_mcs2 = 4;
+    ptrs_mcs3 = 10;
+    n_rb0 = 25;
+    n_rb1 = 75;
+    pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
+    ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
+    ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
     //------------------------------------------------------------------------------//
 
     scheduled_response.ul_config->slot = 8;
     scheduled_response.ul_config->number_pdus = 1;
     scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = mcs;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = rvidx;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
-    scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
+    scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+
+    if (1 << ptrs_time_density >= nr_of_symbols) {
+      scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+    }
 
     nr_ue_scheduled_response(&scheduled_response);
     
@@ -471,7 +495,6 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
     }
   }
 
-  
   // no UL for now
   /*
   if (UE->mac_enabled==1) {
@@ -521,7 +544,7 @@ void UE_processing(void *arg) {
   // then timing advance is processed and set to be applied in the next UL transmission */
   if (UE->mac_enabled == 1) {
 
-    if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot){
+    if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
       LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
 
       //if (nfapi_mode!=3){
@@ -591,7 +614,6 @@ void readFrame(PHY_VARS_NR_UE *UE,  openair0_timestamp *timestamp, bool toTrash)
 void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
 
     LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
-    void *dummy_tx[UE->frame_parms.nb_antennas_tx];
 
     *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
     for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
@@ -753,7 +775,7 @@ void *UE_thread(void *arg) {
 #ifdef OAI_ADRV9371_ZC706
     /*uint32_t total_gain_dB_prev = 0;
     if (total_gain_dB_prev != UE->rx_total_gain_dB) {
-		total_gain_dB_prev = UE->rx_total_gain_dB;
+        total_gain_dB_prev = UE->rx_total_gain_dB;
         openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB;
         UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]);
     }*/
@@ -837,7 +859,7 @@ void *UE_thread(void *arg) {
 
     if (  decoded_frame_rx != curMsg->proc.frame_rx &&
           ((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx )
-      LOG_D(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
+      LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
             decoded_frame_rx, curMsg->proc.frame_rx  );
 
     nbSlotProcessing++;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 53e407923fd..9b2b704833f 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -47,7 +47,6 @@
 #include "PHY/NR_REFSIG/nr_mod_table.h"
 
 #include "LAYER2/MAC/mac_vars.h"
-#include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_vars.h"
 #include "PHY_INTERFACE/phy_interface_vars.h"
 #include "openair1/SIMULATION/TOOLS/sim.h"
@@ -127,7 +126,6 @@ volatile int             start_eNB = 0;
 volatile int             start_UE = 0;
 volatile int             oai_exit = 0;
 
-static clock_source_t    clock_source = unset;
 int                      single_thread_flag=1;
 static double            snr_dB=20;
 
@@ -215,7 +213,7 @@ int emulate_rf = 0;
 
 tpool_t *Tpool;
 #ifdef UE_DLSCH_PARALLELISATION
-tpool_t *Tpool_dl;
+  tpool_t *Tpool_dl;
 #endif
 
 
@@ -311,8 +309,8 @@ static void *scope_thread(void *arg) {
 
   while (!oai_exit) {
     phy_scope_nrUE(form_nrue[0],
-                 PHY_vars_UE_g[0][0],
-                 0,0,1);
+                   PHY_vars_UE_g[0][0],
+                   0,0,1);
     usleep(100*1000);
   }
 
@@ -383,9 +381,9 @@ static void get_options(void) {
   int tddflag=0, nonbiotflag, vcdflag=0;
   char *loopfile=NULL;
   int dumpframe=0;
-
   //uint32_t noS1;
   //uint32_t nokrnmod;
+  //uint32_t nokrnmod;
   paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
   config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
 
@@ -529,12 +527,12 @@ void init_openair0(void) {
         else {
           openair0_cfg[card].sample_rate=122.88e6;
           openair0_cfg[card].samples_per_frame = 1228800;
-        } 
+        }
       } else {
         LOG_E(PHY,"Unsupported numerology!\n");
         exit(-1);
       }
-     }else if(frame_parms[0]->N_RB_DL == 273) {
+    } else if(frame_parms[0]->N_RB_DL == 273) {
       if (numerology==1) {
         if (frame_parms[0]->threequarter_fs) {
           AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
@@ -542,12 +540,12 @@ void init_openair0(void) {
         else {
           openair0_cfg[card].sample_rate=122.88e6;
           openair0_cfg[card].samples_per_frame = 1228800;
-        } 
+        }
       } else {
         LOG_E(PHY,"Unsupported numerology!\n");
         exit(-1);
       }
-     }else if(frame_parms[0]->N_RB_DL == 106) {
+    } else if(frame_parms[0]->N_RB_DL == 106) {
       if (numerology==0) {
         if (frame_parms[0]->threequarter_fs) {
           openair0_cfg[card].sample_rate=23.04e6;
@@ -556,15 +554,15 @@ void init_openair0(void) {
           openair0_cfg[card].sample_rate=30.72e6;
           openair0_cfg[card].samples_per_frame = 307200;
         }
-     } else if (numerology==1) {
+      } else if (numerology==1) {
         if (frame_parms[0]->threequarter_fs) {
-	  openair0_cfg[card].sample_rate=46.08e6;
-	  openair0_cfg[card].samples_per_frame = 460800;
+          openair0_cfg[card].sample_rate=46.08e6;
+          openair0_cfg[card].samples_per_frame = 460800;
 	}
 	else {
-	  openair0_cfg[card].sample_rate=61.44e6;
-	  openair0_cfg[card].samples_per_frame = 614400;
-	}
+          openair0_cfg[card].sample_rate=61.44e6;
+          openair0_cfg[card].samples_per_frame = 614400;
+        }
       } else if (numerology==2) {
         openair0_cfg[card].sample_rate=122.88e6;
         openair0_cfg[card].samples_per_frame = 1228800;
@@ -597,7 +595,8 @@ void init_openair0(void) {
            PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
     openair0_cfg[card].Mod_id = 0;
     openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
-    openair0_cfg[card].clock_source = clock_source;
+    openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
+    openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
     openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx);
     openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx);
 
@@ -639,7 +638,7 @@ void init_pdcp(void) {
     pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
 
   /*if (rlc_module_init() != 0) {
-	  LOG_I(RLC, "Problem at RLC initiation \n");
+    LOG_I(RLC, "Problem at RLC initiation \n");
   }
   pdcp_layer_init();
   nr_ip_over_LTE_DRB_preconfiguration();*/
@@ -649,6 +648,11 @@ void init_pdcp(void) {
   LOG_I(PDCP, "Before getting out from init_pdcp() \n");
 }
 
+// Stupid function addition because UE itti messages queues definition is common with eNB
+void *rrc_enb_process_msg(void *notUsed) {
+  return NULL;
+}
+
 
 int main( int argc, char **argv ) {
   //uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
@@ -676,12 +680,12 @@ int main( int argc, char **argv ) {
   set_taus_seed (0);
   tpool_t pool;
   Tpool = &pool;
-  char params[]="-1,-1"; 
+  char params[]="-1,-1";
   initTpool(params, Tpool, false);
 #ifdef UE_DLSCH_PARALLELISATION
   tpool_t pool_dl;
   Tpool_dl = &pool_dl;
-  char params_dl[]="-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1"; 
+  char params_dl[]="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
   initTpool(params_dl, Tpool_dl, false);
 #endif
   cpuf=get_cpu_freq_GHz();
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 7fad43e897c..ba293324e3b 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -59,7 +59,6 @@
 /*   optname                helpstr                 paramflags      XXXptr                                 defXXXval              type         numelt */
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define CMDLINE_PARAMS_DESC_UE {  \
-  {"clock-source",          CONFIG_HLP_EXCCLK,      0,              iptr:&clock_source,                    defintval:0,           TYPE_INT,    0}, \
   {"single-thread-disable", CONFIG_HLP_NOSNGLT,     PARAMFLAG_BOOL, iptr:&single_thread_flag,              defintval:1,           TYPE_INT,    0}, \
   {"nr-dlsch-demod-shift",  CONFIG_HLP_DLSHIFT,     0,              iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0,           TYPE_INT,    0}, \
   {"A" ,                    CONFIG_HLP_TADV,        0,              uptr:&timing_advance,                  defintval:0,           TYPE_UINT,   0}, \
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index f714fa2bd4b..04a58413b5a 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -81,8 +81,8 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
 }
 
 void get_common_options(uint32_t execmask) {
-  uint32_t online_log_messages;
-  uint32_t glog_level ;
+  uint32_t online_log_messages=0;
+  uint32_t glog_level=0 ;
   uint32_t start_telnetsrv = 0;
   uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
   uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
@@ -145,27 +145,27 @@ void get_common_options(uint32_t execmask) {
   if(worker_config != NULL)   set_worker_conf(worker_config);
 }
 void softmodem_printresources(int sig, telnet_printfunc_t pf) {
-   struct rusage usage;
-   struct timespec stop;
-
-   clock_gettime(CLOCK_BOOTTIME, &stop);
-
-   uint64_t elapse = (stop.tv_sec - start.tv_sec) ;   // in seconds
-
-
-   int st = getrusage(RUSAGE_SELF,&usage);
-   if (!st) {
-   	 pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
-     pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
-     pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
-     pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
-     pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
-     pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
-     pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
-     pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
-     pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
-     pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
-   } 
+  struct rusage usage;
+  struct timespec stop;
+
+  clock_gettime(CLOCK_BOOTTIME, &stop);
+
+  uint64_t elapse = (stop.tv_sec - start.tv_sec) ;   // in seconds
+
+
+  int st = getrusage(RUSAGE_SELF,&usage);
+  if (!st) {
+    pf("\nRun time: %lluh %llus\n",(unsigned long long)elapse/3600,(unsigned long long)(elapse - (elapse/3600)));
+    pf("\tTime executing user inst.: %lds %ldus\n",(long)usage.ru_utime.tv_sec,(long)usage.ru_utime.tv_usec);
+    pf("\tTime executing system inst.: %lds %ldus\n",(long)usage.ru_stime.tv_sec,(long)usage.ru_stime.tv_usec);
+    pf("\tMax. Phy. memory usage: %ldkB\n",(long)usage.ru_maxrss);
+    pf("\tPage fault number (no io): %ld\n",(long)usage.ru_minflt);
+    pf("\tPage fault number (requiring io): %ld\n",(long)usage.ru_majflt);
+    pf("\tNumber of file system read: %ld\n",(long)usage.ru_inblock);
+    pf("\tNumber of filesystem write: %ld\n",(long)usage.ru_oublock);
+    pf("\tNumber of context switch (process origin, io...): %ld\n",(long)usage.ru_nvcsw);
+    pf("\tNumber of context switch (os origin, priority...): %ld\n",(long)usage.ru_nivcsw);
+  }
 }
 
 void signal_handler(int sig) {
@@ -180,9 +180,9 @@ void signal_handler(int sig) {
     backtrace_symbols_fd(array, size, 2);
     exit(-1);
   } else {
-  	if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
-  		softmodem_printresources(sig,(telnet_printfunc_t)printf);
-  	if (sig != SOFTMODEM_RTSIGNAL) {
+    if(sig==SIGINT ||sig==SOFTMODEM_RTSIGNAL)
+      softmodem_printresources(sig,(telnet_printfunc_t)printf);
+    if (sig != SOFTMODEM_RTSIGNAL) {
       printf("Linux signal %s...\n",strsignal(sig));
       exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n");
     }
@@ -192,7 +192,7 @@ void signal_handler(int sig) {
 
 
 void set_softmodem_sighandler(void) {
-  struct sigaction	act,oldact;
+  struct sigaction  act,oldact;
   clock_gettime(CLOCK_BOOTTIME, &start);
   memset(&act,0,sizeof(act));
   act.sa_handler=signal_handler;
@@ -201,6 +201,6 @@ void set_softmodem_sighandler(void) {
   signal(SIGSEGV, signal_handler);
   signal(SIGINT,  signal_handler);
   signal(SIGTERM, signal_handler);
-  signal(SIGABRT, signal_handler);	
+  signal(SIGABRT, signal_handler);
 }
 
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index cfed951469e..0ac7b6449e5 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -38,6 +38,11 @@ extern "C"
 #endif
 /* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
 #define CONFIG_HLP_RFCFGF        "Configuration file for front-end (e.g. LMS7002M)\n"
+#define CONFIG_HLP_SPLIT73       "Split 7.3 (below rate matching) option: <cu|du>:<remote ip address>:<remote port>"
+#define CONFIG_HLP_TPOOL         "Thread pool configuration: \n\
+  default no pool (runs in calling thread),\n\
+  list of cores, comma separated (negative value is no core affinity)\n\
+  example: -1,3 launches two working threads one floating, the second set on core 3"
 #define CONFIG_HLP_ULMAXE        "set the eNodeB max ULSCH erros\n"
 #define CONFIG_HLP_CALUER        "set UE RX calibration\n"
 #define CONFIG_HLP_CALUERM       ""
@@ -53,6 +58,7 @@ extern "C"
 #define CONFIG_HLP_EXTS          "tells hardware to use an external timing reference\n"
 #define CONFIG_HLP_DMRSSYNC      "tells RU to insert DMRS in subframe 1 slot 0"
 #define CONFIG_HLP_CLK           "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
+#define CONFIG_HLP_TME           "tells hardware to use a time reference (0:internal, 1:external, 2:gpsdo)\n"
 #define CONFIG_HLP_USIM          "use XOR autentication algo in case of test usim mode\n"
 #define CONFIG_HLP_NOSNGLT       "Disables single-thread mode in lte-softmodem\n"
 #define CONFIG_HLP_DLF           "Set the downlink frequency for all component carriers\n"
@@ -88,6 +94,8 @@ extern "C"
 /*   optname                 helpstr                  paramflags      XXXptr                              defXXXval              type         numelt   */
 /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define RF_CONFIG_FILE      softmodem_params.rf_config_file
+#define SPLIT73             softmodem_params.split73
+#define TP_CONFIG           softmodem_params.threadPoolConfig
 #define PHY_TEST            softmodem_params.phy_test
 #define WAIT_FOR_SYNC       softmodem_params.wait_for_sync
 #define SINGLE_THREAD_FLAG  softmodem_params.single_thread_flag
@@ -103,9 +111,12 @@ extern "C"
 
 #define CMDLINE_PARAMS_DESC {  \
     {"rf-config-file",       CONFIG_HLP_RFCFGF,       0,              strptr:(char **)&RF_CONFIG_FILE,    defstrval:NULL,        TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
+    {"split73",              CONFIG_HLP_SPLIT73,      0,              strptr:(char **)&SPLIT73,           defstrval:NULL,        TYPE_STRING, sizeof(SPLIT73)},\
+    {"thread-pool",          CONFIG_HLP_TPOOL,        0,              strptr:(char **)&TP_CONFIG,         defstrval:"n",         TYPE_STRING, sizeof(TP_CONFIG)}, \
     {"phy-test",             CONFIG_HLP_PHYTST,       PARAMFLAG_BOOL, iptr:&PHY_TEST,                     defintval:0,           TYPE_INT,    0},                     \
     {"usim-test",            CONFIG_HLP_USIM,         PARAMFLAG_BOOL, u8ptr:&USIM_TEST,                   defintval:0,           TYPE_UINT8,  0},                     \
-    {"clock",                CONFIG_HLP_CLK,          0,              uptr:&CLOCK_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
+    {"clock-source",                CONFIG_HLP_CLK,          0,              uptr:&CLOCK_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
+    {"time-source",                CONFIG_HLP_TME,          0,              uptr:&TIMING_SOURCE,                 defintval:0,           TYPE_UINT,   0},                     \
     {"wait-for-sync",        NULL,                    PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC,                defintval:0,           TYPE_INT,    0},                     \
     {"single-thread-enable", CONFIG_HLP_NOSNGLT,      PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG,           defintval:0,           TYPE_INT,    0},                     \
     {"C" ,                   CONFIG_HLP_DLF,          0,              u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64,   0},                     \
@@ -191,6 +202,8 @@ typedef struct {
   uint64_t       optmask;
   //THREAD_STRUCT  thread_struct;
   char           rf_config_file[1024];
+  char           split73[1024];
+  char           threadPoolConfig[1024];
   int            phy_test;
   uint8_t        usim_test;
   int            emulate_rf;
diff --git a/nfapi/oai_integration/nfapi.c b/nfapi/oai_integration/nfapi.c
index 4fc35fd9513..86d1ae3127d 100644
--- a/nfapi/oai_integration/nfapi.c
+++ b/nfapi/oai_integration/nfapi.c
@@ -29,7 +29,7 @@ typedef struct {
   nfapi_mode_t nfapi_mode;
 } nfapi_params_t;
 
-static nfapi_params_t nfapi_params;
+static nfapi_params_t nfapi_params = {0};
 
 void set_thread_priority(int priority) {
   //printf("%s(priority:%d)\n", __FUNCTION__, priority);
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index f07fb1ad23f..59857659c13 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -49,7 +49,6 @@ extern RAN_CONTEXT_t RC;
 #include "fapi_stub.h"
 //#include "fapi_l1.h"
 #include "common/utils/LOG/log.h"
-#include "openair2/LAYER2/MAC/mac_proto.h"
 
 #include "PHY/INIT/phy_init.h"
 #include "PHY/LTE_TRANSPORT/transport_proto.h"
@@ -692,13 +691,14 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
   free(header);
 }
 
-int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
+int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
   if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
     LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
 
   //phy_info* phy = (phy_info*)(pnf_p7->user_data);
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
+  if (proc ==NULL) 
+    proc = &eNB->proc.L1_proc;
 
   for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) {
     //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
@@ -719,7 +719,7 @@ int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *
   return 0;
 }
 
-int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
+int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
   if (RC.ru == 0) {
     return -1;
   }
@@ -740,7 +740,8 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
   int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
+  if (proc==NULL)
+     proc = &eNB->proc.L1_proc;
   nfapi_dl_config_request_pdu_t *dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
   LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1];
   pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
@@ -797,7 +798,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
         uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid];
         memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length);
         //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
-        handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.L1_proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
+        handle_nfapi_dlsch_pdu( eNB, sfn,sf, proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
       } else {
         NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), rel8_pdu->pdu_index);
       }
@@ -837,7 +838,7 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
   return 0;
 }
 
-int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
+int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
   if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
                 __FUNCTION__,
                 NFAPI_SFNSF2DEC(req->sfn_sf),
@@ -866,7 +867,8 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request
   uint16_t curr_sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf);
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
+  if (proc==NULL)
+     proc = &eNB->proc.L1_proc;
   nfapi_ul_config_request_pdu_t *ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
 
   for (int i=0; i<req->ul_config_request_body.number_of_pdus; i++) {
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index e213d785f14..2c8201737c8 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -23,5 +23,5 @@
 #define NFAPI_PNF_H__
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
 void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
-
+void oai_subframe_ind(uint16_t sfn, uint16_t sf);
 #endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 576144e1df9..2c3809f5d41 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -22,6 +22,8 @@
 #include "fapi_nr_ue_constants.h"
 #include "PHY/impl_defs_nr.h"
 
+#define NFAPI_UE_MAX_NUM_CB 8
+
 /*
   typedef unsigned int	   uint32_t;
   typedef unsigned short	   uint16_t;
@@ -256,40 +258,124 @@ typedef struct {
 
     } fapi_nr_ul_config_pucch_pdu;
 
-    typedef enum {pusch_freq_hopping_disabled = 0 , pusch_freq_hopping_enabled = 1}pusch_freq_hopping_t;
-    typedef struct{
-    uint8_t aperiodicSRS_ResourceTrigger;
-    } fapi_nr_ul_srs_config_t;
-    typedef struct {
-        uint8_t bandwidth_part_ind;
-        uint16_t number_rbs;
-        uint16_t start_rb;
-        uint8_t frame_offset;
-        uint16_t number_symbols;
-        uint16_t start_symbol;
-        pusch_freq_hopping_t pusch_freq_hopping;
-        uint8_t mcs;
-        uint8_t ndi;
-        uint8_t rv;
-        uint8_t harq_process_nbr;
-        int8_t accumulated_delta_PUSCH;
-        int8_t absolute_delta_PUSCH;
-        uint8_t n_layers;
-        uint8_t tpmi;
-        uint8_t n_dmrs_cdm_groups;
-        uint8_t dmrs_ports[4];
-        uint8_t n_front_load_symb;
-        fapi_nr_ul_srs_config_t srs_config;
-        uint8_t csi_reportTriggerSize;
-        uint8_t maxCodeBlockGroupsPerTransportBlock;
-        uint8_t ptrs_dmrs_association_port;
-        uint8_t beta_offset_ind;
-    } fapi_nr_ul_config_pusch_pdu_rel15_t;
+typedef struct
+{
+  uint8_t  rv_index;
+  uint8_t  harq_process_id;
+  uint8_t  new_data_indicator;
+  uint32_t tb_size;
+  uint16_t num_cb;
+  uint8_t cb_present_and_position[(NFAPI_UE_MAX_NUM_CB+7) / 8];
 
-typedef struct {
+} nfapi_nr_ue_pusch_data_t;
+
+typedef struct
+{
+  uint16_t harq_ack_bit_length;
+  uint16_t csi_part1_bit_length;
+  uint16_t csi_part2_bit_length;
+  uint8_t  alpha_scaling;
+  uint8_t  beta_offset_harq_ack;
+  uint8_t  beta_offset_csi1;
+  uint8_t  beta_offset_csi2;
+
+} nfapi_nr_ue_pusch_uci_t;
+
+typedef struct
+{
+  uint16_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec6.2.3.1 and 38.212, section 7.3.1.1.2] Bitmap occupying the 12 LSBs with: bit 0: antenna port 0 bit 11: antenna port 11 and for each bit 0: PTRS port not used 1: PTRS port used
+  uint8_t  ptrs_dmrs_port;//DMRS port corresponding to PTRS.
+  uint8_t  ptrs_re_offset;//PT-RS resource element offset value taken from 0~11
+} nfapi_nr_ue_ptrs_ports_t;
+
+typedef struct
+{
+  uint8_t  num_ptrs_ports;
+  nfapi_nr_ue_ptrs_ports_t* ptrs_ports_list;
+  uint8_t  ptrs_time_density;
+  uint8_t  ptrs_freq_density;
+  uint8_t  ul_ptrs_power;
+
+}nfapi_nr_ue_pusch_ptrs_t;
+
+typedef struct
+{
+  uint8_t  low_papr_group_number;//Group number for Low PAPR sequence generation.
+  uint16_t low_papr_sequence_number;//[TS38.211, sec 5.2.2] For DFT-S-OFDM.
+  uint8_t  ul_ptrs_sample_density;//Number of PTRS groups [But I suppose this sentence is misplaced, so as the next one. --Chenyu]
+  uint8_t  ul_ptrs_time_density_transform_precoding;//Number of samples per PTRS group
+
+} nfapi_nr_ue_dfts_ofdm_t;
+
+typedef struct
+{
+  uint16_t beam_idx;//Index of the digital beam weight vector pre-stored at cell configuration. The vector maps this input port to output TXRUs. Value: 0->65535
+
+}nfapi_nr_ue_dig_bf_interface_t;
+
+typedef struct
+{
+  nfapi_nr_ue_dig_bf_interface_t* dig_bf_interface_list;
+
+} nfapi_nr_ue_ul_beamforming_number_of_prgs_t;
+
+typedef struct
+{
+  uint16_t num_prgs;
+  uint16_t prg_size;
+  //watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces
+  uint8_t  dig_bf_interface;
+  nfapi_nr_ue_ul_beamforming_number_of_prgs_t* prgs_list;//
+
+} nfapi_nr_ue_ul_beamforming_t;
+
+typedef struct
+{
+  uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs (see above)
   uint16_t rnti;
-  fapi_nr_ul_config_pusch_pdu_rel15_t ulsch_pdu_rel15;
-} fapi_nr_ul_config_pusch_pdu;
+  uint32_t handle;//An opaque handling returned in the RxData.indication and/or UCI.indication message
+  //BWP
+  uint16_t bwp_size;
+  uint16_t bwp_start;
+  uint8_t  subcarrier_spacing;
+  uint8_t  cyclic_prefix;
+  //pusch information always include
+  uint16_t target_code_rate;
+  uint8_t  qam_mod_order;
+  uint8_t  mcs_index;
+  uint8_t  mcs_table;
+  uint8_t  transform_precoding;
+  uint16_t data_scrambling_id;
+  uint8_t  nrOfLayers;
+  //DMRS
+  uint16_t  ul_dmrs_symb_pos;
+  uint8_t  dmrs_config_type;
+  uint16_t ul_dmrs_scrambling_id;
+  uint8_t  scid;
+  uint8_t  num_dmrs_cdm_grps_no_data;
+  uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
+  //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
+  uint8_t  resource_alloc;
+  uint8_t  rb_bitmap[36];//
+  uint16_t rb_start;
+  uint16_t rb_size;
+  uint8_t  vrb_to_prb_mapping;
+  uint8_t  frequency_hopping;
+  uint16_t tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
+  uint8_t  uplink_frequency_shift_7p5khz;
+  //Resource Allocation in time domain
+  uint8_t  start_symbol_index;
+  uint8_t  nr_of_symbols;
+  //Optional Data only included if indicated in pduBitmap
+  nfapi_nr_ue_pusch_data_t pusch_data;
+  nfapi_nr_ue_pusch_uci_t  pusch_uci;
+  nfapi_nr_ue_pusch_ptrs_t pusch_ptrs;
+  nfapi_nr_ue_dfts_ofdm_t dfts_ofdm;
+  //beamforming
+  nfapi_nr_ue_ul_beamforming_t beamforming;
+  //OAI specific
+  int8_t absolute_delta_PUSCH;
+} nfapi_nr_ue_pusch_pdu_t;
 
 typedef struct {
 
@@ -300,7 +386,7 @@ typedef struct {
   union {
     fapi_nr_ul_config_prach_pdu prach_config_pdu;
     fapi_nr_ul_config_pucch_pdu pucch_config_pdu;
-    fapi_nr_ul_config_pusch_pdu ulsch_config_pdu;
+    nfapi_nr_ue_pusch_pdu_t     pusch_config_pdu;
     fapi_nr_ul_config_srs_pdu srs_config_pdu;
   };
 } fapi_nr_ul_config_request_pdu_t;
@@ -341,7 +427,6 @@ typedef struct {
   uint8_t SubcarrierSpacing;  
   uint16_t number_rbs;
   uint16_t start_rb;
-  uint8_t frame_offset;
   uint16_t number_symbols;
   uint16_t start_symbol;
   uint16_t dlDmrsSymbPos;  
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index 5fe1c53a546..650bda4f780 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -10,6 +10,7 @@
 #define _NFAPI_NR_INTERFACE_H_
 
 #include "nfapi_interface.h"
+#include <nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h>
 
 #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index f69c928ed27..54b592202d5 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -19,6 +19,7 @@
 
 #define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6
 #define NFAPI_MAX_NUM_UL_PDU 8
+#define NFAPI_MAX_NUM_UCI_INDICATION 8
 #define NFAPI_MAX_NUM_GROUPS 8
 #define NFAPI_MAX_NUM_CB 8
 
@@ -1393,7 +1394,7 @@ typedef struct
   uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid
   uint16_t rssi;
   //variable ! fixme
-  uint32_t pdu; //MAC PDU
+  uint8_t *pdu; //MAC PDU
 
 } nfapi_nr_rx_data_pdu_t;
 
@@ -1519,8 +1520,8 @@ typedef struct
   uint8_t  ul_cqi;
   uint16_t timing_advance;
   uint16_t rssi;
-  nfapi_nr_sr_pdu_0_1_t sr;//67
-  nfapi_nr_harq_pdu_0_1_t harq;//68
+  nfapi_nr_sr_pdu_0_1_t *sr;//67
+  nfapi_nr_harq_pdu_0_1_t *harq;//68
   
 
 }nfapi_nr_uci_pucch_pdu_format_0_1_t;
@@ -1542,28 +1543,22 @@ typedef struct
 
 }nfapi_nr_uci_pucch_pdu_format_2_3_4_t;
 
-//for SR, HARQ and CSI Part 1/ 2 PDUs
-
-typedef struct
-{
-  nfapi_nr_uci_pusch_pdu_t* pusch_pdu;
-  nfapi_nr_uci_pucch_pdu_format_0_1_t* pucch_pdu_format_0_1;
-  nfapi_nr_uci_pucch_pdu_format_2_3_4_t* pucch_pdu_format_2_3_4;
-  nfapi_nr_sr_pdu_0_1_t*   sr_pdu_0_1;
-  nfapi_nr_sr_pdu_2_3_4_t* sr_pdu_2_3_4;
-  nfapi_nr_harq_pdu_0_1_t* harq_pdu_0_1;
-  nfapi_nr_harq_pdu_2_3_4_t* harq_pdu_2_3_4;
-  nfapi_nr_csi_part1_pdu_t*  csi_part1_pdu;
-  nfapi_nr_csi_part2_pdu_t*  csi_part2_pdu;
-
-} nfapi_nr_uci_pdu_information_t;
+typedef enum {
+  NFAPI_NR_UCI_PDCCH_PDU_TYPE  = 0,
+  NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE  = 1,
+  NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2,
+} nfapi_nr_uci_pdu_type_e;
 
 typedef struct
 {
-  uint16_t pdu_type;
+  uint16_t pdu_type;  // 0 for PDU on PUSCH, 1 for PUCCH format 0 or 1, 2 for PUCCH format 2 to 4
   uint16_t pdu_size;
-  nfapi_nr_uci_pdu_information_t uci_pdu;
-
+  union
+  {
+    nfapi_nr_uci_pusch_pdu_t pusch_pdu;
+    nfapi_nr_uci_pucch_pdu_format_0_1_t pucch_pdu_format_0_1;
+    nfapi_nr_uci_pucch_pdu_format_2_3_4_t pucch_pdu_format_2_3_4;
+  };
 } nfapi_nr_uci_t;
 
 typedef struct
@@ -1571,7 +1566,7 @@ typedef struct
   uint16_t sfn;
   uint16_t slot;
   uint16_t num_ucis;
-  nfapi_nr_uci_t* uci_list;
+  nfapi_nr_uci_t uci_list[NFAPI_MAX_NUM_UCI_INDICATION];
 
 } nfapi_nr_uci_indication_t;
 
diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
index 8d17416a418..d169177d6b1 100644
--- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
+++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
@@ -24,6 +24,7 @@ extern "C" {
 
 #include "nfapi_interface.h"
 #include "debug.h"
+#include <openair2/PHY_INTERFACE/IF_Module.h>
 
 #include <sys/types.h>
 
@@ -619,21 +620,21 @@ typedef struct nfapi_pnf_p7_config
 	 * \param req A pointer to the dl config request message structure
 	 * \return not currently used
 	 */
-	int (*dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
+	int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
 	
 	/*! A callback for the UL_CONFIG.request
 	 * \param config A poiner to the PNF P7 config
 	 * \param req A pointer to the ul config request message structure
 	 * \return not currently used	
 	 */
-	int (*ul_config_req)(nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
+	int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
 	
 	/*! A callback for the HI_DCI0.request
 	 * \param config A poiner to the PNF P7 config
 	 * \param req A pointer to the hi dci0 request message structure
 	 * \return not currently used
 	 */
-	int (*hi_dci0_req)(nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
+	int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
 	
 	/*! A callback for the TX_REQ.request
 	 * \param config A poiner to the PNF P7 config
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_interface.c
index 7310fc0c66c..dda0d0fdc60 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c
@@ -39,7 +39,7 @@ nfapi_pnf_config_t* nfapi_pnf_config_create()
 	_this->_public.codec_config.allocate = &malloc;
 	_this->_public.codec_config.deallocate = &free;
 
-	return &(_this->_public);
+	return (nfapi_pnf_config_t* )_this;
 }
 
 void nfapi_pnf_config_destory(nfapi_pnf_config_t* config)
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
index 94467303750..5ba912e059f 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
@@ -576,20 +576,20 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
 	{
 		pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf;
 		//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - enter\n");
-		(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
+		(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
 		//NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - exit\n");
 	}
 	if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
 	{
 		pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
 		NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy ul_config_req - enter\n");
-		(pnf_p7->_public.ul_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.ul_config_req);
+		(pnf_p7->_public.ul_config_req)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_subframe.ul_config_req);
 	}
 	if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
 	{
 		pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf;
 		NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy hi_dci0 - enter\n");
-		(pnf_p7->_public.hi_dci0_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.hi_dci0_req);
+		(pnf_p7->_public.hi_dci0_req)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_subframe.hi_dci0_req);
 	}
 	if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req)
 	{
@@ -699,7 +699,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
 			if(tx_subframe_buffer->dl_config_req != 0)
 			{
 				if(pnf_p7->_public.dl_config_req)
-					(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), tx_subframe_buffer->dl_config_req);
+					(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->dl_config_req);
 
 				//deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
 			}
@@ -709,14 +709,14 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
 				if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_config_req)
 				{
 					pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf_tx;
-					(pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
+					(pnf_p7->_public.dl_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req);
 				}
 			}
 
 			if(tx_subframe_buffer->hi_dci0_req != 0)
 			{
 				if(pnf_p7->_public.hi_dci0_req)
-					(pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req);
+					(pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req);
 
 				//deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7);
 			}
@@ -726,7 +726,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
 				if(pnf_p7->_public.hi_dci0_req && pnf_p7->_public.dummy_subframe.hi_dci0_req)
 				{
 					pnf_p7->_public.dummy_subframe.hi_dci0_req->sfn_sf = sfn_sf_tx;
-					(pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.hi_dci0_req);
+					(pnf_p7->_public.hi_dci0_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.hi_dci0_req);
 				}
 			}
 
@@ -777,7 +777,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
 			if(subframe_buffer->ul_config_req != 0)
 			{
 				if(pnf_p7->_public.ul_config_req)
-					(pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), subframe_buffer->ul_config_req);
+					(pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), subframe_buffer->ul_config_req);
 
 				//deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
 			}
@@ -787,7 +787,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
 				if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req)
 				{
 					pnf_p7->_public.dummy_subframe.ul_config_req->sfn_sf = sfn_sf;
-					(pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ul_config_req);
+					(pnf_p7->_public.ul_config_req)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ul_config_req);
 				}
 			}
 
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c
index 0aba0a29f5e..59d7f3eb4fb 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c
@@ -55,7 +55,7 @@ nfapi_vnf_config_t* nfapi_vnf_config_create()
 	_this->_public.codec_config.deallocate = &free;
 	
 
-	return &(_this->_public);
+	return (nfapi_vnf_config_t* )_this;
 }
 
 void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
index 35bd5e4c1b8..a0efeeb5f4d 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
@@ -47,7 +47,7 @@ nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
 	_this->_public.codec_config.deallocate = &free;
 	
 
-	return &(_this->_public);
+	return (nfapi_vnf_p7_config_t*)_this;
 }
 
 void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config)
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index d47d6e77553..b3c9f3117c3 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -18,7 +18,6 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-// add GPU mode (-G 1)
 
 #include <stdlib.h>
 #include <math.h>
@@ -26,12 +25,11 @@
 #include <string.h>
 #include "assertions.h"
 #include "SIMULATION/TOOLS/sim.h"
-#include "PHY/CODING/nrLDPC_encoder/defs.h"
-#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
+#include "PHY/CODING/nrLDPC_extern.h"
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
-
-#include "PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
-
+// extern "C" {
+#include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
+// }
 #define MAX_NUM_DLSCH_SEGMENTS 16
 #define MAX_BLOCK_LENGTH 8448
 
@@ -88,6 +86,7 @@ typedef struct {
 RAN_CONTEXT_t RC;
 PHY_VARS_UE ***PHY_vars_UE_g;
 uint16_t NB_UE_INST = 1;
+nrLDPC_encoderfunc_t encoder_orig;
 
 short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
 
@@ -118,7 +117,6 @@ int test_ldpc(short No_iteration,
 
   double sigma;
   sigma = 1.0/sqrt(2*SNR);
-
   opp_enabled=1;
   cpu_freq_GHz = get_cpu_freq_GHz();
   //short test_input[block_length];
@@ -290,16 +288,19 @@ int test_ldpc(short No_iteration,
   no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
   //  printf("puncture:%d\n",no_punctured_columns);
   removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
+  encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS;
+ 
+  impp.gen_code=1;
   if (ntrials==0)
-    ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1);
-
+    encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp);
+  impp.gen_code=0;
   for (trial=0; trial < ntrials; trial++)
   {
 	segment_bler = 0;
     //// encoder
     start_meas(&time);
     for(j=0;j<n_segments;j++) {
-      ldpc_encoder_orig(test_input[j], channel_input[j],Zc,Kb,block_length,BG,0);
+      encoder_orig(&(test_input[j]), &(channel_input[j]),Zc,Kb,block_length,BG,&impp);
     }
     stop_meas(&time);
 
@@ -309,10 +310,11 @@ int test_ldpc(short No_iteration,
       ldpc_encoder_optim(test_input[j],channel_input_optim[j],Zc,Kb,block_length,BG,&tinput,&tprep,&tparity,&toutput);
       }
     stop_meas(time_optim);*/
-
+    impp.n_segments=n_segments;
     for(j=0;j<(n_segments/8+1);j++) {
     	start_meas(time_optim);
-    	ldpc_encoder_optim_8seg_multi(test_input,channel_input_optim,Zc,Kb,block_length, BG, n_segments,j,&tinput,&tprep,&tparity,&toutput);
+    	impp.macro_num=j;
+    	nrLDPC_encoder(test_input,channel_input_optim,Zc,Kb,block_length, BG, &impp);
     	stop_meas(time_optim);
     }
     
@@ -399,25 +401,21 @@ int test_ldpc(short No_iteration,
 
 
       for(j=0;j<n_segments;j++) {
+    	  start_meas(time_decoder);
+
+        if(run_cuda){
+          printf("***********run ldpc by cuda\n");
+          n_iter = nrLDPC_decoder_LYC(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length, time_decoder);
+      }  
+      else{ 
+        printf("**************run ldpc by cpu\n");  
       // decode the sequence
       // decoder supports BG2, Z=128 & 256
       //esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
       ///nrLDPC_decoder(&decParams, channel_output_fixed, estimated_output, NULL);
-//#ifdef __NR_LDPC_DECODER_LYC__H__RUN__
-		if(run_cuda){
-		  printf("run ldpc by cuda\n");
-    	  start_meas(time_decoder);
-		  n_iter = nrLDPC_decoder_LYC(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length, time_decoder);
-		  stop_meas(time_decoder);
-		}  
-//#else	
-        else{	
-		  printf("run ldpc by cpu\n");
-    	  start_meas(time_decoder);
-		  n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_nrLDPC_procBuf, p_decoder_profiler);
-		  stop_meas(time_decoder);
-		}  
-//#endif      
+        n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_nrLDPC_procBuf, p_decoder_profiler);
+      }
+	stop_meas(time_decoder);
       }
 
       //for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
@@ -520,10 +518,12 @@ int main(int argc, char *argv[])
   unsigned int errors, errors_bit, crc_misses;
   double errors_bit_uncoded;
   short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
-  short run_cuda = 0;
+
   short No_iteration=5;
   int n_segments=1;
   //double rate=0.333;
+  short run_cuda = 0;
+  
   int nom_rate=1;
   int denom_rate=3;
   double SNR0=-2.0,SNR,SNR_lin;
@@ -540,9 +540,9 @@ int main(int argc, char *argv[])
   time_stats_t time_optim[10], time_decoder[10];
   n_iter_stats_t dec_iter[3];
 
-  short BG=0,Zc,Kb;
+  short BG=0,Zc,Kb=0;
 
-  while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h:G:")) != -1)
+  while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:h")) != -1)
     switch (c)
     {
       case 'q':
@@ -552,10 +552,7 @@ int main(int argc, char *argv[])
       case 'r':
         nom_rate = atoi(optarg);
         break;
-	  case 'G':
-        run_cuda = atoi(optarg);
-        break;
-		
+
       case 'd':
         denom_rate = atoi(optarg);
         break;
@@ -563,6 +560,10 @@ int main(int argc, char *argv[])
       case 'l':
         block_length = atoi(optarg);
         break;
+		
+	  case 'G':
+        run_cuda = atoi(optarg);
+        break;
 
       case 'n':
         n_trials = atoi(optarg);
@@ -587,7 +588,6 @@ int main(int argc, char *argv[])
       case 'u':
         test_uncoded = atoi(optarg);
         break;
-		
 
       case 'h':
             default:
@@ -599,6 +599,7 @@ int main(int argc, char *argv[])
               printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
               printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
               printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
+			  printf("-G give 1 to run cuda for LDPC, Default: 0\n");
               printf("-n Number of simulation trials, Default: 1\n");
               //printf("-M MCS2 for TB 2\n");
               printf("-s SNR per information bit (EbNo) in dB, Default: -2\n");
@@ -606,7 +607,6 @@ int main(int argc, char *argv[])
               printf("-t SNR simulation step, Default: 0.1\n");
               printf("-i Max decoder iterations, Default: 5\n");
               printf("-u Set SNR per coded bit, Default: 0\n");
-			  printf("-G set 1 to run cuda for ldpc \n");
               exit(1);
               break;
     }
@@ -616,10 +616,10 @@ int main(int argc, char *argv[])
   printf("block length %d: \n", block_length);
   printf("n_trials %d: \n", n_trials);
   printf("SNR0 %f: \n", SNR0);
-  
-
 
 
+  load_nrLDPClib();
+  load_nrLDPClib_ref("_orig", &encoder_orig);
   //for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
 
 
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
index dbf671fdfb1..785b588b9fa 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
@@ -1,4 +1,4 @@
-/*               
+/*
  * 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.
@@ -18,7 +18,7 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-      
+
 /*!\file nrLDPC_decoder.c
  * \brief Defines the LDPC decoder
  * \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
index 10b45ac0e78..b76750459d9 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h
@@ -135,25 +135,25 @@ static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrL
 */
 static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
 {
-    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
-    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
-    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
-    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
-
-    const uint8_t (*lut_posBnInCnProcBuf_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->posBnInCnProcBuf[0];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->posBnInCnProcBuf[1];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->posBnInCnProcBuf[2];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->posBnInCnProcBuf[3];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->posBnInCnProcBuf[4];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->posBnInCnProcBuf[5];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->posBnInCnProcBuf[6];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->posBnInCnProcBuf[7];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (uint8_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->posBnInCnProcBuf[8];
+    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
+    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
+    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
+    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
+
+    const uint8_t (*lut_posBnInCnProcBuf_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->posBnInCnProcBuf[0];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->posBnInCnProcBuf[1];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->posBnInCnProcBuf[2];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->posBnInCnProcBuf[3];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->posBnInCnProcBuf[4];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->posBnInCnProcBuf[5];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->posBnInCnProcBuf[6];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->posBnInCnProcBuf[7];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (const uint8_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->posBnInCnProcBuf[8];
 
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -344,19 +344,19 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, t_
 */
 static inline void nrLDPC_llr2CnProcBuf_BG2(t_nrLDPC_lut* p_lut, int8_t* llr, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
 {
-    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
-
-    const uint8_t (*lut_posBnInCnProcBuf_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->posBnInCnProcBuf[0];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->posBnInCnProcBuf[1];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->posBnInCnProcBuf[2];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->posBnInCnProcBuf[3];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->posBnInCnProcBuf[4];
-    const uint8_t (*lut_posBnInCnProcBuf_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (uint8_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->posBnInCnProcBuf[5];
+    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
+
+    const uint8_t (*lut_posBnInCnProcBuf_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->posBnInCnProcBuf[0];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->posBnInCnProcBuf[1];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->posBnInCnProcBuf[2];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->posBnInCnProcBuf[3];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->posBnInCnProcBuf[4];
+    const uint8_t (*lut_posBnInCnProcBuf_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (const uint8_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->posBnInCnProcBuf[5];
 
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
@@ -483,26 +483,26 @@ static inline void nrLDPC_cn2bnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
-
-    const uint32_t (*lut_startAddrBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
-
-    const uint8_t (*lut_bnPosBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (uint8_t(*)[lut_numCnInCnGroups[0]]) p_lut->bnPosBnProcBuf[0];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
+    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
+
+    const uint32_t (*lut_startAddrBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (const uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (const uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (const uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (const uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
+
+    const uint8_t (*lut_bnPosBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (const uint8_t(*)[lut_numCnInCnGroups[0]]) p_lut->bnPosBnProcBuf[0];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (const uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (const uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (const uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
 
     int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
     int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
@@ -626,34 +626,34 @@ static inline void nrLDPC_cn2bnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
-    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
-    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
-    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
-
-    const uint32_t (*lut_startAddrBnProcBuf_CNG3) [lut_numCnInCnGroups[0]] = (uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (uint32_t(*)[lut_numCnInCnGroups[6]]) p_lut->startAddrBnProcBuf[6];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (uint32_t(*)[lut_numCnInCnGroups[7]]) p_lut->startAddrBnProcBuf[7];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (uint32_t(*)[lut_numCnInCnGroups[8]]) p_lut->startAddrBnProcBuf[8];
-
-    const uint8_t (*lut_bnPosBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (uint8_t(*)[lut_numCnInCnGroups[6]]) p_lut->bnPosBnProcBuf[6];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
+    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
+    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
+    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
+    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
+
+    const uint32_t (*lut_startAddrBnProcBuf_CNG3) [lut_numCnInCnGroups[0]] = (const uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (const uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (const uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (const uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (const uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (const uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (const uint32_t(*)[lut_numCnInCnGroups[6]]) p_lut->startAddrBnProcBuf[6];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint32_t(*)[lut_numCnInCnGroups[7]]) p_lut->startAddrBnProcBuf[7];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint32_t(*)[lut_numCnInCnGroups[8]]) p_lut->startAddrBnProcBuf[8];
+
+    const uint8_t (*lut_bnPosBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (const uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (const uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (const uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (const uint8_t(*)[lut_numCnInCnGroups[6]]) p_lut->bnPosBnProcBuf[6];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
 
     int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
     int8_t* bnProcBuf    = p_procBuf->bnProcBuf;
@@ -824,26 +824,26 @@ static inline void nrLDPC_bn2cnProcBuf_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
-
-    const uint32_t (*lut_startAddrBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
-
-    const uint8_t (*lut_bnPosBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (uint8_t(*)[lut_numCnInCnGroups[0]]) p_lut->bnPosBnProcBuf[0];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
+    const uint16_t (*lut_circShift_CNG3)  [lut_numCnInCnGroups_BG2_R15[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4)  [lut_numCnInCnGroups_BG2_R15[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5)  [lut_numCnInCnGroups_BG2_R15[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6)  [lut_numCnInCnGroups_BG2_R15[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG8)  [lut_numCnInCnGroups_BG2_R15[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG10) [lut_numCnInCnGroups_BG2_R15[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG2_R15[5]]) p_lut->circShift[5];
+
+    const uint32_t (*lut_startAddrBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (const uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (const uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (const uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (const uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
+
+    const uint8_t (*lut_bnPosBnProcBuf_CNG3)  [lut_numCnInCnGroups[0]] = (const uint8_t(*)[lut_numCnInCnGroups[0]]) p_lut->bnPosBnProcBuf[0];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG4)  [lut_numCnInCnGroups[1]] = (const uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG5)  [lut_numCnInCnGroups[2]] = (const uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG6)  [lut_numCnInCnGroups[3]] = (const uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG8)  [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG10) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
 
     int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
     int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
@@ -966,34 +966,34 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf
     const uint8_t*  lut_numCnInCnGroups = p_lut->numCnInCnGroups;
     const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
 
-    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
-    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
-    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
-    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
-    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
-    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
-    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
-    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
-    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
-
-    const uint32_t (*lut_startAddrBnProcBuf_CNG3) [lut_numCnInCnGroups[0]] = (uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (uint32_t(*)[lut_numCnInCnGroups[6]]) p_lut->startAddrBnProcBuf[6];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (uint32_t(*)[lut_numCnInCnGroups[7]]) p_lut->startAddrBnProcBuf[7];
-    const uint32_t (*lut_startAddrBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (uint32_t(*)[lut_numCnInCnGroups[8]]) p_lut->startAddrBnProcBuf[8];
-
-    const uint8_t (*lut_bnPosBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (uint8_t(*)[lut_numCnInCnGroups[6]]) p_lut->bnPosBnProcBuf[6];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
-    const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
+    const uint16_t (*lut_circShift_CNG3) [lut_numCnInCnGroups_BG1_R13[0]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[0]]) p_lut->circShift[0];
+    const uint16_t (*lut_circShift_CNG4) [lut_numCnInCnGroups_BG1_R13[1]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[1]]) p_lut->circShift[1];
+    const uint16_t (*lut_circShift_CNG5) [lut_numCnInCnGroups_BG1_R13[2]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[2]]) p_lut->circShift[2];
+    const uint16_t (*lut_circShift_CNG6) [lut_numCnInCnGroups_BG1_R13[3]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[3]]) p_lut->circShift[3];
+    const uint16_t (*lut_circShift_CNG7) [lut_numCnInCnGroups_BG1_R13[4]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[4]]) p_lut->circShift[4];
+    const uint16_t (*lut_circShift_CNG8) [lut_numCnInCnGroups_BG1_R13[5]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[5]]) p_lut->circShift[5];
+    const uint16_t (*lut_circShift_CNG9) [lut_numCnInCnGroups_BG1_R13[6]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[6]]) p_lut->circShift[6];
+    const uint16_t (*lut_circShift_CNG10)[lut_numCnInCnGroups_BG1_R13[7]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[7]]) p_lut->circShift[7];
+    const uint16_t (*lut_circShift_CNG19)[lut_numCnInCnGroups_BG1_R13[8]] = (const uint16_t(*)[lut_numCnInCnGroups_BG1_R13[8]]) p_lut->circShift[8];
+
+    const uint32_t (*lut_startAddrBnProcBuf_CNG3) [lut_numCnInCnGroups[0]] = (const uint32_t(*)[lut_numCnInCnGroups[0]]) p_lut->startAddrBnProcBuf[0];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (const uint32_t(*)[lut_numCnInCnGroups[1]]) p_lut->startAddrBnProcBuf[1];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (const uint32_t(*)[lut_numCnInCnGroups[2]]) p_lut->startAddrBnProcBuf[2];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (const uint32_t(*)[lut_numCnInCnGroups[3]]) p_lut->startAddrBnProcBuf[3];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (const uint32_t(*)[lut_numCnInCnGroups[4]]) p_lut->startAddrBnProcBuf[4];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (const uint32_t(*)[lut_numCnInCnGroups[5]]) p_lut->startAddrBnProcBuf[5];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (const uint32_t(*)[lut_numCnInCnGroups[6]]) p_lut->startAddrBnProcBuf[6];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint32_t(*)[lut_numCnInCnGroups[7]]) p_lut->startAddrBnProcBuf[7];
+    const uint32_t (*lut_startAddrBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint32_t(*)[lut_numCnInCnGroups[8]]) p_lut->startAddrBnProcBuf[8];
+
+    const uint8_t (*lut_bnPosBnProcBuf_CNG4) [lut_numCnInCnGroups[1]] = (const uint8_t(*)[lut_numCnInCnGroups[1]]) p_lut->bnPosBnProcBuf[1];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG5) [lut_numCnInCnGroups[2]] = (const uint8_t(*)[lut_numCnInCnGroups[2]]) p_lut->bnPosBnProcBuf[2];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG6) [lut_numCnInCnGroups[3]] = (const uint8_t(*)[lut_numCnInCnGroups[3]]) p_lut->bnPosBnProcBuf[3];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG7) [lut_numCnInCnGroups[4]] = (const uint8_t(*)[lut_numCnInCnGroups[4]]) p_lut->bnPosBnProcBuf[4];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG8) [lut_numCnInCnGroups[5]] = (const uint8_t(*)[lut_numCnInCnGroups[5]]) p_lut->bnPosBnProcBuf[5];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG9) [lut_numCnInCnGroups[6]] = (const uint8_t(*)[lut_numCnInCnGroups[6]]) p_lut->bnPosBnProcBuf[6];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG10)[lut_numCnInCnGroups[7]] = (const uint8_t(*)[lut_numCnInCnGroups[7]]) p_lut->bnPosBnProcBuf[7];
+    const uint8_t (*lut_bnPosBnProcBuf_CNG19)[lut_numCnInCnGroups[8]] = (const uint8_t(*)[lut_numCnInCnGroups[8]]) p_lut->bnPosBnProcBuf[8];
 
     int8_t* cnProcBuf    = p_procBuf->cnProcBuf;
     int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c
index 207bf249f51..dddd6b1bd50 100644
--- a/openair1/PHY/INIT/lte_init_ru.c
+++ b/openair1/PHY/INIT/lte_init_ru.c
@@ -38,7 +38,7 @@ int phy_init_RU(RU_t *ru) {
   LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
   RU_CALIBRATION *calibration = &ru->calibration;
   int i,j,p,re;
-  init_dfts();
+  //load_dftslib();
   LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx);
 
   if (ru->is_slave == 1) {
@@ -76,7 +76,7 @@ int phy_init_RU(RU_t *ru) {
   }
 
   if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
-    init_dfts();
+    load_dftslib();
     init_7_5KHz();
     LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
     ru->common.rxdata_7_5kHz = (int32_t **)malloc16(ru->nb_rx*sizeof(int32_t *) );
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index 1a6f0081e1a..082db61da94 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -625,7 +625,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
   int th_id;
   LOG_D(PHY,"Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   crcTableInit();
-  init_dfts();
+  load_dftslib();
   init_frame_parms(&ue->frame_parms,1);
   lte_sync_time_init(&ue->frame_parms);
   init_lte_top(&ue->frame_parms);
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 1c0d5a6acad..813d419429b 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -96,7 +96,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
 
   while(gNB->configured == 0) usleep(10000);
 
-  init_dfts();
+  load_dftslib();
   /*
     LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
           gNB->Mod_id,
@@ -112,7 +112,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
           );*/
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
   crcTableInit();
-  init_dfts();
+  init_scrambling_luts();
+  init_pucch2_luts();
   load_nrLDPClib();
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 4ed5be2119e..5a60d15e2b4 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -657,8 +657,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   abstraction_flag = 0;
   fp->nb_antennas_tx = 1;
   fp->nb_antennas_rx=1;
-  dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
-  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
+  // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig;
+  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
   printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
   phy_init_nr_top(ue);
@@ -710,9 +710,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   }
 
   //------------- config DMRS parameters--------------//
-  dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
-  dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
-  dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
+  // dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
+  // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
+  // dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
   //-------------------------------------------------//
   ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1;
   ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0;
@@ -745,15 +745,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
   /////////////////////////PUSCH PTRS init/////////////////////////
   ///////////
 
-  ue->ptrs_configured = 0; // flag to be toggled by RCC
-
   //------------- config PTRS parameters--------------//
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0;
-  ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0;
-  ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
-  ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0;
-  ptrs_Uplink_Config->resourceElementOffset = 0;
+  // ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 2; // setting MCS values to 0 indicate abscence of time_density field in the configuration
+  // ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 4;
+  // ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 10;
+  // ptrs_Uplink_Config->frequencyDensity.n_rb0 = 25;     // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
+  // ptrs_Uplink_Config->frequencyDensity.n_rb1 = 75;
+  // ptrs_Uplink_Config->resourceElementOffset = 0;
   //-------------------------------------------------//
 
   ///////////
@@ -988,7 +986,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,
 void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   crcTableInit();
-  init_dfts();
+  load_dftslib();
   init_context_synchro_nr(frame_parms);
   generate_ul_reference_signal_sequences(SHRT_MAX);
   // Polar encoder init for PBCH
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
index 04fe19ecbce..aaa138fcd9d 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
@@ -56,22 +56,22 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
       // do ifft of channel estimate
       switch(frame_parms->N_RB_DL) {
       case 6:
-	dft128((int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
+	dft(DFT_128,(int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
 	       (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa],
 	       1);
 	break;
       case 25:
-	dft512((int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
+	dft(DFT_512,(int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
 	       (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa],
 	       1);
 	break;
       case 50:
-	dft1024((int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
+	dft(DFT_1024,(int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
 		(int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa],
 		1);
 	break;
       case 100:
-	dft2048((int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
+	dft(DFT_2048,(int16_t*) &lte_eNB_srs->srs_ch_estimates[aa][0],
 	       (int16_t*) lte_eNB_srs->srs_ch_estimates_time[aa],
 	       1);
 	break;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
index 7414c3a69d1..23f261149a6 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
@@ -23,7 +23,6 @@
 #include "PHY/defs_UE.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
 #include "PHY/impl_defs_top.h"
-#include "openair2/LAYER2/MAC/mac_proto.h"
 
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
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 43c0350efb1..2331e253d5f 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -43,7 +43,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   uint8_t pilot0,pilot1,pilot2,pilot3;
 
   short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev;
-  short *fl, *fm, *fr, *fl_dc, *fm_dc, *fr_dc, *f1, *f2l, *f2r;
+  short *fl=NULL, *fm=NULL, *fr=NULL, *fl_dc=NULL, *fm_dc=NULL, *fr_dc=NULL, *f1, *f2l=NULL, *f2r=NULL;
 
   unsigned int *rballoc; 
   int **rxdataF;
@@ -58,10 +58,10 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
 
   if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) ||
-      ((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
-    rballoc = dlsch0_harq->rb_alloc_odd;
+		  ((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
+	  rballoc = dlsch0_harq->rb_alloc_odd;
   else
-    rballoc = dlsch0_harq->rb_alloc_even;
+	  rballoc = dlsch0_harq->rb_alloc_even;
 
   rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[Ns>>1]].rxdataF;
 
@@ -69,56 +69,56 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   beamforming_mode   = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
   if (phy_vars_ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
-    ch_offset     = frame_parms->ofdm_symbol_size;
+	  ch_offset     = frame_parms->ofdm_symbol_size;
   else
-    ch_offset     = frame_parms->ofdm_symbol_size*symbol;
+	  ch_offset     = frame_parms->ofdm_symbol_size*symbol;
+
 
-  
   uespec_nushift = frame_parms->Nid_cell%3;
   subframe = Ns>>1;
- 
 
-    //generate ue specific pilots
-    lprime = symbol/3-1;
-    lte_dl_ue_spec_rx(phy_vars_ue,uespec_pilot,Ns,5,lprime,0,dlsch0_harq->nb_rb);
-    //LOG_M("uespec_pilot_rx.m","uespec_pilot",uespec_pilot,300,1,1);
-
-    if (frame_parms->Ncp==0){
-      if (symbol==3 || symbol==6 || symbol==9 || symbol==12)
-        uespec_pilots = 1;
-    } else{
-      if (symbol==4 || symbol==7 || symbol==10)
-        uespec_pilots = 1;
-    }
-   
-    if ((frame_parms->Ncp==0 && (symbol==6 ||symbol ==12)) || (frame_parms->Ncp==1 && symbol==7))
-      uespec_poffset = 2;
-
-    if (phy_vars_ue->frame_parms.Ncp == 0) { // normal prefix
-      pilot0 = 3;
-      pilot1 = 6;
-      pilot2 = 9;
-      pilot3 = 12;
-    } else { // extended prefix
-      pilot0 = 4;
-      pilot1 = 7;
-      pilot2 = 10;
-    }
 
-    //define the filter
-    pil_offset = (uespec_nushift+uespec_poffset)%3;
-    // printf("symbol=%d,pil_offset=%d\n",symbol,pil_offset);
-    switch (pil_offset) {
-    case 0:
-      fl = filt16_l0;
-      fm = filt16_m0;
-      fr = filt16_r0;
-      fl_dc = filt16_l0;
-      fm_dc = filt16_m0;
-      fr_dc = filt16_r0;
-      f1 = filt16_1;
-      f2l = filt16_2l0;
-      f2r = filt16_2r0;
+  //generate ue specific pilots
+  lprime = symbol/3-1;
+  lte_dl_ue_spec_rx(phy_vars_ue,uespec_pilot,Ns,5,lprime,0,dlsch0_harq->nb_rb);
+  //LOG_M("uespec_pilot_rx.m","uespec_pilot",uespec_pilot,300,1,1);
+
+  if (frame_parms->Ncp==0){
+	  if (symbol==3 || symbol==6 || symbol==9 || symbol==12)
+		  uespec_pilots = 1;
+  } else{
+	  if (symbol==4 || symbol==7 || symbol==10)
+		  uespec_pilots = 1;
+  }
+
+  if ((frame_parms->Ncp==0 && (symbol==6 ||symbol ==12)) || (frame_parms->Ncp==1 && symbol==7))
+	  uespec_poffset = 2;
+
+  if (phy_vars_ue->frame_parms.Ncp == 0) { // normal prefix
+	  pilot0 = 3;
+	  pilot1 = 6;
+	  pilot2 = 9;
+	  pilot3 = 12;
+  } else { // extended prefix
+	  pilot0 = 4;
+	  pilot1 = 7;
+	  pilot2 = 10;
+  }
+
+  //define the filter
+  pil_offset = (uespec_nushift+uespec_poffset)%3;
+  // printf("symbol=%d,pil_offset=%d\n",symbol,pil_offset);
+  switch (pil_offset) {
+	  case 0:
+		  fl = filt16_l0;
+		  fm = filt16_m0;
+		  fr = filt16_r0;
+		  fl_dc = filt16_l0;
+		  fm_dc = filt16_m0;
+		  fr_dc = filt16_r0;
+		  f1 = filt16_1;
+		  f2l = filt16_2l0;
+		  f2r = filt16_2r0;
       break;
 
     case 1:
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
index e50af7cdd8f..d221348b44f 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -657,35 +657,35 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
     }
   }
 
-  void (*idft)(int16_t *,int16_t *, int);
+  idft_size_idx_t idftsizeidx;
 
   switch (ue->frame_parms.ofdm_symbol_size) {
     case 128:
-      idft = idft128;
-      break;
-
-    case 256:
-      idft = idft256;
-      break;
-
-    case 512:
-      idft = idft512;
-      break;
-
-    case 1024:
-      idft = idft1024;
-      break;
-
-    case 1536:
-      idft = idft1536;
-      break;
-
-    case 2048:
-      idft = idft2048;
-      break;
-
-    default:
-      idft = idft512;
+      idftsizeidx = IDFT_128;
+      break;        
+                    
+    case 256:       
+      idftsizeidx = IDFT_256;
+      break;        
+                    
+    case 512:       
+      idftsizeidx = IDFT_512;
+      break;        
+                    
+    case 1024:      
+      idftsizeidx = IDFT_1024;
+      break;       
+                   
+    case 1536:     
+      idftsizeidx = IDFT_1536;
+      break;        
+                    
+    case 2048:      
+      idftsizeidx = IDFT_2048;
+      break;        
+                    
+    default:        
+      idftsizeidx = IDFT_512;
       break;
   }
 
@@ -695,7 +695,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
       for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
         if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx]) {
           //LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
-          idft((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
+          idft(idftsizeidx,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
                (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
         }
       }
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
index 6f917ee49c5..333a6f08665 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
@@ -724,31 +724,31 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
     if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa]) {
       switch (ue->frame_parms.N_RB_DL) {
         case 6:
-          idft128((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+          idft(IDFT_128,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
                   (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
                   1);
           break;
 
         case 25:
-          idft512((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+          idft(IDFT_512,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
                   (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
                   1);
           break;
 
         case 50:
-          idft1024((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+          idft(IDFT_1024,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
                    (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
                    1);
           break;
 
         case 75:
-          idft1536((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+          idft(IDFT_1536,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
                    (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
                    1);
           break;
 
         case 100:
-          idft2048((int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+          idft(IDFT_2048,(int16_t *) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
                    (int16_t *) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
                    1);
           break;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index 0c98bdc5a56..0d765a18b33 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -141,28 +141,28 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms )   // LTE_UE_COMMON *com
 
   switch (frame_parms->N_RB_DL) {
   case 6:
-    idft128((short*)syncF_tmp,          /// complex input
+    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 25:
-    idft512((short*)syncF_tmp,          /// complex input
+    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 50:
-    idft1024((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
 	    (short*)sync_tmp, /// complex output
 	    1);
     break;
     
   case 75:
-    idft1536((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
 	     (short*)sync_tmp,
 	     1); /// complex output
     break;
   case 100:
-    idft2048((short*)syncF_tmp,          /// complex input
+    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
 	     (short*)sync_tmp, /// complex output
 	     1);
     break;
@@ -189,28 +189,28 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms )   // LTE_UE_COMMON *com
 
   switch (frame_parms->N_RB_DL) {
   case 6:
-    idft128((short*)syncF_tmp,          /// complex input
+    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 25:
-    idft512((short*)syncF_tmp,          /// complex input
+    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 50:
-    idft1024((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
 	    (short*)sync_tmp, /// complex output
 	    1);
     break;
     
   case 75:
-    idft1536((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
 	     (short*)sync_tmp, /// complex output
 	     1);
     break;
   case 100:
-    idft2048((short*)syncF_tmp,          /// complex input
+    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
 	    (short*)sync_tmp, /// complex output
 	    1);
     break;
@@ -237,28 +237,28 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms )   // LTE_UE_COMMON *com
 
   switch (frame_parms->N_RB_DL) {
   case 6:
-    idft128((short*)syncF_tmp,          /// complex input
+    idft(IDFT_128,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 25:
-    idft512((short*)syncF_tmp,          /// complex input
+    idft(IDFT_512,(short*)syncF_tmp,          /// complex input
 	   (short*)sync_tmp, /// complex output
 	   1);
     break;
   case 50:
-    idft1024((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1024,(short*)syncF_tmp,          /// complex input
 	    (short*)sync_tmp, /// complex output
 	    1);
     break;
     
   case 75:
-    idft1536((short*)syncF_tmp,          /// complex input
+    idft(IDFT_1536,(short*)syncF_tmp,          /// complex input
 	     (short*)sync_tmp, /// complex output
 	     1);
     break;
   case 100:
-    idft2048((short*)syncF_tmp,          /// complex input
+    idft(IDFT_2048,(short*)syncF_tmp,          /// complex input
 	    (short*)sync_tmp, /// complex output
 	    1);
     break;
@@ -492,28 +492,28 @@ int ru_sync_time_init(RU_t *ru)   // LTE_UE_COMMON *common_vars
 
   switch (ru->frame_parms->N_RB_DL) {
   case 6:
-    idft128((int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+    idft(IDFT_128,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
 	    ru->dmrssync, /// complex output
 	    1);
     break;
   case 25:
-    idft512((int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+    idft(IDFT_512,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
 	    ru->dmrssync, /// complex output
 	    1);
     break;
   case 50:
-    idft1024((int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+    idft(IDFT_1024,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
 	    ru->dmrssync, /// complex output
 	    1);
     break;
      
   case 75:
-    idft1536((int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+    idft(IDFT_1536,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
 	     ru->dmrssync,
 	     1); /// complex output
     break;
   case 100:
-    idft2048((int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+    idft(IDFT_2048,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
 	     ru->dmrssync, /// complex output
 	     1);
     break;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
index de48a855df6..524b200e1a1 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
@@ -80,7 +80,7 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq)
     while (1) {
 
       //compute frequency-domain representation of 6144-sample chunk
-      dft6144((int16_t *)rxp,
+      dft(DFT_6144,(int16_t *)rxp,
               sp,1);
 
 
@@ -267,7 +267,7 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq)
         }
 
         // ifft, accumulate energy over two half-frames
-        idft256((int16_t*)autocorr0,(int16_t*)tmp_t,1);
+        idft(IDFT_256,(int16_t*)autocorr0,(int16_t*)tmp_t,1);
         /*
               if (i==12288) {
           sprintf(fname,"corr256F_%d.m",abs(f));
@@ -285,12 +285,12 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq)
         for (re=0; re<(256/4); re++)
           autocorr0_t[re] = _mm_add_epi32(autocorr0_t[re],_mm_madd_epi16(tmp_t[re],tmp_t[re]));
 
-        idft256((int16_t*)autocorr1,(int16_t*)tmp_t,1);
+        idft(IDFT_256,(int16_t*)autocorr1,(int16_t*)tmp_t,1);
 
         for (re=0; re<(256/4); re++)
           autocorr1_t[re] = _mm_add_epi32(autocorr1_t[re],_mm_madd_epi16(tmp_t[re],tmp_t[re]));
 
-        idft256((int16_t*)autocorr2,(int16_t*)tmp_t,1);
+        idft(IDFT_256,(int16_t*)autocorr2,(int16_t*)tmp_t,1);
 
         for (re=0; re<(256/4); re++)
           autocorr2_t[re] = _mm_add_epi32(autocorr2_t[re],_mm_madd_epi16(tmp_t[re],tmp_t[re]));
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index 2e4f3e60361..880c056578e 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -1029,7 +1029,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
   int N_RB_DL = frame_parms->N_RB_DL;
 
 
-  int rank_tm3_tm4;
+  int rank_tm3_tm4=-1;
 
 
   ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index cb001f9dc48..7caaf07406b 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -50,8 +50,11 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
   int32_t **ul_ch_estimates_time = (eNB!=NULL) ? pusch_vars->drs_ch_estimates_time : calibration->drs_ch_estimates_time;
   AssertFatal(ul_ch_estimates_time != NULL, "ul_ch_estimates_time is null\n");
   int32_t **rxdataF_ext = (eNB!=NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext;
-  int subframe = (eNB!=NULL) ? proc->subframe_rx : ru->proc.tti_rx;
-  uint8_t harq_pid;
+
+  int subframe = proc->subframe_rx;
+
+  uint8_t harq_pid; 
+
   int16_t delta_phase = 0;
   int16_t *ru1 = ru_90;
   int16_t *ru2 = ru_90;
@@ -246,25 +249,25 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
 
       switch(frame_parms->N_RB_DL) {
         case 6:
-          idft128((int16_t *) temp_in_ifft_0,
+          idft(IDFT_128,(int16_t *) temp_in_ifft_0,
                   (int16_t *) ul_ch_estimates_time[aa],
                   1);
           break;
 
         case 25:
-          idft512((int16_t *) temp_in_ifft_0,
+          idft(IDFT_512,(int16_t *) temp_in_ifft_0,
                   (int16_t *) ul_ch_estimates_time[aa],
                   1);
           break;
 
         case 50:
-          idft1024((int16_t *) temp_in_ifft_0,
+          idft(IDFT_1024,(int16_t *) temp_in_ifft_0,
                    (int16_t *) ul_ch_estimates_time[aa],
                    1);
           break;
 
         case 100:
-          idft2048((int16_t *) temp_in_ifft_0,
+          idft(IDFT_2048,(int16_t *) temp_in_ifft_0,
                    (int16_t *) ul_ch_estimates_time[aa],
                    1);
           break;
@@ -575,25 +578,25 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
 
       switch(frame_parms->N_RB_DL) {
         case 6:
-          idft128((int16_t *) temp_in_ifft_0,
+          idft(IDFT_128,(int16_t *) temp_in_ifft_0,
                   (int16_t *) ul_ch_estimates_time[aa],
                   1);
           break;
 
         case 25:
-          idft512((int16_t *) temp_in_ifft_0,
+          idft(IDFT_512,(int16_t *) temp_in_ifft_0,
                   (int16_t *) ul_ch_estimates_time[aa],
                   1);
           break;
 
         case 50:
-          idft1024((int16_t *) temp_in_ifft_0,
+          idft(IDFT_1024,(int16_t *) temp_in_ifft_0,
                    (int16_t *) ul_ch_estimates_time[aa],
                    1);
           break;
 
         case 100:
-          idft2048((int16_t *) temp_in_ifft_0,
+          idft(IDFT_2048,(int16_t *) temp_in_ifft_0,
                    (int16_t *) ul_ch_estimates_time[aa],
                    1);
           break;
diff --git a/openair1/PHY/LTE_REFSIG/mod_table.h b/openair1/PHY/LTE_REFSIG/mod_table.h
index 7bdc1f518f1..29ae9f4495d 100644
--- a/openair1/PHY/LTE_REFSIG/mod_table.h
+++ b/openair1/PHY/LTE_REFSIG/mod_table.h
@@ -19,9 +19,14 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __PHY_LTE_REFSIG_MOD_TABLE__H__
+#define __PHY_LTE_REFSIG_MOD_TABLE__H__
+
 #define MOD_TABLE_SIZE_SHORT 304
 #define MOD_TABLE_QPSK_OFFSET 1
 #define MOD_TABLE_16QAM_OFFSET 5
 #define MOD_TABLE_64QAM_OFFSET 21
 #define MOD_TABLE_PSS_OFFSET 85
 short mod_table[MOD_TABLE_SIZE_SHORT] = {0,0,768,768,768,-768,-768,768,-768,-768,343,343,343,1030,1030,343,1030,1030,343,-343,343,-1030,1030,-343,1030,-1030,-343,343,-343,1030,-1030,343,-1030,1030,-343,-343,-343,-1030,-1030,-343,-1030,-1030,503,503,503,168,168,503,168,168,503,838,503,1173,168,838,168,1173,838,503,838,168,1173,503,1173,168,838,838,838,1173,1173,838,1173,1173,503,-503,503,-168,168,-503,168,-168,503,-838,503,-1173,168,-838,168,-1173,838,-503,838,-168,1173,-503,1173,-168,838,-838,838,-1173,1173,-838,1173,-1173,-503,503,-503,168,-168,503,-168,168,-503,838,-503,1173,-168,838,-168,1173,-838,503,-838,168,-1173,503,-1173,168,-838,838,-838,1173,-1173,838,-1173,1173,-503,-503,-503,-168,-168,-503,-168,-168,-503,-838,-503,-1173,-168,-838,-168,-1173,-838,-503,-838,-168,-1173,-503,-1173,-168,-838,-838,-838,-1173,-1173,-838,-1173,-1173,1086,0,1081,-108,1065,-215,1038,-320,1001,-422,954,-519,897,-612,832,-698,758,-777,677,-849,589,-912,495,-966,397,-1011,294,-1046,189,-1070,81,-1083,-27,-1086,-135,-1078,-242,-1059,-346,-1030,-447,-990,-543,-941,-634,-882,-719,-814,-796,-739,-866,-656,-927,-566,-979,-471,-1021,-371,-1053,-268,-1074,-162,-1085,-54,-1085,54,-1074,162,-1053,268,-1021,371,-979,471,-927,566,-866,656,-796,739,-719,814,-634,882,-543,941,-447,990,-346,1030,-242,1059,-135,1078,-27,1086,81,1083,189,1070,294,1045,397,1011,495,966,589,912,677,849,758,777,832,698,897,612,954,519,1001,422,1038,320,1065,215,1081,108,16384,0,8192,0,4096,0,2048,0};
+
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 6595158f1a8..15eb5206a19 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -20,15 +20,15 @@
  */
 
 /*! \file PHY/LTE_TRANSPORT/dlsch_coding.c
-* \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
-* \author R. Knopp
-* \date 2011
-* \version 0.1
-* \company Eurecom
-* \email: knopp@eurecom.fr
-* \note
-* \warning
-*/
+ * \brief Top-level routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
+ * \author R. Knopp
+ * \date 2011
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
 
 #include "PHY/defs_eNB.h"
 #include "PHY/phy_extern.h"
@@ -42,22 +42,23 @@
 #include "common/utils/LOG/log.h"
 #include "targets/RT/USER/lte-softmodem.h"
 #include <syscall.h>
-#include "executables/thread-common.h"
+#include "targets/RT/USER/rt_wrapper.h"
+#include <common/utils/threadPool/thread-pool.h>
 
 //#define DEBUG_DLSCH_CODING
 //#define DEBUG_DLSCH_FREE 1
 
 /*
-#define is_not_pilot(pilots,first_pilot,re) (pilots==0) || \
+  #define is_not_pilot(pilots,first_pilot,re) (pilots==0) || \
   ((pilots==1)&&(first_pilot==1)&&(((re>2)&&(re<6))||((re>8)&&(re<12)))) || \
   ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
 */
 #define is_not_pilot(pilots,first_pilot,re) (1)
 /*extern void thread_top_init(char *thread_name,
-         int affinity,
-         uint64_t runtime,
-         uint64_t deadline,
-         uint64_t period);*/
+  int affinity,
+  uint64_t runtime,
+  uint64_t deadline,
+  uint64_t period);*/
 
 extern volatile int oai_exit;
 
@@ -83,11 +84,6 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) {
             free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
             dlsch->harq_processes[i]->c[r] = NULL;
           }
-
-          if (dlsch->harq_processes[i]->d[r]) {
-            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));
@@ -108,26 +104,26 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
                                LTE_DL_FRAME_PARMS *frame_parms)
 {
   LTE_eNB_DLSCH_t *dlsch;
-  unsigned char exit_flag = 0,i,j,r,aa,layer;
+  unsigned char exit_flag = 0,i,r,aa,layer;
   int re;
   unsigned char bw_scaling =1;
 
   switch (N_RB_DL) {
-    case 6:
-      bw_scaling =16;
-      break;
+  case 6:
+    bw_scaling =16;
+    break;
 
-    case 25:
-      bw_scaling =4;
-      break;
+  case 25:
+    bw_scaling =4;
+    break;
 
-    case 50:
-      bw_scaling =2;
-      break;
+  case 50:
+    bw_scaling =2;
+    break;
 
-    default:
-      bw_scaling =1;
-      break;
+  default:
+    bw_scaling =1;
+    break;
   }
 
   dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t));
@@ -153,11 +149,11 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
 
     // NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!!
     /*
-     dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
-     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-       dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
+      dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
+      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+      dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
 
-       }*/
+      }*/
 
     for (i=0; i<20; i++)
       dlsch->harq_ids[i/10][i%10] = Mdlharq;
@@ -183,7 +179,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
           for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
             // account for filler in first segment and CRCs for multiple segment case
             dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768);
-            dlsch->harq_processes[i]->d[r] = (uint8_t *)malloc16((96+12+3+(3*6144)));
 
             if (dlsch->harq_processes[i]->c[r]) {
               bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
@@ -191,13 +186,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
               printf("Can't get c\n");
               exit_flag=2;
             }
-
-            if (dlsch->harq_processes[i]->d[r]) {
-              bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
-            } else {
-              printf("Can't get d\n");
-              exit_flag=2;
-            }
           }
         }
       } else {
@@ -209,13 +197,6 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
     if (exit_flag==0) {
       for (i=0; i<Mdlharq; i++) {
         dlsch->harq_processes[i]->round=0;
-
-        for (j=0; j<96; j++)
-          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
-            //      printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]);
-            if (dlsch->harq_processes[i]->d[r])
-              dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
-          }
       }
 
       return(dlsch);
@@ -231,7 +212,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,
 
 void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
   unsigned char Mdlharq;
-  unsigned char i,j,r;
+  unsigned char i;
 
   if (dlsch) {
     Mdlharq = dlsch->Mdlharq;
@@ -255,307 +236,17 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
         dlsch->harq_processes[i]->status = 0;
         dlsch->harq_processes[i]->round  = 0;
 
-        for (j=0; j<96; j++)
-          for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
-            if (dlsch->harq_processes[i]->d[r])
-              dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
       }
     }
   }
 }
 
-
-int dlsch_encoding_2threads0(te_params *tep) {
-  LTE_eNB_DLSCH_t *dlsch          = tep->dlsch;
-  unsigned int G                  = tep->G;
-  unsigned char harq_pid          = tep->harq_pid;
-  unsigned int total_worker       = tep->total_worker;
-  unsigned int current_worker     = tep->current_worker;
-  unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
-  unsigned int Kr=0,Kr_bytes,r,r_offset=0;
-  //  unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN);
-
-  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-    for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
-      if (r<dlsch->harq_processes[harq_pid]->Cminus)
-        Kr = dlsch->harq_processes[harq_pid]->Kminus;
-      else
-        Kr = dlsch->harq_processes[harq_pid]->Kplus;
-
-      Kr_bytes = Kr>>3;
-      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
-             );
-      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]);
-    }
-  }
-
-  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
-  // outputs for each code segment, see Section 5.1.5 p.20
-
-  for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) {
-    if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)) {
-      int Nl=dlsch->harq_processes[harq_pid]->Nl;
-      int Qm=dlsch->harq_processes[harq_pid]->Qm;
-      int C = dlsch->harq_processes[harq_pid]->C;
-      int Gp = G/Nl/Qm;
-      int GpmodC = Gp%C;
-
-      if (r < (C-(GpmodC)))
-        r_offset += Nl*Qm * (Gp/C);
-      else
-        r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
-    } else {
-      r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
-                                          G,  //G
-                                          dlsch->harq_processes[harq_pid]->w[r],
-                                          dlsch->harq_processes[harq_pid]->e+r_offset,
-                                          dlsch->harq_processes[harq_pid]->C, // C
-                                          dlsch->Nsoft,                    // Nsoft,
-                                          dlsch->Mdlharq,
-                                          dlsch->Kmimo,
-                                          dlsch->harq_processes[harq_pid]->rvidx,
-                                          dlsch->harq_processes[harq_pid]->Qm,
-                                          dlsch->harq_processes[harq_pid]->Nl,
-                                          r,
-                                          nb_rb);
-      //                                        m);                       // r
-    }
-  }
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);
-  return(0);
-}
-
-
 void *te_thread(void *param) {
-  te_params *tep                 = (te_params *)param;
-
-  //wait_sync("te_thread");
-
-  while (!oai_exit) {
-    if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break;
-
-    if(oai_exit) break;
-
-    dlsch_encoding_2threads0(tep);
-
-    if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break;
-
-    if (pthread_cond_signal(&tep->cond_te) != 0) {
-      printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-      return(NULL);
-    }
-
-    /*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){
-      print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr);
-      printf("te_thread0 delay for waking up in frame_rx: %d  subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
-    }*/
-  }
-
   return(NULL);
 }
 
-
-int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
-                            unsigned char *a,
-                            uint8_t num_pdcch_symbols,
-                            LTE_eNB_DLSCH_t *dlsch,
-                            int frame,
-                            uint8_t subframe,
-                            time_stats_t *rm_stats,
-                            time_stats_t *te_stats,
-                            time_stats_t *te_wait_stats,
-                            time_stats_t *te_main_stats,
-                            time_stats_t *te_wakeup_stats0,
-                            time_stats_t *te_wakeup_stats1,
-                            time_stats_t *i_stats,
-                            int worker_num) {
-  //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
-  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
-  L1_proc_t *proc = &eNB->proc;
-  unsigned int G;
-  unsigned int crc=1;
-  unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
-  if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
-    LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
-    return(-1);
-  }
-
-  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;
-  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
-  mod_order = dlsch->harq_processes[harq_pid]->Qm;
-  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,
-            dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
-
-  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-    start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
-    // Add 24-bit crc (polynomial A) to payload
-    crc = crc24a(a,
-                 A)>>8;
-    stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
-    a[A>>3] = ((uint8_t *)&crc)[2];
-    a[1+(A>>3)] = ((uint8_t *)&crc)[1];
-    a[2+(A>>3)] = ((uint8_t *)&crc)[0];
-    dlsch->harq_processes[harq_pid]->B = A+24;
-    memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
-    //stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
-    start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
-
-    if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
-                         dlsch->harq_processes[harq_pid]->c,
-                         dlsch->harq_processes[harq_pid]->B,
-                         &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);
-
-    stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
-    start_meas(&eNB->dlsch_turbo_encoding_signal_stats);
-
-    for(int i=0; i<worker_num; i++) {
-      proc->tep[i].eNB               = eNB;
-      proc->tep[i].dlsch             = dlsch;
-      proc->tep[i].G                 = G;
-      proc->tep[i].harq_pid          = harq_pid;
-      proc->tep[i].total_worker      = worker_num;
-      proc->tep[i].current_worker    = i;
-      pthread_mutex_lock( &proc->tep[i].mutex_te );
-
-      if (proc->tep[i].instance_cnt_te==0) {
-        printf("[eNB] TE thread busy\n");
-        exit_fun("TE thread busy");
-        pthread_mutex_unlock( &proc->tep[i].mutex_te );
-        return(-1);
-      }
-
-      ++proc->tep[i].instance_cnt_te;
-
-      // wakeup worker to do segments
-      if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
-        printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i);
-        exit_fun( "ERROR pthread_cond_signal" );
-        return (-1);
-      }
-
-      pthread_mutex_unlock( &proc->tep[i].mutex_te );
-    }
-
-    stop_meas(&eNB->dlsch_turbo_encoding_signal_stats);
-    start_meas(te_main_stats);
-
-    for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) {
-      if (r<dlsch->harq_processes[harq_pid]->Cminus)
-        Kr = dlsch->harq_processes[harq_pid]->Kminus;
-      else
-        Kr = dlsch->harq_processes[harq_pid]->Kplus;
-
-      Kr_bytes = Kr>>3;
-      start_meas(te_stats);
-      encoder(dlsch->harq_processes[harq_pid]->c[r],
-              Kr>>3,
-              &dlsch->harq_processes[harq_pid]->d[r][96],
-              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0
-             );
-      stop_meas(te_stats);
-      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);
-    }
-  } else {
-    for(int i=0; i<worker_num; i++) {
-      proc->tep[i].eNB               = eNB;
-      proc->tep[i].dlsch             = dlsch;
-      proc->tep[i].G                 = G;
-      proc->tep[i].total_worker      = worker_num;
-      proc->tep[i].current_worker    = i;
-
-      if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
-        printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
-        exit_fun( "ERROR pthread_cond_signal" );
-        return (-1);
-      }
-    }
-  }
-
-  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
-  // outputs for each code segment, see Section 5.1.5 p.20
-  for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
-    // get information for E for the segments that are handled by the worker thread
-    if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) {
-      int Nl=dlsch->harq_processes[harq_pid]->Nl;
-      int Qm=dlsch->harq_processes[harq_pid]->Qm;
-      int C = dlsch->harq_processes[harq_pid]->C;
-      int Gp = G/Nl/Qm;
-      int GpmodC = Gp%C;
-
-      if (r < (C-(GpmodC)))
-        r_offset += Nl*Qm * (Gp/C);
-      else
-        r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
-    } else  {
-      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,
-                                          dlsch->harq_processes[harq_pid]->Qm,
-                                          dlsch->harq_processes[harq_pid]->Nl,
-                                          r,
-                                          nb_rb);
-      //            m);                       // r
-      stop_meas(rm_stats);
-    }
-  }
-
-  stop_meas(te_main_stats);
-  start_meas(te_wait_stats);
-
-  if(worker_num == 1) {
-    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
-  } else if(worker_num == 2) {
-    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
-    wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
-  } else {
-    wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
-    wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
-    wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2");
-  }
-
-  stop_meas(te_wait_stats);
-  /*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){
-    print_meas_now(te_wait_stats,"coding_wait",stderr);
-  printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
-  }*/
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
-  return(0);
-}
-
-
 int dlsch_encoding_all(PHY_VARS_eNB *eNB,
+		       L1_rxtx_proc_t *proc,
                        unsigned char *a,
                        uint8_t num_pdcch_symbols,
                        LTE_eNB_DLSCH_t *dlsch,
@@ -568,108 +259,72 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                        time_stats_t *te_wakeup_stats0,
                        time_stats_t *te_wakeup_stats1,
                        time_stats_t *i_stats) {
-  int encoding_return = 0;
-  unsigned int L,C,B;
   uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe];
   if(harq_pid >= dlsch->Mdlharq) {
     LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid);
     return(-1);
   }
-  B = dlsch->harq_processes[harq_pid]->B;
+  
+  LOG_D(PHY,"B %d, harq_pid %d\n",
+	dlsch->harq_processes[harq_pid]->B,
+	dlsch->harq_ids[frame%2][subframe]);
+
+  return dlsch_encoding(eNB,
+			proc,
+			a,
+			num_pdcch_symbols,
+			dlsch,
+			frame,
+			subframe,
+			rm_stats,
+			te_stats,
+			i_stats);
 
-  LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]);
-
-  if(B<=6144) {
-    L=0;
-    C=1;
-  } else {
-    L=24;
-    C = B/(6144-L);
-
-    if((6144-L)*C < B) {
-      C = C+1;
-    }
-  }
+}
 
-  if(get_thread_worker_conf() == WORKER_ENABLE) {
-    if(C >= 8) { //one main three worker
-      encoding_return =
-        dlsch_encoding_2threads(eNB,
-                                a,
-                                num_pdcch_symbols,
-                                dlsch,
-                                frame,
-                                subframe,
-                                rm_stats,
-                                te_stats,
-                                te_wait_stats,
-                                te_main_stats,
-                                te_wakeup_stats0,
-                                te_wakeup_stats1,
-                                i_stats,
-                                3);
-    } else if(C >= 6) { //one main two worker
-      encoding_return =
-        dlsch_encoding_2threads(eNB,
-                                a,
-                                num_pdcch_symbols,
-                                dlsch,
-                                frame,
-                                subframe,
-                                rm_stats,
-                                te_stats,
-                                te_wait_stats,
-                                te_main_stats,
-                                te_wakeup_stats0,
-                                te_wakeup_stats1,
-                                i_stats,
-                                2);
-    } else if(C >= 4) { //one main one worker
-      encoding_return =
-        dlsch_encoding_2threads(eNB,
-                                a,
-                                num_pdcch_symbols,
-                                dlsch,
-                                frame,
-                                subframe,
-                                rm_stats,
-                                te_stats,
-                                te_wait_stats,
-                                te_main_stats,
-                                te_wakeup_stats0,
-                                te_wakeup_stats1,
-                                i_stats,
-                                1);
-    } else {
-      encoding_return =
-        dlsch_encoding(eNB,
-                       a,
-                       num_pdcch_symbols,
-                       dlsch,
-                       frame,
-                       subframe,
-                       rm_stats,
-                       te_stats,
-                       i_stats);
-    }
-  } else {
-    encoding_return =
-      dlsch_encoding(eNB,
-                     a,
-                     num_pdcch_symbols,
-                     dlsch,
-                     frame,
-                     subframe,
-                     rm_stats,
-                     te_stats,
-                     i_stats);
+static void TPencode(void * arg) {
+  turboEncode_t * rdata=(turboEncode_t *) arg;
+  unsigned char harq_pid = rdata->harq_pid;
+  LTE_DL_eNB_HARQ_t *hadlsch=rdata->dlsch->harq_processes[harq_pid];
+  
+  if ( rdata-> round == 0) {
+    uint8_t tmp[96+12+3+3*6144];
+    memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS);
+    start_meas(rdata->te_stats);
+    encoder(rdata->input,
+	    rdata->Kr_bytes,
+	    tmp+96,//&dlsch->harq_processes[harq_pid]->d[r][96],
+	    rdata->filler);
+    stop_meas(rdata->te_stats);
+    start_meas(rdata->i_stats);
+    hadlsch->RTC[rdata->r] =
+      sub_block_interleaving_turbo(4+(rdata->Kr_bytes*8),
+				   tmp+96,
+				   hadlsch->w[rdata->r]);
+    stop_meas(rdata->i_stats);
   }
-
-  return encoding_return;
+  
+  // 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
+    start_meas(rdata->rm_stats);
+  lte_rate_matching_turbo(hadlsch->RTC[rdata->r],
+			  rdata->G,  //G
+			  hadlsch->w[rdata->r],
+			  hadlsch->eDL+rdata->r_offset,
+			  hadlsch->C, // C
+			  rdata->dlsch->Nsoft,                    // Nsoft,
+			  rdata->dlsch->Mdlharq,
+			  rdata->dlsch->Kmimo,
+			  hadlsch->rvidx,
+			  hadlsch->Qm,
+			  hadlsch->Nl,
+			  rdata->r,
+			  hadlsch->nb_rb);
+    stop_meas(rdata->rm_stats);
 }
 
-
 int dlsch_encoding(PHY_VARS_eNB *eNB,
+                   L1_rxtx_proc_t *proc,
                    unsigned char *a,
                    uint8_t num_pdcch_symbols,
                    LTE_eNB_DLSCH_t *dlsch,
@@ -678,8 +333,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
                    time_stats_t *rm_stats,
                    time_stats_t *te_stats,
                    time_stats_t *i_stats) {
-  unsigned int G;
-  unsigned int crc=1;
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
   unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
   if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
@@ -687,135 +340,88 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
     return(-1);
   }
 
-  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;
+  LTE_DL_eNB_HARQ_t *hadlsch=dlsch->harq_processes[harq_pid];
   uint8_t beamforming_mode=0;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
-  A = dlsch->harq_processes[harq_pid]->TBS; //6228
-  // printf("Encoder: A: %d\n",A);
-  mod_order = dlsch->harq_processes[harq_pid]->Qm;
 
-  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
+  if(hadlsch->mimo_mode == TM7)
     beamforming_mode = 7;
-  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
+  else if(hadlsch->mimo_mode == TM8)
     beamforming_mode = 8;
-  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
+  else if(hadlsch->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);
+  unsigned int G = get_G(frame_parms,hadlsch->nb_rb,
+	    hadlsch->rb_alloc,
+	    hadlsch->Qm, // mod order
+	    hadlsch->Nl,
+	    num_pdcch_symbols,
+	    frame,subframe,beamforming_mode);
 
-  //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
-  if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-#ifdef DEBUG_DLSCH_CODING
-    printf("encoding thinks this is a new packet for harq_pid %d (%p), A %u \n",harq_pid,dlsch,A);
-#endif
-    /*
-    int i;
-    printf("dlsch (tx): \n");
-    for (i=0;i<(A>>3);i++)
-      printf("%02x.",a[i]);
-    printf("\n");
-    */
+  proc->nbEncode=0;
+
+  //  if (hadlsch->Ndi == 1) {  // this is a new packet
+  if (hadlsch->round == 0) {  // this is a new packet
     // Add 24-bit crc (polynomial A) to payload
-    crc = crc24a(a,
+    unsigned int A=hadlsch->TBS; //6228;
+    unsigned int 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)
+    hadlsch->B = A+24;
+    //    hadlsch->b = a;
+    memcpy(hadlsch->b,a,(A/8)+4);
+    
+    if (lte_segmentation(hadlsch->b,
+                         hadlsch->c,
+                         hadlsch->B,
+                         &hadlsch->C,
+                         &hadlsch->Cplus,
+                         &hadlsch->Cminus,
+                         &hadlsch->Kplus,
+                         &hadlsch->Kminus,
+                         &hadlsch->F)<0)
       return(-1);
-
-    for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
-      if (r<dlsch->harq_processes[harq_pid]->Cminus)
-        Kr = dlsch->harq_processes[harq_pid]->Kminus;
-      else
-        Kr = dlsch->harq_processes[harq_pid]->Kplus;
-
-      Kr_bytes = Kr>>3;
-#ifdef DEBUG_DLSCH_CODING
-      printf("Generating Code Segment %u (%u bits)\n",r,Kr);
-      // generate codewords
-      printf("bits_per_codeword (Kr)= %u, A %u\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
-      start_meas(te_stats);
-      encoder(dlsch->harq_processes[harq_pid]->c[r],
-              Kr>>3,
-              &dlsch->harq_processes[harq_pid]->d[r][96],
-              (r==0) ? dlsch->harq_processes[harq_pid]->F : 0
-             );
-      stop_meas(te_stats);
-#ifdef DEBUG_DLSCH_CODING
-
-      if (r==0)
-        LOG_M("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);
-
-#endif
-      start_meas(i_stats);
-      dlsch->harq_processes[harq_pid]->RTC[r] =
-        sub_block_interleaving_turbo(4+(Kr_bytes*8),
-                                     &dlsch->harq_processes[harq_pid]->d[r][96],
-                                     dlsch->harq_processes[harq_pid]->w[r]);
-      stop_meas(i_stats);
-    }
   }
-
-  // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
-  // outputs for each code segment, see Section 5.1.5 p.20
-
-  for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
-#ifdef DEBUG_DLSCH_CODING
-    printf("Rate Matching, Code segment %u (coded bits (G) %u,unpunctured/repeated bits per code segment %u,mod_order %d, nb_rb %d)...\n",
-           r,
-           G,
-           Kr*3,
-           mod_order,nb_rb);
-#endif
-    start_meas(rm_stats);
-#ifdef DEBUG_DLSCH_CODING
-    printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
-#endif
-    r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
-                                        G,  //G
-                                        dlsch->harq_processes[harq_pid]->w[r],
-                                        dlsch->harq_processes[harq_pid]->e+r_offset,
-                                        dlsch->harq_processes[harq_pid]->C, // C
-                                        dlsch->Nsoft,                    // Nsoft,
-                                        dlsch->Mdlharq,
-                                        dlsch->Kmimo,
-                                        dlsch->harq_processes[harq_pid]->rvidx,
-                                        dlsch->harq_processes[harq_pid]->Qm,
-                                        dlsch->harq_processes[harq_pid]->Nl,
-                                        r,
-                                        nb_rb);
-    //                                        m);                       // r
-    stop_meas(rm_stats);
-#ifdef DEBUG_DLSCH_CODING
-
-    if (r==dlsch->harq_processes[harq_pid]->C-1)
-      LOG_M("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
-
-#endif
+ 
+  for (int r=0, r_offset=0; r<hadlsch->C; r++) {
+    
+    union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
+    notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
+    turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
+    rdata->input=hadlsch->c[r];
+    rdata->Kr_bytes= ( r<hadlsch->Cminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
+    rdata->filler=(r==0) ? hadlsch->F : 0;
+    rdata->r=r;
+    rdata->harq_pid=harq_pid;
+    rdata->dlsch=dlsch;
+    rdata->rm_stats=rm_stats;
+    rdata->te_stats=te_stats;
+    rdata->i_stats=i_stats;
+    rdata->round=hadlsch->round;
+    rdata->r_offset=r_offset;
+    rdata->G=G;
+    
+    if (  proc->threadPool->activated ) {
+      pushTpool(proc->threadPool,req);
+      proc->nbEncode++;
+    } else {
+      TPencode(rdata);
+      delNotifiedFIFO_elt(req);
+    }
+    
+    int Qm=hadlsch->Qm;
+    int C=hadlsch->C;
+    int Nl=hadlsch->Nl;
+    int Gp = G/Nl/Qm;
+    int GpmodC = Gp%C;
+    if (r < (C-(GpmodC)))
+      r_offset += Nl*Qm * (Gp/C);
+    else
+      r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
   }
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
   return(0);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index 04a49d062a3..475c8bd521d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -158,7 +158,7 @@ int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
 {
 
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qpsk_table_offset_re = 0;
   uint32_t qpsk_table_offset_im = 0;
 
@@ -248,7 +248,7 @@ int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
 
   LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
 
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qpsk_table_offset_re = 0;
   uint32_t qpsk_table_offset_im = 0;
 
@@ -343,7 +343,7 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 {
 
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qam16_table_offset_re = 0;
   uint32_t qam16_table_offset_im = 0;
 
@@ -439,7 +439,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 
   LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
 
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qam16_table_offset_re = 0;
   uint32_t qam16_table_offset_im = 0;
 
@@ -542,7 +542,7 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
 
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qam64_table_offset_re = 0;
   uint32_t qam64_table_offset_im = 0;
 
@@ -699,7 +699,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 
   LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
 
-  uint8_t *x0             = dlsch0_harq->e;
+  uint8_t *x0             = dlsch0_harq->eDL;
   uint32_t qam64_table_offset_re = 0;
   uint32_t qam64_table_offset_im = 0;
 
@@ -866,12 +866,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
 
   if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
 
-    x0 = dlsch0_harq->e;
+    x0 = dlsch0_harq->eDL;
     mimo_mode = dlsch0_harq->mimo_mode;
     first_layer0 = dlsch0_harq->first_layer;
     Nlayers0 = dlsch0_harq->Nlayers;
     mod_order0 = dlsch0_harq->Qm;
-    x1             = dlsch1_harq->e;
+    x1             = dlsch1_harq->eDL;
     // Fill these in later for TM8-10
     //    Nlayers1       = dlsch1_harq->Nlayers;
     //    first_layer1   = dlsch1_harq->first_layer;
@@ -879,7 +879,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
 
   } else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc
 
-    x0 = dlsch0_harq->e;
+    x0 = dlsch0_harq->eDL;
     mimo_mode = dlsch0_harq->mimo_mode;
     first_layer0 = dlsch0_harq->first_layer;
     Nlayers0 = dlsch0_harq->Nlayers;
@@ -887,7 +887,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
 
   } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission
 
-    x0 = dlsch1_harq->e;
+    x0 = dlsch1_harq->eDL;
     mimo_mode = dlsch1_harq->mimo_mode;
     first_layer0 = dlsch1_harq->first_layer;
     Nlayers0 = dlsch1_harq->Nlayers;
@@ -2692,7 +2692,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer,
   LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
   uint32_t i,jj,re_allocated=0;
   uint8_t mod_order0 = dlsch0_harq->Qm;
-  uint8_t *x0  = dlsch0_harq->e;
+  uint8_t *x0  = dlsch0_harq->eDL;
   uint8_t qam64_table_offset_re = 0;
   uint8_t qam64_table_offset_im = 0;
   uint8_t qam16_table_offset_re = 0;
@@ -2883,7 +2883,7 @@ int mch_modulation(int32_t **txdataF,
                              &jj,
                              re_offset,
                              symbol_offset,
-                             dlsch->harq_processes[0]->e,
+                             dlsch->harq_processes[0]->eDL,
                              l,
                              mod_order,
                              amp,
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index 2e8ddde8488..d48164e07d6 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -52,7 +52,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   int n;
   //  uint8_t reset;
   uint32_t x1, x2, s=0;
-  uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->e;
+  uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->eDL;
   uint8_t *e=dlsch_e;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
   // Rule for accumulation of subframes for BL/CE UEs
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h b/openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h
index 9673ba15b50..5a08b7a4023 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h
@@ -19,6 +19,9 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __DLSCH_TBS_FULL__H__
+#define __DLSCH_TBS_FULL__H__
+
 #define TBStable_rowCnt 27
 
 /** \brief "Transport block size table"
@@ -54,3 +57,4 @@ unsigned int TBStable[TBStable_rowCnt][110] = {{16,32,56,88,120,152,176,208,224,
 };
 
 unsigned int TBStable1C[32] = {40, 56, 72, 120, 136, 144, 176, 208, 224, 256, 280, 296, 328, 336, 392, 488, 552, 600, 632, 696, 776, 840, 904, 1000, 1064, 1128, 1224, 1288, 1384, 1480, 1608, 1736};
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.h b/openair1/PHY/LTE_TRANSPORT/if5_tools.h
index 0f24f7becee..6c75b20bd96 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.h
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.h
@@ -61,7 +61,8 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t;
 
 void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t);
 
-void recv_IF5(RU_t *, openair0_timestamp*, int, uint16_t);
+void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type);
+
 
 void malloc_IF5_buffer(RU_t *ru);
 
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
index c13876f29a3..6144b978bf4 100644
--- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
+++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -94,6 +94,35 @@ unsigned char I_TBS2I_MCS(unsigned char I_TBS) {
   return I_MCS;
 }
 
+uint16_t find_nb_rb_DL(uint8_t mcs, uint32_t bytes, uint16_t nb_rb_max, uint16_t rb_gran) {
+  if (bytes == 0 || mcs > 28 || nb_rb_max == 0)
+    return 0;
+  const uint32_t bits = bytes << 3;
+  const unsigned char I_TBS = get_I_TBS(mcs);
+
+  uint32_t TBS = TBStable[I_TBS][nb_rb_max - 1];
+  if (bits >= TBS)     // is nb_rb_max too small?
+    return nb_rb_max;
+
+  TBS = TBStable[I_TBS][rb_gran - 1];
+  if (bits <= TBS)     // is rb_gran RB enough?
+    return rb_gran;
+
+  nb_rb_max += nb_rb_max % rb_gran; // round up to full RBG
+  uint16_t hi = nb_rb_max/rb_gran - 1;
+  uint16_t lo = 0;
+  uint16_t p = (hi + lo) / 2;
+  for (; lo + 1 != hi; p = (hi + lo) / 2) {
+    const uint16_t rbi = (p + 1) * rb_gran - 1;  // convert "RBG" -> RB
+    TBS = TBStable[I_TBS][rbi];
+    if (bits <= TBS)  // need less RBs
+      hi = p;
+    else              // need more RBs
+      lo = p;
+  }
+  return (hi + 1) * rb_gran;
+}
+
 uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb) {
   uint32_t TBS;
 
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index ab2fe2d743b..6d8b58818b1 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -714,7 +714,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
   int32_t **txdataF = eNB->common_vars.txdataF;
   uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH;
   uint8_t NSF_PHICH = 4;
-  uint8_t pusch_subframe;
+  uint8_t pusch_subframe=-1;
   uint8_t i;
   int subframe = proc->subframe_tx;
   phich_config_t *phich;
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index f48ee629a1e..90e2836b1e7 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -105,6 +105,7 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
   AssertFatal(eNB->dlsch_MCH->harq_processes[0]->pdu != NULL, "attempt to encode a NULL harq PDU\n");
   
   AssertFatal(dlsch_encoding(eNB,
+			     proc,
 			    // a,
 			    eNB->dlsch_MCH->harq_processes[0]->pdu,
 			     1,
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index 3471f98af79..24faf584d3a 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -38,9 +38,13 @@
 #include "SCHED/sched_eNB.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "prach_extern.h"
+#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
+#include <executables/split_headers.h>
 
 void rx_prach0(PHY_VARS_eNB *eNB,
                RU_t *ru,
+	       int frame_prach,
+	       int subframe,
                uint16_t *max_preamble,
                uint16_t *max_preamble_energy,
                uint16_t *max_preamble_delay,
@@ -51,17 +55,14 @@ void rx_prach0(PHY_VARS_eNB *eNB,
                uint8_t ce_level
               ) {
   int i;
-  LTE_DL_FRAME_PARMS *fp=NULL;
   lte_frame_type_t   frame_type;
   uint16_t           rootSequenceIndex;
   uint8_t            prach_ConfigIndex;
   uint8_t            Ncs_config;
   uint8_t            restricted_set;
   uint8_t            n_ra_prb;
-  int                subframe;
   int16_t            *prachF=NULL;
   int16_t            **rxsigF=NULL;
-  int                nb_rx=0;
   int16_t *prach2;
   uint8_t preamble_index;
   uint16_t NCS,NCS2;
@@ -89,6 +90,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   int32_t **prach_ifftp=(int32_t **)NULL;
   int prach_ifft_cnt=0;
 
+  LTE_DL_FRAME_PARMS *fp;
+  int nb_rx;
   if(eNB)  {
     fp    = &(eNB->frame_parms);
     nb_rx = fp->nb_antennas_rx;
@@ -96,7 +99,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     fp    = (ru->frame_parms);
     nb_rx = ru->nb_rx;
   }
-
+  
   AssertFatal(fp!=NULL,"rx_prach called without valid RU or eNB descriptor\n");
   frame_type          = fp->frame_type;
 
@@ -133,14 +136,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   if (eNB) {
     if (br_flag == 1) {
       prach_ifftp         = eNB->prach_vars_br.prach_ifft[ce_level];
-      subframe            = eNB->proc.subframe_prach_br;
       prachF              = eNB->prach_vars_br.prachF;
       rxsigF              = eNB->prach_vars_br.rxsigF[ce_level];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,
+        if (((frame_prach)&1023) < 20) LOG_I(PHY,
               "PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
-              br_flag,ce_level,eNB->proc.frame_prach,subframe,
+              br_flag,ce_level,frame_prach,subframe,
               fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
               prach_ConfigIndex,rootSequenceIndex,
               eNB->prach_vars_br.repetition_number[ce_level],
@@ -148,30 +150,27 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       }
     } else {
       prach_ifftp       = eNB->prach_vars.prach_ifft[0];
-      subframe          = eNB->proc.subframe_prach;
       prachF            = eNB->prach_vars.prachF;
       rxsigF            = eNB->prach_vars.rxsigF[0];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
+        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,
               fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
       }
     }
   } else {
     if (br_flag == 1) {
-      subframe          = ru->proc.subframe_prach_br;
       rxsigF            = ru->prach_rxsigF_br[ce_level];
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
-              br_flag,ce_level,ru->proc.frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
+        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
+              br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
       }
     } else {
-      subframe          = ru->proc.subframe_prach;
       rxsigF            = ru->prach_rxsigF;
 
       if (LOG_DEBUGFLAG(PRACH)) {
-        if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
+        if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
               subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
       }
     }
@@ -202,7 +201,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
           if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
 
           LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
-                ru->idx,br_flag,ce_level,ru->proc.frame_prach,subframe,fp->samples_per_tti,
+                ru->idx,br_flag,ce_level,frame_prach,subframe,fp->samples_per_tti,
                 prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
                 (subframe*fp->samples_per_tti)-ru->N_TA_offset);
         }
@@ -298,24 +297,24 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       switch (fp->N_RB_UL) {
         case 6:
           if (prach_fmt == 4) {
-            dft256(prach2,rxsigF[aa],1);
+            dft(DFT_256,prach2,rxsigF[aa],1);
           } else {
-            dft1536(prach2,rxsigF[aa],1);
+            dft(DFT_1536,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
-              dft1536(prach2+3072,rxsigF[aa]+3072,1);
+              dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
           }
 
           break;
 
         case 15:
           if (prach_fmt == 4) {
-            dft256(prach2,rxsigF[aa],1);
+            dft(DFT_256,prach2,rxsigF[aa],1);
           } else {
-            dft3072(prach2,rxsigF[aa],1);
+            dft(DFT_3072,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
-              dft3072(prach2+6144,rxsigF[aa]+6144,1);
+              dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
           }
 
           break;
@@ -323,13 +322,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 25:
         default:
           if (prach_fmt == 4) {
-            dft1024(prach2,rxsigF[aa],1);
+            dft(DFT_1024,prach2,rxsigF[aa],1);
             fft_size = 1024;
           } else {
-            dft6144(prach2,rxsigF[aa],1);
+            dft(DFT_6144,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
-              dft6144(prach2+12288,rxsigF[aa]+12288,1);
+              dft(DFT_6144,prach2+12288,rxsigF[aa]+12288,1);
 
             fft_size = 6144;
           }
@@ -338,24 +337,24 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
         case 50:
           if (prach_fmt == 4) {
-            dft2048(prach2,rxsigF[aa],1);
+            dft(DFT_2048,prach2,rxsigF[aa],1);
           } else {
-            dft12288(prach2,rxsigF[aa],1);
+            dft(DFT_12288,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
-              dft12288(prach2+24576,rxsigF[aa]+24576,1);
+              dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1);
           }
 
           break;
 
         case 75:
           if (prach_fmt == 4) {
-            dft3072(prach2,rxsigF[aa],1);
+            dft(DFT_3072,prach2,rxsigF[aa],1);
           } else {
-            dft18432(prach2,rxsigF[aa],1);
+            dft(DFT_18432,prach2,rxsigF[aa],1);
 
             if (prach_fmt>1)
-              dft18432(prach2+36864,rxsigF[aa]+36864,1);
+              dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1);
           }
 
           break;
@@ -363,21 +362,21 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         case 100:
           if (fp->threequarter_fs==0) {
             if (prach_fmt == 4) {
-              dft4096(prach2,rxsigF[aa],1);
+              dft(DFT_4096,prach2,rxsigF[aa],1);
             } else {
-              dft24576(prach2,rxsigF[aa],1);
+              dft(DFT_24576,prach2,rxsigF[aa],1);
 
               if (prach_fmt>1)
-                dft24576(prach2+49152,rxsigF[aa]+49152,1);
+                dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1);
             }
           } else {
             if (prach_fmt == 4) {
-              dft3072(prach2,rxsigF[aa],1);
+              dft(DFT_3072,prach2,rxsigF[aa],1);
             } else {
-              dft18432(prach2,rxsigF[aa],1);
+              dft(DFT_18432,prach2,rxsigF[aa],1);
 
               if (prach_fmt>1)
-                dft18432(prach2+36864,rxsigF[aa]+36864,1);
+                dft(DFT_18432,prach2+36864,rxsigF[aa]+36864,1);
             }
           }
 
@@ -407,16 +406,16 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   if ((eNB==NULL)  && ru->function == NGFI_RRU_IF4p5) {
     /// **** send_IF4 of rxsigF to RAU **** ///
     if (br_flag == 1)
-      send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level);
+      send_IF4p5(ru, frame_prach, subframe, IF4p5_PRACH+1+ce_level);
     else
-      send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH);
+      send_IF4p5(ru, frame_prach, subframe, IF4p5_PRACH);
 
     return;
   } else if (eNB!=NULL) {
     if ( LOG_DEBUGFLAG(PRACH)) {
       int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-      if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
+      if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en);
     }
   }
 
@@ -457,7 +456,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     if (LOG_DEBUGFLAG(PRACH)) {
       int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-      if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",ru->proc.frame_prach,subframe,preamble_index,br_flag);
+      if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag);
     }
 
     if (restricted_set == 0) {
@@ -543,7 +542,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
       if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
-                         ru->proc.frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
+                         frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
     }
 
     log2_ifft_size = 10;
@@ -589,13 +588,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
         if (N_ZC == 839) {
           log2_ifft_size = 10;
-          idft1024(prachF,prach_ifft_tmp,1);
+          idft(IDFT_1024,prachF,prach_ifft_tmp,1);
 
           // compute energy and accumulate over receive antennas and repetitions for BR
           for (i=0; i<2048; i++)
             prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>9;
         } else {
-          idft256(prachF,prach_ifft_tmp,1);
+          idft(IDFT_256,prachF,prach_ifft_tmp,1);
           log2_ifft_size = 8;
 
           // compute energy and accumulate over receive antennas and repetitions for BR
@@ -618,7 +617,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       if (LOG_DEBUGFLAG(PRACH)) {
         int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
 
-        if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",ru->proc.frame_prach,subframe,br_flag,en);
+        if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",frame_prach,subframe,br_flag,en);
       }
 
       preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
@@ -638,7 +637,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 
             if ((en>60) && (br_flag==1))
               LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
-                    ru->proc.frame_prach,subframe,
+                    frame_prach,subframe,
                     *max_preamble_energy,*max_preamble_delay,
                     *max_preamble,br_flag,ce_level,levdB,lev);
           }
@@ -694,8 +693,16 @@ void rx_prach(PHY_VARS_eNB *eNB,
   int i;
   int prach_mask=0;
 
+  int subframe;
+  if (eNB)
+    subframe= br_flag?eNB->proc.subframe_prach_br:eNB->proc.subframe_prach;
+  else 
+    subframe= br_flag?ru->proc.subframe_prach_br:ru->proc.subframe_prach;
+  
+  int frame_prach=eNB?eNB->proc.frame_prach: ru->proc.frame_prach;
+
   if (br_flag == 0) {
-    rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
+    rx_prach0(eNB,ru,frame_prach,subframe,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
   } else { // This is procedure for eMTC, basically handling the repetitions
     prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br);
 
@@ -709,7 +716,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
         // increment repetition number
         eNB->prach_vars_br.repetition_number[i]++;
         // do basic PRACH reception
-        rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
+        rx_prach0(eNB,ru,frame_prach,subframe,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
 
         // if last repetition, clear counter
         if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) {
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_extern.h b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
index 2f8a83e24f2..47fbd93ad7c 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/prach_extern.h
@@ -29,6 +29,10 @@
  * \note
  * \warning
  */
+
+#ifndef __PHY_LTE_TRANSPORT_PRACH_EXTERN__H__
+#define __PHY_LTE_TRANSPORT_PRACH_EXTERN__H__
+
 #include "PHY/sse_intrin.h"
 #include "PHY/defs_eNB.h"
 #include "PHY/phy_extern.h"
@@ -91,3 +95,4 @@ void compute_prach_seq(uint16_t rootSequenceIndex,
 		       lte_frame_type_t frame_type,
 		       uint32_t X_u[64][839]);
 
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index e142d2f29fe..8637e801375 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -180,7 +180,7 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX
                                       uint16_t n3_pucch_array[NUMBER_OF_UE_MAX],
                                       uint8_t ncs_cell[20][7] ) {
   uint32_t        aa, symNo, k, slotNo, sym, i, j;
-  int16_t         np, np_n, ip_ind;
+  int16_t         np, np_n, ip_ind=-1;
   //int16_t         npucch_sf;
   int16_t         calctmp[2];
   int16_t         BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2];
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch_extern.h b/openair1/PHY/LTE_TRANSPORT/pucch_extern.h
index 899b9043067..b1513748880 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch_extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/pucch_extern.h
@@ -30,6 +30,9 @@
 * \warning
 */
 
+#ifndef __PHY_LTE_TRANSPORT_PUCCH_EXTERN__H__
+#define __PHY_LTE_TRANSPORT_PUCCH_EXTERN__H__
+
 #include <stdint.h>
 
 /* PUCCH format3 >> */
@@ -76,3 +79,5 @@ extern uint8_t Np4_TBL[4];
 // alpha_TBL
 extern int16_t alphaTBL_re[12];
 extern int16_t alphaTBL_im[12];
+
+#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
index 1d7aa598afd..e4f5d9a17f1 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common_proto.h
@@ -60,6 +60,8 @@ unsigned char get_I_TBS_UL(unsigned char I_MCS);
     @return Transport block size */
 uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb);
 
+uint16_t find_nb_rb_DL(uint8_t mcs, uint32_t bytes, uint16_t nb_rb_max, uint16_t rb_gran);
+
 /** \brief Compute Q (modulation order) based on uplink I_MCS. Implements table 7.1.7.1-1 from 36.213.
     @param I_MCS
     @param nb_rb
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
index 7b9004ba80c..5e446db5fdd 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
@@ -100,7 +100,7 @@ typedef struct {
   /// start symbold of pdsch
   uint8_t pdsch_start;
   /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
-  uint8_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
+  uint8_t eDL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
   /// Turbo-code outputs (36-212 V8.6 2009-03, p.12
   uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
   /// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
@@ -261,12 +261,13 @@ typedef struct {
   /// coded RI bits
   int16_t q_RI[MAX_RI_PAYLOAD];
   /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
-  int16_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
+  int16_t eUL[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
   /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
   uint8_t h[MAX_NUM_CHANNEL_BITS];
   /// Pointer to the payload
-  uint8_t *b;
+  uint8_t *decodedBytes;
   /// Pointers to transport block segments
+  //TBD
   uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
   /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
   uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
@@ -282,8 +283,12 @@ typedef struct {
   uint8_t rvidx;
   /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
   int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
+  int16_t pusch_rep_buffer[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
   /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+  //TBD
   int16_t *d[MAX_NUM_ULSCH_SEGMENTS];
+  uint32_t processedSegments;
+  uint32_t processedBadSegment;
   /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
   uint32_t C;
   /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_extern.h b/openair1/PHY/LTE_TRANSPORT/transport_extern.h
index 357d31ca107..8b33449ccaf 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_extern.h
@@ -22,7 +22,7 @@
 extern unsigned int dlsch_tbs25[27][25],TBStable[27][110],TBStable1C[32];
 extern unsigned short lte_cqi_eff1024[16];
 extern char lte_cqi_snr_dB[15];
-extern short conjugate[8],conjugate2[8];
+extern const short conjugate[8],conjugate2[8];
 extern short minus_one[8];
 extern short minus_one[8];
 extern short *ul_ref_sigs[30][2][34];
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
index f034039e7e2..3988923bb98 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
@@ -73,18 +73,19 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch);
 LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
 
 int dlsch_encoding_all(PHY_VARS_eNB *eNB,
-                       unsigned char *a,
-                       uint8_t num_pdcch_symbols,
-                       LTE_eNB_DLSCH_t *dlsch,
-                       int frame,
-                       uint8_t subframe,
-                       time_stats_t *rm_stats,
-                       time_stats_t *te_stats,
-                       time_stats_t *te_wait_stats,
-                       time_stats_t *te_main_stats,
-                       time_stats_t *te_wakeup_stats0,
-                       time_stats_t *te_wakeup_stats1,
-                       time_stats_t *i_stats);
+                      L1_rxtx_proc_t *proc,
+		       unsigned char *a,
+		       uint8_t num_pdcch_symbols,
+		       LTE_eNB_DLSCH_t *dlsch,
+		       int frame,
+		       uint8_t subframe,
+		       time_stats_t *rm_stats,
+		       time_stats_t *te_stats,
+		       time_stats_t *te_wait_stats,
+		       time_stats_t *te_main_stats,
+		       time_stats_t *te_wakeup_stats0,
+		       time_stats_t *te_wakeup_stats1,
+		       time_stats_t *i_stats);
 
 /** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
     uint8_t *input_buffer,
@@ -112,6 +113,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
     @returns status
 */
 int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
+                      L1_rxtx_proc_t *proc,
                        uint8_t *a,
                        uint8_t num_pdcch_symbols,
                        LTE_eNB_DLSCH_t *dlsch,
@@ -467,9 +469,12 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
 
 
 int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
-                            int UE_id,
-                            int harq_pid,
-                            int llr8_flag);
+
+                        L1_rxtx_proc_t *proc,
+                        int UE_id,
+                        int harq_pid,
+                        int llr8_flag);
+
 
 /*!
   \brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
@@ -511,6 +516,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
   @returns 0 on success
 */
 int ulsch_decoding_data(PHY_VARS_eNB *eNB,
+                        L1_rxtx_proc_t *proc,
                         int UE_id,
                         int harq_pid,
                         int llr8_flag);
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 39556902fcd..92fe7772011 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -41,22 +41,22 @@
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
 #include "transport_proto.h"
-#include "common/utils/LOG/vcd_signal_dumper.h"
-
+#include <executables/split_headers.h>
 
 extern WORKER_CONF_t get_thread_worker_conf(void);
 extern volatile int oai_exit;
 
 
+
 void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) {
   int i,r;
 
   if (ulsch) {
     for (i=0; i<8; i++) {
       if (ulsch->harq_processes[i]) {
-        if (ulsch->harq_processes[i]->b) {
-          free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
-          ulsch->harq_processes[i]->b = NULL;
+        if (ulsch->harq_processes[i]->decodedBytes) {
+          free16(ulsch->harq_processes[i]->decodedBytes,MAX_ULSCH_PAYLOAD_BYTES);
+          ulsch->harq_processes[i]->decodedBytes = NULL;
         }
 
         for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
@@ -115,10 +115,10 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
 
       if (ulsch->harq_processes[i]) {
         memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
-        ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
+        ulsch->harq_processes[i]->decodedBytes = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
 
-        if (ulsch->harq_processes[i]->b)
-          memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
+        if (ulsch->harq_processes[i]->decodedBytes)
+          memset(ulsch->harq_processes[i]->decodedBytes,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
         else
           exit_flag=3;
 
@@ -210,490 +210,163 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) {
   return(crc);
 }
 
-
-
-
-int ulsch_decoding_data_2thread0(td_params *tdp) {
-  PHY_VARS_eNB *eNB = tdp->eNB;
-  int UE_id         = tdp->UE_id;
-  int harq_pid      = tdp->harq_pid;
-  int llr8_flag     = tdp->llr8_flag;
-  unsigned int r,r_offset=0,Kr,Kr_bytes;
-  uint8_t crc_type;
-  int offset = 0;
-  int ret = 1;
-  int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
-  LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
-  LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
-  int Q_m = ulsch_harq->Qm;
-  int G = ulsch_harq->G;
-  uint32_t E=0;
-  uint32_t Gp,GpmodC,Nl=1;
-  uint32_t C = ulsch_harq->C;
-  decoder_if_t *tc;
-
-  if (llr8_flag == 0)
-    tc = decoder16;
-  else
-    tc = decoder8;
-
-  // go through first half of segments to get r_offset
-  for (r=0; r<(ulsch_harq->C/2); r++) {
-    // Get Turbo interleaver parameters
-    if (r<ulsch_harq->Cminus)
-      Kr = ulsch_harq->Kminus;
-    else
-      Kr = ulsch_harq->Kplus;
-
-    Kr_bytes = Kr>>3;
-    // This is stolen from rate-matching algorithm to get the value of E
-    Gp = G/Nl/Q_m;
-    GpmodC = Gp%C;
-
-    if (r < (C-(GpmodC)))
-      E = Nl*Q_m * (Gp/C);
-    else
-      E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
-
-    r_offset += E;
-
-    if (r==0) {
-      offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
-    } else {
-      offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
-    }
-  }
-
-  // go through second half of segments
-  for (; r<(ulsch_harq->C); r++) {
-    //    printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
-    // Get Turbo interleaver parameters
-    if (r<ulsch_harq->Cminus)
-      Kr = ulsch_harq->Kminus;
-    else
-      Kr = ulsch_harq->Kplus;
-
-    Kr_bytes = Kr>>3;
-    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
-    ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
-                                          (uint8_t *)&dummy_w[r][0],
+void processULSegment(void * arg) {
+  turboDecode_t* rdata=(turboDecode_t*) arg;
+  PHY_VARS_eNB *eNB=rdata->eNB;
+  LTE_UL_eNB_HARQ_t *ulsch_harq=rdata->ulsch_harq;
+  int r=rdata->segment_r;
+  int G=ulsch_harq->G;
+  int Kr_bytes=rdata->Kr>>3;
+  int16_t dummy_w[3*(6144+64)];
+  
+  memset(&dummy_w[0],0,3*(6144+64)*sizeof(short));
+  ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
+                                          (uint8_t *)&dummy_w[0],
                                           (r==0) ? ulsch_harq->F : 0);
-#ifdef DEBUG_ULSCH_DECODING
-    printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n",
-           r, G,
-           Kr*3,
-           Q_m,
-           nb_rb,
-           ulsch_harq->Nl);
-#endif
-
-    if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
+  start_meas(&eNB->ulsch_deinterleaving_stats);
+  unsigned int E;
+   if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
                                    G,
                                    ulsch_harq->w[r],
-                                   (uint8_t *) &dummy_w[r][0],
-                                   ulsch_harq->e+r_offset,
+                                   (uint8_t *) &dummy_w[0],
+                                   ulsch_harq->eUL+rdata->r_offset,
                                    ulsch_harq->C,
                                    NSOFT,
                                    0,   //Uplink
                                    1,
                                    ulsch_harq->rvidx,
-                                   (ulsch_harq->round==0)?1:0,  // clear
+                                   (ulsch_harq->rvidx==0)?1:0,  // clear
                                    ulsch_harq->Qm,
                                    1,
                                    r,
                                    &E)==-1) {
       LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
-      return(-1);
-    }
+      return;
+   }
+   stop_meas(&eNB->ulsch_rate_unmatching_stats);
+   int max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
 
-    r_offset += E;
-    sub_block_deinterleaving_turbo(4+Kr,
-                                   &ulsch_harq->d[r][96],
-                                   ulsch_harq->w[r]);
+  if(ulsch_harq->repetition_number == 1) {
+    memset(ulsch_harq->pusch_rep_buffer[r],0,(sizeof(int32_t)*3*(6144+64))) ;  // reset the buffer every new repetitions
+  }
+  if(ulsch_harq->total_number_of_repetitions > 1) {
+    if (ulsch_harq->rvidx==1) {
+      LOG_E(PHY,"Adding HARQ data for segment: %d\n", r);
+      // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1
+      for (int nn=0; nn<max_Ncb; nn++)
+	ulsch_harq->pusch_rep_buffer[r][nn] += ulsch_harq->w[r][nn] ;
+    }
 
-    if (ulsch_harq->C == 1)
-      crc_type = CRC24_A;
-    else
-      crc_type = CRC24_B;
-
-    ret = tc(&ulsch_harq->d[r][96],
-             NULL,
-             ulsch_harq->c[r],
-             NULL,
-             Kr,
-             ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
-             crc_type,
-             (r==0) ? ulsch_harq->F : 0,
-             &eNB->ulsch_tc_init_stats,
-             &eNB->ulsch_tc_alpha_stats,
-             &eNB->ulsch_tc_beta_stats,
-             &eNB->ulsch_tc_gamma_stats,
-             &eNB->ulsch_tc_ext_stats,
-             &eNB->ulsch_tc_intl1_stats,
-             &eNB->ulsch_tc_intl2_stats);
-
-    // Reassembly of Transport block here
-
-    if (ret != (1+ulsch->max_turbo_iterations)) {
-      if (r<ulsch_harq->Cminus)
-        Kr = ulsch_harq->Kminus;
-      else
-        Kr = ulsch_harq->Kplus;
-
-      Kr_bytes = Kr>>3;
-      memcpy(ulsch_harq->b+offset,
-             ulsch_harq->c[r],
-             Kr_bytes - ((ulsch_harq->C>1)?3:0));
-      offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
-    } else {
-      break;
+    if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) {
+      LOG_E(PHY,"Will use HARQ data sum up for segment: %d\n", r);
+      for (int nn=0; nn<max_Ncb; nn++) 
+	ulsch_harq->w[r][nn] =  ulsch_harq->pusch_rep_buffer[r][nn] ;
     }
   }
-
-  return(ret);
+  int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32)));
+  sub_block_deinterleaving_turbo(4+rdata->Kr,
+				 soft_bits+96,
+				 ulsch_harq->w[r]);
+  stop_meas(&eNB->ulsch_deinterleaving_stats);
+  rdata->decodeIterations = rdata->function( soft_bits+96,
+					     NULL,
+					     rdata->decoded_bytes,
+					     NULL,
+					     rdata->Kr,
+					     rdata->maxIterations,
+					     rdata->nbSegments == 1 ? CRC24_A: CRC24_B,
+					     rdata->Fbits,
+					     &eNB->ulsch_tc_init_stats,
+					     &eNB->ulsch_tc_alpha_stats,
+					     &eNB->ulsch_tc_beta_stats,
+					     &eNB->ulsch_tc_gamma_stats,
+					     &eNB->ulsch_tc_ext_stats,
+					     &eNB->ulsch_tc_intl1_stats,
+					     &eNB->ulsch_tc_intl2_stats);
+  stop_meas(&eNB->ulsch_turbo_decoding_stats);
+  
 }
 
-
 void *td_thread(void *param) {
-  PHY_VARS_eNB *eNB = ((td_params *)param)->eNB;
-  L1_proc_t *proc  = &eNB->proc;
-  pthread_setname_np( pthread_self(),"td processing");
-  LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
-  //wait_sync("td_thread");
-
-  while (!oai_exit) {
-    if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
-
-    if(oai_exit) break;
-
-    ((td_params *)param)->ret = ulsch_decoding_data_2thread0((td_params *)param);
-
-    if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break;
-
-    if (pthread_cond_signal(&proc->cond_td) != 0) {
-      printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-      return(NULL);
-    }
-  }
 
   return(NULL);
 }
 
-int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
-  L1_proc_t *proc = &eNB->proc;
-  unsigned int r,r_offset=0,Kr,Kr_bytes;
-  uint8_t crc_type;
+int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
+			int UE_id,int harq_pid,int llr8_flag) {
+  unsigned int r_offset=0;
   int offset = 0;
-  int ret = 1;
-  int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
   LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
   LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
   int G = ulsch_harq->G;
   unsigned int E;
-  int Cby2;
-  decoder_if_t *tc;
-  struct timespec wait;
-  wait.tv_sec=0;
-  wait.tv_nsec=5000000L;
-
-  if (llr8_flag == 0)
-    tc = decoder16;
-  else
-    tc = decoder8;
-
-  if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
-    if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
-      printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td);
-      exit_fun( "error locking mutex_fep" );
-      return -1;
-    }
-
-    if (proc->instance_cnt_td==0) {
-      printf("[eNB] TD thread busy\n");
-      exit_fun("TD thread busy");
-      pthread_mutex_unlock( &proc->mutex_td );
-      return -1;
-    }
-
-    ++proc->instance_cnt_td;
-    proc->tdp.eNB       = eNB;
-    proc->tdp.UE_id     = UE_id;
-    proc->tdp.harq_pid  = harq_pid;
-    proc->tdp.llr8_flag = llr8_flag;
-
-    // wakeup worker to do second half segments
-    if (pthread_cond_signal(&proc->cond_td) != 0) {
-      printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-      return (1+ulsch->max_turbo_iterations);
-    }
-
-    pthread_mutex_unlock( &proc->mutex_td );
-    Cby2 = ulsch_harq->C/2;
-  } else {
-    Cby2 = 1;
-  }
-
-  // go through first half of segments in main thread
-  for (r=0; r<Cby2; r++) {
+  int ret=0;
+  
+  decoder_if_t * td=llr8_flag == 0 ?
+    *decoder16 : *decoder8;
+  ulsch_harq->processedSegments=0;
+  
+  for (int r=0; r<ulsch_harq->C; r++) {
     //    printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
     // Get Turbo interleaver parameters
-    if (r<ulsch_harq->Cminus)
-      Kr = ulsch_harq->Kminus;
-    else
-      Kr = ulsch_harq->Kplus;
-
-    Kr_bytes = Kr>>3;
-    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
-    ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
-                                          (uint8_t *)&dummy_w[r][0],
-                                          (r==0) ? ulsch_harq->F : 0);
+    unsigned int Kr= r<ulsch_harq->Cminus ?
+      ulsch_harq->Kminus :ulsch_harq->Kplus;
+    unsigned int Kr_bytes = Kr>>3;
+    
 #ifdef DEBUG_ULSCH_DECODING
-    printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n",
-           r, G,
-           Kr*3,
-           Q_m,
-           nb_rb,
-           ulsch_harq->Nl);
-#endif
-    start_meas(&eNB->ulsch_rate_unmatching_stats);
-
-    if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
-                                   G,
-                                   ulsch_harq->w[r],
-                                   (uint8_t *) &dummy_w[r][0],
-                                   ulsch_harq->e+r_offset,
-                                   ulsch_harq->C,
-                                   NSOFT,
-                                   0,   //Uplink
-                                   1,
-                                   ulsch_harq->rvidx,
-                                   (ulsch_harq->round==0)?1:0,  // clear
-                                   ulsch_harq->Qm,
-                                   1,
-                                   r,
-                                   &E)==-1) {
-      LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
-      return(-1);
-    }
-
-    stop_meas(&eNB->ulsch_rate_unmatching_stats);
-    r_offset += E;
-    start_meas(&eNB->ulsch_deinterleaving_stats);
-    sub_block_deinterleaving_turbo(4+Kr,
-                                   &ulsch_harq->d[r][96],
-                                   ulsch_harq->w[r]);
-    stop_meas(&eNB->ulsch_deinterleaving_stats);
-
-    if (ulsch_harq->C == 1)
-      crc_type = CRC24_A;
-    else
-      crc_type = CRC24_B;
-
-    start_meas(&eNB->ulsch_turbo_decoding_stats);
-    ret = tc(&ulsch_harq->d[r][96],
-             NULL,
-             ulsch_harq->c[r],
-             NULL,
-             Kr,
-             ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
-             crc_type,
-             (r==0) ? ulsch_harq->F : 0,
-             &eNB->ulsch_tc_init_stats,
-             &eNB->ulsch_tc_alpha_stats,
-             &eNB->ulsch_tc_beta_stats,
-             &eNB->ulsch_tc_gamma_stats,
-             &eNB->ulsch_tc_ext_stats,
-             &eNB->ulsch_tc_intl1_stats,
-             &eNB->ulsch_tc_intl2_stats);
-
-    // Reassembly of Transport block here
-
-    if (ret != (1+ulsch->max_turbo_iterations)) {
-      if (r<ulsch_harq->Cminus)
-        Kr = ulsch_harq->Kminus;
-      else
-        Kr = ulsch_harq->Kplus;
-
-      Kr_bytes = Kr>>3;
-
-      if (r==0) {
-        memcpy(ulsch_harq->b,
-               &ulsch_harq->c[0][(ulsch_harq->F>>3)],
-               Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
-        offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
-      } else {
-        memcpy(ulsch_harq->b+offset,
-               ulsch_harq->c[r],
-               Kr_bytes - ((ulsch_harq->C>1)?3:0));
-        offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
-      }
-    } else {
-      break;
-    }
-
-    stop_meas(&eNB->ulsch_turbo_decoding_stats);
-    //printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r);
-  }
-
-  // wait for worker to finish
-  wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread");
-  return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
-}
-
-int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
-  unsigned int r,r_offset=0,Kr,Kr_bytes;
-  uint8_t crc_type;
-  int offset = 0;
-  int ret = 1;
-  int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
-  LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
-  LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
-  int G = ulsch_harq->G;
-  unsigned int E;
-  decoder_if_t *tc;
-  static int32_t pusch_rep_buffer[3*(6144+64)];
-  int max_Ncb;
-
-  if (llr8_flag == 0)
-    tc = *decoder16;
-  else
-    tc = *decoder8;
-
-  if(ulsch_harq->repetition_number == 1) {
-    memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ;  // reset the buffer every new repetitions
-  }
-
-  for (r=0; r<ulsch_harq->C; r++) {
-    //    printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
-    // Get Turbo interleaver parameters
-    if (r<ulsch_harq->Cminus)
-      Kr = ulsch_harq->Kminus;
-    else
-      Kr = ulsch_harq->Kplus;
-
-    Kr_bytes = Kr>>3;
-    memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
-    ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
-                                          (uint8_t *)&dummy_w[r][0],
-                                          (r==0) ? ulsch_harq->F : 0);
-#ifdef DEBUG_ULSCH_DECODING
-    printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d)...\n",
+    printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, Nl %d, r_offset %u)...\n",
            r, G,
            Kr*3,
            ulsch_harq->Qm,
-           ulsch_harq->Nl);
+           ulsch_harq->Nl, r_offset);
 #endif
-    start_meas(&eNB->ulsch_rate_unmatching_stats);
-
-    if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
-                                   G,
-                                   ulsch_harq->w[r],
-                                   (uint8_t *) &dummy_w[r][0],
-                                   ulsch_harq->e+r_offset,
-                                   ulsch_harq->C,
-                                   NSOFT,
-                                   0,   //Uplink
-                                   1,
-                                   ulsch_harq->rvidx,
-                                   (ulsch_harq->rvidx==0)?1:0,  // clear
-                                   ulsch_harq->Qm,
-                                   1,
-                                   r,
-                                   &E)==-1) {
-      LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
-      return(-1);
-    }
-
-    stop_meas(&eNB->ulsch_rate_unmatching_stats);
-    max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
-
-    if(ulsch_harq->total_number_of_repetitions > 1) {
-      if (ulsch_harq->rvidx==1) {
-        // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1
-        for (int nn=0; nn<max_Ncb; nn++) {
-          pusch_rep_buffer[nn] += ulsch_harq->w[r][nn] ;
-        }
-      }
-
-      if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) {
-        for (int nn=0; nn<max_Ncb; nn++) {
-          ulsch_harq->w[r][nn] =  pusch_rep_buffer[nn] ;
-        }
-      }
-    }
-
-    r_offset += E;
-    start_meas(&eNB->ulsch_deinterleaving_stats);
-    sub_block_deinterleaving_turbo(4+Kr,
-                                   &ulsch_harq->d[r][96],
-                                   ulsch_harq->w[r]);
-    stop_meas(&eNB->ulsch_deinterleaving_stats);
-
-    if (ulsch_harq->C == 1)
-      crc_type = CRC24_A;
+    int Gp=G/ulsch_harq->Qm;
+    int GpmodC = Gp%ulsch_harq->C;
+    
+    if (r < (ulsch_harq->C-(GpmodC)))
+      E = ulsch_harq->Qm * (Gp/ulsch_harq->C);
     else
-      crc_type = CRC24_B;
-
-    start_meas(&eNB->ulsch_turbo_decoding_stats);
-    ret = tc(&ulsch_harq->d[r][96],
-             NULL,
-             ulsch_harq->c[r],
-             NULL,
-             Kr,
-             ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
-             crc_type,
-             (r==0) ? ulsch_harq->F : 0,
-             &eNB->ulsch_tc_init_stats,
-             &eNB->ulsch_tc_alpha_stats,
-             &eNB->ulsch_tc_beta_stats,
-             &eNB->ulsch_tc_gamma_stats,
-             &eNB->ulsch_tc_ext_stats,
-             &eNB->ulsch_tc_intl1_stats,
-             &eNB->ulsch_tc_intl2_stats);
-    stop_meas(&eNB->ulsch_turbo_decoding_stats);
-
-    // Reassembly of Transport block here
-
-    if (ret != (1+ulsch->max_turbo_iterations)) {
-      if (r<ulsch_harq->Cminus)
-        Kr = ulsch_harq->Kminus;
-      else
-        Kr = ulsch_harq->Kplus;
-
-      Kr_bytes = Kr>>3;
-
-      if (r==0) {
-        memcpy(ulsch_harq->b,
-               &ulsch_harq->c[0][(ulsch_harq->F>>3)],
-               Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
-        offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
-      } else {
-        memcpy(ulsch_harq->b+offset,
-               ulsch_harq->c[r],
-               Kr_bytes - ((ulsch_harq->C>1)?3:0));
-        offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
-      }
-    } else {
-      break;
+      E = ulsch_harq->Qm * ((GpmodC==0?0:1) + (Gp/ulsch_harq->C));
+    
+    if ( split73 == SPLIT73_DU ) {
+      sendFs6Ul(eNB, UE_id, harq_pid, r, ulsch_harq->eUL+r_offset, E*sizeof(int16_t), r_offset);
+      r_offset += E;
+      continue;
     }
-  }
 
+    union turboReqUnion id= {.s={ulsch->rnti,proc->frame_rx,proc->subframe_rx,0,0}};
+    notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboDecode_t), id.p, proc->respDecode, processULSegment);
+    turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
+
+    rdata->eNB=eNB;
+    rdata->frame=proc->frame_rx;
+    rdata->subframe=proc->subframe_rx;
+    rdata->UEid=UE_id;
+    rdata->harq_pid=harq_pid;
+    rdata->Kr=Kr;
+    rdata->maxIterations=eNB->ulsch[UE_id]->max_turbo_iterations;
+    rdata->ulsch_harq=ulsch_harq;
+    rdata->eNB=eNB;
+    rdata->nbSegments=ulsch_harq->C;
+    rdata->segment_r=r;
+    rdata->Fbits=(r==0) ? ulsch_harq->F : 0;
+    rdata->r_offset=r_offset;
+    rdata->offset=offset;
+    rdata->function=td;
+    int Fbytes=(r==0) ? rdata->Fbits>>3 : 0;
+    int sz=Kr_bytes - Fbytes - ((ulsch_harq->C>1)?3:0);
+    pushTpool(proc->threadPool,req);
+    proc->nbDecode++;
+    LOG_D(PHY,"Added a block to decode, in pipe: %d\n",proc->nbDecode);
+    r_offset+=E;
+    offset+=sz;	    
+  }
   return(ret);
 }
 
-int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
-  int ret = 0;
-  /*if(get_thread_worker_conf() == WORKER_ENABLE)
-  {
-    ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag);
-  }
-  else*/
-  {
-    ret = ulsch_decoding_data(eNB,UE_id,harq_pid,llr8_flag);
-  }
-  return ret;
+int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
+			    int UE_id,int harq_pid,int llr8_flag) {
+  return ulsch_decoding_data(eNB,proc,UE_id,harq_pid,llr8_flag);
 }
 
 static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
@@ -767,7 +440,6 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
   else
     harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
   // x1 is set in lte_gold_generic
   x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
   ulsch_harq = ulsch->harq_processes[harq_pid];
@@ -779,8 +451,9 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
   A = ulsch_harq->TBS;
   Q_m = ulsch_harq->Qm;
   G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
+  LOG_D(PHY, "PUSCH nb_rb %d Q_m %d ulsch_harq->Nsymb_pusch %d\n",nb_rb, Q_m, ulsch_harq->Nsymb_pusch);  
   //#ifdef DEBUG_ULSCH_DECODING
-  LOG_D(PHY,"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n",
+  LOG_D(PHY,"[PUSCH harq %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): TBS %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n",
         harq_pid,
         proc->frame_rx,subframe,
         frame_parms->Nid_cell,ulsch->rnti,x2,
@@ -822,7 +495,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
   }
 
   AssertFatal(sumKr>0,
-              "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
+              "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %u, subframe %d\n",
               frame_parms->Nid_cell,ulsch->rnti,x2,
               harq_pid,
               ulsch_harq->round,
@@ -833,6 +506,12 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
               subframe);
   // Compute Q_ri
   Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
+  LOG_D(PHY, "Qprime %d, O_RI %d, Msc %d, Nym %d beta %d\n",
+		  Qprime,
+		  ulsch_harq->O_RI,
+		  ulsch_harq->Msc_initial,
+		  ulsch_harq->Nsymb_initial,
+		  ulsch->beta_offset_ri_times8);
 
   if (Qprime > 0 ) {
     if ((Qprime % (8*sumKr)) > 0)
@@ -893,7 +572,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
   G = G - Q_RI - Q_CQI;
   ulsch_harq->G = G;
   AssertFatal((int)G > 0,
-              "FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
+              "FATAL: ulsch_decoding.c G < 0 (%u) : Q_RI %u, Q_CQI %u\n",G,Q_RI,Q_CQI);
   H = G + Q_CQI;
   Hprime = H/Q_m;
   // Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
@@ -1209,8 +888,8 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
             j2+=2;
           }
 
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
         }
 
         break;
@@ -1222,10 +901,10 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
             j2+=4;
           }
 
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
         }
 
         break;
@@ -1237,12 +916,12 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
             j2+=6;
           }
 
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
-          ulsch_harq->e[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
+          ulsch_harq->eUL[iprime++] = y[j2++];
         }
 
         break;
@@ -1280,7 +959,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
     */
     int16_t *yp,*ep;
 
-    for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
+    for (iprime=0,yp=&y[j2],ep=&ulsch_harq->eUL[0];
          iprime<G;
          iprime+=8,j2+=8,ep+=8,yp+=8) {
       ep[0] = yp[0];
@@ -1404,7 +1083,6 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,
 
   LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]);
   // Do ULSCH Decoding for data portion
-  ret = ulsch_decoding_data_all(eNB,UE_id,harq_pid,llr8_flag);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
+  ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag);
   return(ret);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index 1b0d7feaf51..f357e385f0d 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -154,9 +154,9 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) {
 
   switch (Msc_PUSCH) {
     case 12:
-      dft12((int16_t *)idft_in0,(int16_t *)idft_out0);
-      dft12((int16_t *)idft_in1,(int16_t *)idft_out1);
-      dft12((int16_t *)idft_in2,(int16_t *)idft_out2);
+      dft(DFT_12,(int16_t *)idft_in0,(int16_t *)idft_out0,0);
+      dft(DFT_12,(int16_t *)idft_in1,(int16_t *)idft_out1,0);
+      dft(DFT_12,(int16_t *)idft_in2,(int16_t *)idft_out2,0);
 #if defined(__x86_64__)||defined(__i386__)
       norm128 = _mm_set1_epi16(9459);
 #elif defined(__arm__)
@@ -178,201 +178,201 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH) {
       break;
 
     case 24:
-      dft24(idft_in0,idft_out0,1);
-      dft24(idft_in1,idft_out1,1);
-      dft24(idft_in2,idft_out2,1);
+      dft(DFT_24,idft_in0,idft_out0,1);
+      dft(DFT_24,idft_in1,idft_out1,1);
+      dft(DFT_24,idft_in2,idft_out2,1);
       break;
 
     case 36:
-      dft36(idft_in0,idft_out0,1);
-      dft36(idft_in1,idft_out1,1);
-      dft36(idft_in2,idft_out2,1);
+      dft(DFT_36,idft_in0,idft_out0,1);
+      dft(DFT_36,idft_in1,idft_out1,1);
+      dft(DFT_36,idft_in2,idft_out2,1);
       break;
 
     case 48:
-      dft48(idft_in0,idft_out0,1);
-      dft48(idft_in1,idft_out1,1);
-      dft48(idft_in2,idft_out2,1);
+      dft(DFT_48,idft_in0,idft_out0,1);
+      dft(DFT_48,idft_in1,idft_out1,1);
+      dft(DFT_48,idft_in2,idft_out2,1);
       break;
 
     case 60:
-      dft60(idft_in0,idft_out0,1);
-      dft60(idft_in1,idft_out1,1);
-      dft60(idft_in2,idft_out2,1);
+      dft(DFT_60,idft_in0,idft_out0,1);
+      dft(DFT_60,idft_in1,idft_out1,1);
+      dft(DFT_60,idft_in2,idft_out2,1);
       break;
 
     case 72:
-      dft72(idft_in0,idft_out0,1);
-      dft72(idft_in1,idft_out1,1);
-      dft72(idft_in2,idft_out2,1);
+      dft(DFT_72,idft_in0,idft_out0,1);
+      dft(DFT_72,idft_in1,idft_out1,1);
+      dft(DFT_72,idft_in2,idft_out2,1);
       break;
 
     case 96:
-      dft96(idft_in0,idft_out0,1);
-      dft96(idft_in1,idft_out1,1);
-      dft96(idft_in2,idft_out2,1);
+      dft(DFT_96,idft_in0,idft_out0,1);
+      dft(DFT_96,idft_in1,idft_out1,1);
+      dft(DFT_96,idft_in2,idft_out2,1);
       break;
 
     case 108:
-      dft108(idft_in0,idft_out0,1);
-      dft108(idft_in1,idft_out1,1);
-      dft108(idft_in2,idft_out2,1);
+      dft(DFT_108,idft_in0,idft_out0,1);
+      dft(DFT_108,idft_in1,idft_out1,1);
+      dft(DFT_108,idft_in2,idft_out2,1);
       break;
 
     case 120:
-      dft120(idft_in0,idft_out0,1);
-      dft120(idft_in1,idft_out1,1);
-      dft120(idft_in2,idft_out2,1);
+      dft(DFT_120,idft_in0,idft_out0,1);
+      dft(DFT_120,idft_in1,idft_out1,1);
+      dft(DFT_120,idft_in2,idft_out2,1);
       break;
 
     case 144:
-      dft144(idft_in0,idft_out0,1);
-      dft144(idft_in1,idft_out1,1);
-      dft144(idft_in2,idft_out2,1);
+      dft(DFT_144,idft_in0,idft_out0,1);
+      dft(DFT_144,idft_in1,idft_out1,1);
+      dft(DFT_144,idft_in2,idft_out2,1);
       break;
 
     case 180:
-      dft180(idft_in0,idft_out0,1);
-      dft180(idft_in1,idft_out1,1);
-      dft180(idft_in2,idft_out2,1);
+      dft(DFT_180,idft_in0,idft_out0,1);
+      dft(DFT_180,idft_in1,idft_out1,1);
+      dft(DFT_180,idft_in2,idft_out2,1);
       break;
 
     case 192:
-      dft192(idft_in0,idft_out0,1);
-      dft192(idft_in1,idft_out1,1);
-      dft192(idft_in2,idft_out2,1);
+      dft(DFT_192,idft_in0,idft_out0,1);
+      dft(DFT_192,idft_in1,idft_out1,1);
+      dft(DFT_192,idft_in2,idft_out2,1);
       break;
 
     case 216:
-      dft216(idft_in0,idft_out0,1);
-      dft216(idft_in1,idft_out1,1);
-      dft216(idft_in2,idft_out2,1);
+      dft(DFT_216,idft_in0,idft_out0,1);
+      dft(DFT_216,idft_in1,idft_out1,1);
+      dft(DFT_216,idft_in2,idft_out2,1);
       break;
 
     case 240:
-      dft240(idft_in0,idft_out0,1);
-      dft240(idft_in1,idft_out1,1);
-      dft240(idft_in2,idft_out2,1);
+      dft(DFT_240,idft_in0,idft_out0,1);
+      dft(DFT_240,idft_in1,idft_out1,1);
+      dft(DFT_240,idft_in2,idft_out2,1);
       break;
 
     case 288:
-      dft288(idft_in0,idft_out0,1);
-      dft288(idft_in1,idft_out1,1);
-      dft288(idft_in2,idft_out2,1);
+      dft(DFT_288,idft_in0,idft_out0,1);
+      dft(DFT_288,idft_in1,idft_out1,1);
+      dft(DFT_288,idft_in2,idft_out2,1);
       break;
 
     case 300:
-      dft300(idft_in0,idft_out0,1);
-      dft300(idft_in1,idft_out1,1);
-      dft300(idft_in2,idft_out2,1);
+      dft(DFT_300,idft_in0,idft_out0,1);
+      dft(DFT_300,idft_in1,idft_out1,1);
+      dft(DFT_300,idft_in2,idft_out2,1);
       break;
 
     case 324:
-      dft324((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft324((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft324((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_324,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_324,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_324,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 360:
-      dft360((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft360((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft360((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_360,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_360,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_360,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 384:
-      dft384((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft384((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft384((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_384,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_384,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_384,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 432:
-      dft432((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft432((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft432((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_432,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_432,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_432,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 480:
-      dft480((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft480((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft480((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_480,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_480,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_480,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 540:
-      dft540((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft540((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft540((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_540,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_540,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_540,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 576:
-      dft576((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft576((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft576((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_576,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_576,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_576,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 600:
-      dft600((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft600((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft600((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_600,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_600,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_600,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 648:
-      dft648((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft648((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft648((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_648,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_648,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_648,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 720:
-      dft720((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft720((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft720((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_720,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_720,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_720,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 768:
-      dft768((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft768((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft768((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_768,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_768,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_768,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 864:
-      dft864((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft864((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft864((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_864,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_864,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_864,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 900:
-      dft900((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft900((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft900((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_900,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_900,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_900,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 960:
-      dft960((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft960((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft960((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_960,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_960,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_960,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 972:
-      dft972((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft972((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft972((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_972,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_972,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_972,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 1080:
-      dft1080((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft1080((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft1080((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_1080,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_1080,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_1080,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 1152:
-      dft1152((int16_t *)idft_in0,(int16_t *)idft_out0,1);
-      dft1152((int16_t *)idft_in1,(int16_t *)idft_out1,1);
-      dft1152((int16_t *)idft_in2,(int16_t *)idft_out2,1);
+      dft(DFT_1152,(int16_t *)idft_in0,(int16_t *)idft_out0,1);
+      dft(DFT_1152,(int16_t *)idft_in1,(int16_t *)idft_out1,1);
+      dft(DFT_1152,(int16_t *)idft_in2,(int16_t *)idft_out2,1);
       break;
 
     case 1200:
-      dft1200(idft_in0,idft_out0,1);
-      dft1200(idft_in1,idft_out1,1);
-      dft1200(idft_in2,idft_out2,1);
+      dft(DFT_1200,idft_in0,idft_out0,1);
+      dft(DFT_1200,idft_in1,idft_out1,1);
+      dft(DFT_1200,idft_in2,idft_out2,1);
       break;
 
     default:
@@ -780,7 +780,6 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
 #endif
 
     for (rb=0; rb<nb_rb; rb++) {
-      LOG_D(PHY,"comp: symbol %d rb %d\n",symbol,rb);
       // just compute channel magnitude without scaling, this is done after equalization for SC-FDMA
 #if defined(__x86_64__) || defined(__i386__)
       mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
index 4ca9a7c7625..7442a0ae7e0 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c
@@ -793,7 +793,7 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
     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]->eDL+r_offset,
                                         dlsch->harq_processes[harq_pid]->C, // C
                                         dlsch->Nsoft,                    // Nsoft,
                                         dlsch->Mdlharq,
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
index afa46de820f..ba904629a1c 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/initial_sync.c
@@ -38,7 +38,6 @@
 #include "PHY/MODULATION/modulation_UE.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
 #include "PHY/LTE_REFSIG/lte_refsig.h"
-#include "openair2/LAYER2/MAC/mac_proto.h"
 #include "common_lib.h"
 #include "PHY/INIT/phy_init.h"
 
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
index 49fa484c265..e4083863f0d 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c
@@ -65,7 +65,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
   uint16_t *prach_root_sequence_map;
   uint16_t preamble_offset,preamble_shift;
   uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
-  uint16_t d_start,numshift;
+  uint16_t d_start=-1,numshift;
   uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
   //uint8_t Nsp=2;
   //uint8_t f_ra,t1_ra;
@@ -338,11 +338,11 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
   switch (ue->frame_parms.N_RB_UL) {
     case 6:
       if (prach_fmt == 4) {
-        idft256(prachF,prach2,1);
+        idft(IDFT_256,prachF,prach2,1);
         memmove( prach, prach+512, Ncp<<2 );
         prach_len = 256+Ncp;
       } else {
-        idft1536(prachF,prach2,1);
+        idft(IDFT_1536,prachF,prach2,1);
         memmove( prach, prach+3072, Ncp<<2 );
         prach_len = 1536+Ncp;
 
@@ -356,12 +356,12 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
 
     case 15:
       if (prach_fmt == 4) {
-        idft512(prachF,prach2,1);
+        idft(IDFT_512,prachF,prach2,1);
         //TODO: account for repeated format in dft output
         memmove( prach, prach+1024, Ncp<<2 );
         prach_len = 512+Ncp;
       } else {
-        idft3072(prachF,prach2,1);
+        idft(IDFT_3072,prachF,prach2,1);
         memmove( prach, prach+6144, Ncp<<2 );
         prach_len = 3072+Ncp;
 
@@ -376,11 +376,11 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
     case 25:
     default:
       if (prach_fmt == 4) {
-        idft1024(prachF,prach2,1);
+        idft(IDFT_1024,prachF,prach2,1);
         memmove( prach, prach+2048, Ncp<<2 );
         prach_len = 1024+Ncp;
       } else {
-        idft6144(prachF,prach2,1);
+        idft(IDFT_6144,prachF,prach2,1);
         /*for (i=0;i<6144*2;i++)
         prach2[i]<<=1;*/
         memmove( prach, prach+12288, Ncp<<2 );
@@ -396,11 +396,11 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
 
     case 50:
       if (prach_fmt == 4) {
-        idft2048(prachF,prach2,1);
+        idft(IDFT_2048,prachF,prach2,1);
         memmove( prach, prach+4096, Ncp<<2 );
         prach_len = 2048+Ncp;
       } else {
-        idft12288(prachF,prach2,1);
+        idft(IDFT_12288,prachF,prach2,1);
         memmove( prach, prach+24576, Ncp<<2 );
         prach_len = 12288+Ncp;
 
@@ -414,12 +414,12 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
 
     case 75:
       if (prach_fmt == 4) {
-        idft3072(prachF,prach2,1);
+        idft(IDFT_3072,prachF,prach2,1);
         //TODO: account for repeated format in dft output
         memmove( prach, prach+6144, Ncp<<2 );
         prach_len = 3072+Ncp;
       } else {
-        idft18432(prachF,prach2,1);
+        idft(IDFT_18432,prachF,prach2,1);
         memmove( prach, prach+36864, Ncp<<2 );
         prach_len = 18432+Ncp;
 
@@ -434,11 +434,11 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
     case 100:
       if (ue->frame_parms.threequarter_fs == 0) {
         if (prach_fmt == 4) {
-          idft4096(prachF,prach2,1);
+          idft(IDFT_4096,prachF,prach2,1);
           memmove( prach, prach+8192, Ncp<<2 );
           prach_len = 4096+Ncp;
         } else {
-          idft24576(prachF,prach2,1);
+          idft(IDFT_24576,prachF,prach2,1);
           memmove( prach, prach+49152, Ncp<<2 );
           prach_len = 24576+Ncp;
 
@@ -449,12 +449,12 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
         }
       } else {
         if (prach_fmt == 4) {
-          idft3072(prachF,prach2,1);
+          idft(IDFT_3072,prachF,prach2,1);
           //TODO: account for repeated format in dft output
           memmove( prach, prach+6144, Ncp<<2 );
           prach_len = 3072+Ncp;
         } else {
-          idft18432(prachF,prach2,1);
+          idft(IDFT_18432,prachF,prach2,1);
           memmove( prach, prach+36864, Ncp<<2 );
           prach_len = 18432+Ncp;
           printf("Generated prach for 100 PRB, 3/4 sampling\n");
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/sldch.c b/openair1/PHY/LTE_UE_TRANSPORT/sldch.c
index 9c9d36c9746..8769d5f81bf 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/sldch.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/sldch.c
@@ -29,8 +29,6 @@
  * \note
  * \warning
  */
-#ifndef __LTE_TRANSPORT_SLSS__C__
-#define __LTE_TRANSPORT_SLSS__C__
 #include "PHY/defs_UE.h"
 
 extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
@@ -63,4 +61,3 @@ void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx)
 }
 
 
-#endif
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/slsch.c b/openair1/PHY/LTE_UE_TRANSPORT/slsch.c
index e51e33626df..e4e94a232d7 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/slsch.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/slsch.c
@@ -29,8 +29,6 @@
  * \note
  * \warning
  */
-#ifndef __LTE_TRANSPORT_SLSS__C__
-#define __LTE_TRANSPORT_SLSS__C__
 #include "PHY/defs_UE.h"
 
 extern int
@@ -66,5 +64,3 @@ void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slsch,int frame_tx,int subframe_tx)
     
   }
 }
-
-#endif
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/slss.c b/openair1/PHY/LTE_UE_TRANSPORT/slss.c
index 18bc5a28dec..3cd1c1acb09 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/slss.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/slss.c
@@ -29,8 +29,6 @@
  * \note
  * \warning
  */
-#ifndef __LTE_TRANSPORT_SLSS__C__
-#define __LTE_TRANSPORT_SLSS__C__
 #include "PHY/defs_UE.h"
 
 
@@ -39,5 +37,3 @@ void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss,int frame_tx,int subframe_tx) {
   AssertFatal(1==0,"Should get here yet for UE %d\n",ue->Mod_id);
 
 }
-
-#endif
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
index cc1f762e704..de1c3891da0 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
@@ -446,6 +446,13 @@ uint32_t ulsch_encoding(uint8_t *a,
       Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
     else
       Qprime = 0;
+      LOG_D(PHY,"Qprime %d, O_RI %d + %d, Msc %d, Nym %d beta %d\n",
+                  Qprime,
+                  ulsch->O, L,
+                  ulsch->harq_processes[harq_pid]->Msc_initial,
+                  ulsch->harq_processes[harq_pid]->Nsymb_initial,
+                  ulsch->beta_offset_cqi_times8);
+
 
     if (Qprime > 0) {
       if ((Qprime % (8*sumKr)) > 0)
@@ -455,7 +462,7 @@ uint32_t ulsch_encoding(uint8_t *a,
     }
 
     G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
-
+    LOG_D(PHY,"G: rb %d * ( 12 * Qm %d ) * nsymb %d, Qprime %d, O_RI %d\n", ulsch->harq_processes[harq_pid]->nb_rb, Q_m, ulsch->Nsymb_pusch, Qprime, ulsch->O_RI);
     if (Qprime > (G - ulsch->O_RI))
       Qprime = G - ulsch->O_RI;
 
@@ -465,6 +472,7 @@ uint32_t ulsch_encoding(uint8_t *a,
 
 
     G = G - Q_RI - Q_CQI;
+    LOG_D(PHY,"new G: %d, Q_RI %d Q_CQI %d\n",  G , Q_RI , Q_CQI);
     ulsch->harq_processes[harq_pid]->G = G;
 
 /*
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
index a9878b4eae4..b08fe302482 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c
@@ -104,9 +104,9 @@ void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
 
   switch (Msc_PUSCH) {
   case 12:
-    dft12((int16_t *)dft_in0,(int16_t *)dft_out0);
-    dft12((int16_t *)dft_in1,(int16_t *)dft_out1);
-    dft12((int16_t *)dft_in2,(int16_t *)dft_out2);
+    dft(DFT_12,(int16_t *)dft_in0,(int16_t *)dft_out0,0);
+    dft(DFT_12,(int16_t *)dft_in1,(int16_t *)dft_out1,0);
+    dft(DFT_12,(int16_t *)dft_in2,(int16_t *)dft_out2,0);
 
     /*
     dft12f(&((__m128i *)dft_in0)[0],&((__m128i *)dft_in0)[1],&((__m128i *)dft_in0)[2],&((__m128i *)dft_in0)[3],&((__m128i *)dft_in0)[4],&((__m128i *)dft_in0)[5],&((__m128i *)dft_in0)[6],&((__m128i *)dft_in0)[7],&((__m128i *)dft_in0)[8],&((__m128i *)dft_in0)[9],&((__m128i *)dft_in0)[10],&((__m128i *)dft_in0)[11],
@@ -138,201 +138,201 @@ void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
     break;
 
   case 24:
-    dft24((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft24((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft24((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_24,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_24,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_24,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 36:
-    dft36((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft36((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft36((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_36,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_36,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_36,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 48:
-    dft48((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft48((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft48((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_48,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_48,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_48,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 60:
-    dft60((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft60((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft60((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_60,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_60,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_60,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 72:
-    dft72((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft72((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft72((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_72,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_72,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_72,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 96:
-    dft96((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft96((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft96((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_96,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_96,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_96,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 108:
-    dft108((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft108((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft108((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_108,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_108,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_108,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 120:
-    dft120((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft120((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft120((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_120,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_120,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_120,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 144:
-    dft144((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft144((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft144((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_144,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_144,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_144,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 180:
-    dft180((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft180((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft180((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_180,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_180,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_180,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 192:
-    dft192((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft192((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft192((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_192,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_192,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_192,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 216:
-    dft216((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft216((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft216((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_216,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_216,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_216,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 240:
-    dft240((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft240((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft240((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_240,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_240,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_240,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 288:
-    dft288((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft288((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft288((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_288,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_288,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_288,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 300:
-    dft300((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft300((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft300((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_300,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_300,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_300,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 324:
-    dft324((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft324((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft324((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_324,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_324,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_324,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 360:
-    dft360((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft360((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft360((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_360,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_360,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_360,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 384:
-    dft384((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft384((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft384((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_384,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_384,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_384,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 432:
-    dft432((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft432((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft432((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_432,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_432,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_432,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 480:
-    dft480((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft480((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft480((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_480,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_480,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_480,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 540:
-    dft540((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft540((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft540((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_540,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_540,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_540,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 576:
-    dft576((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft576((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft576((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_576,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_576,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_576,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 600:
-    dft600((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft600((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft600((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_600,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_600,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_600,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 648:
-    dft648((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft648((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft648((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_648,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_648,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_648,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 720:
-    dft720((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft720((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft720((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_720,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_720,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_720,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 768:
-    dft768((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft768((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft768((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_768,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_768,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_768,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 864:
-    dft864((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft864((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft864((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_864,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_864,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_864,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 900:
-    dft900((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft900((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft900((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_900,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_900,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_900,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 960:
-    dft960((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft960((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft960((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_960,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_960,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_960,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 972:
-    dft972((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft972((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft972((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_972,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_972,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_972,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 1080:
-    dft1080((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft1080((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft1080((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_1080,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_1080,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_1080,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 1152:
-    dft1152((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft1152((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft1152((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_1152,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_1152,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_1152,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
 
   case 1200:
-    dft1200((int16_t*)dft_in0,(int16_t*)dft_out0,1);
-    dft1200((int16_t*)dft_in1,(int16_t*)dft_out1,1);
-    dft1200((int16_t*)dft_in2,(int16_t*)dft_out2,1);
+    dft(DFT_1200,(int16_t*)dft_in0,(int16_t*)dft_out0,1);
+    dft(DFT_1200,(int16_t*)dft_in1,(int16_t*)dft_out1,1);
+    dft(DFT_1200,(int16_t*)dft_in2,(int16_t*)dft_out2,1);
     break;
   }
 
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 5c8fce3c386..b27b692e661 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -242,7 +242,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
 
   switch (Msc_PUSCH) {
     case 12:
-      dft12((int16_t *)dft_in0, (int16_t *)dft_out0);
+      dft(DFT_12,(int16_t *)dft_in0, (int16_t *)dft_out0,0);
 
 #if defined(__x86_64__) || defined(__i386__)
       norm128 = _mm_set1_epi16(9459);
@@ -260,135 +260,135 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
       break;
 
     case 24:
-      dft24((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_24,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 36:
-      dft36((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_36,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 48:
-      dft48((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_48,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 60:
-      dft60((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_60,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 72:
-      dft72((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_72,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 96:
-      dft96((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_96,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 108:
-      dft108((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_108,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 120:
-      dft120((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_120,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 144:
-      dft144((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_144,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 180:
-      dft180((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_180,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 192:
-      dft192((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_192,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 216:
-      dft216((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_216,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 240:
-      dft240((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 288:
-      dft288((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_288,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 300:
-      dft300((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_300,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 324:
-      dft324((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_324,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 360:
-      dft360((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_360,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 384:
-      dft384((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_384,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 432:
-      dft432((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_432,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 480:
-      dft480((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_480,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 540:
-      dft540((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_540,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 576:
-      dft576((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_576,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 600:
-      dft600((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_600,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 648:
-      dft648((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_648,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 720:
-      dft720((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_720,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 768:
-      dft768((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_768,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 864:
-      dft864((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_864,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 900:
-      dft900((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_900,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 960:
-      dft960((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 972:
-      dft972((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 1080:
-      dft1080((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_1080,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 1152:
-      dft1152((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_1152,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
 
     case 1200:
-      dft1200((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+      dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
       break;
   }
 
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index cbeeca13278..855e649cc5e 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -95,41 +95,41 @@ void PHY_ofdm_mod(int *input,                       /// pointer to complex input
   volatile int *output_ptr=(int*)0;
 
   int *temp_ptr=(int*)0;
-  void (*idft)(int16_t *,int16_t *, int);
+  idft_size_idx_t idftsize;
 
   switch (fftsize) {
   case 128:
-    idft = idft128;
+    idftsize = IDFT_128;
     break;
 
   case 256:
-    idft = idft256;
+    idftsize = IDFT_256;
     break;
 
   case 512:
-    idft = idft512;
+    idftsize = IDFT_512;
     break;
 
   case 1024:
-    idft = idft1024;
+    idftsize = IDFT_1024;
     break;
 
   case 1536:
-    idft = idft1536;
+    idftsize = IDFT_1536;
     break;
 
   case 2048:
-    idft = idft2048;
+    idftsize = IDFT_2048;
     break;
 
   case 3072:
-    idft = idft3072;
+    idftsize = IDFT_3072;
     break;
   case 4096:
-    idft = idft4096;
+    idftsize = IDFT_4096;
     break;
   default:
-    idft = idft512;
+    idftsize = IDFT_512;
     break;
   }
 
@@ -148,12 +148,12 @@ void PHY_ofdm_mod(int *input,                       /// pointer to complex input
 
 #ifndef __AVX2__
     // handle 128-bit alignment for 128-bit SIMD (SSE4,NEON,AltiVEC)
-    idft((int16_t *)&input[i*fftsize],
+    idft(idftsize,(int16_t *)&input[i*fftsize],
          (fftsize==128) ? (int16_t *)temp : (int16_t *)&output[(i*fftsize) + ((1+i)*nb_prefix_samples)],
          1);
 #else
     // on AVX2 need 256-bit alignment
-    idft((int16_t *)&input[i*fftsize],
+    idft(idftsize,(int16_t *)&input[i*fftsize],
          (int16_t *)temp,
          1);
 
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 163ebac65f7..8f41735f10c 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -49,36 +49,36 @@ int slot_fep(PHY_VARS_UE *ue,
   unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
   LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
   int uespec_pilot[9][1200];*/
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsizeidx;
   int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
 
   switch (frame_parms->ofdm_symbol_size) {
     case 128:
-      dft = dft128;
-      break;
-
-    case 256:
-      dft = dft256;
-      break;
-
-    case 512:
-      dft = dft512;
-      break;
-
-    case 1024:
-      dft = dft1024;
-      break;
-
-    case 1536:
-      dft = dft1536;
-      break;
-
-    case 2048:
-      dft = dft2048;
+      dftsizeidx = DFT_128;
+      break;      
+                  
+    case 256:     
+      dftsizeidx = DFT_256;
+      break;       
+                   
+    case 512:      
+      dftsizeidx = DFT_512;
+      break;       
+                   
+    case 1024:     
+      dftsizeidx = DFT_1024;
+      break;       
+                   
+    case 1536:     
+      dftsizeidx = DFT_1536;
+      break;       
+                   
+    case 2048:     
+      dftsizeidx = DFT_2048;
       break;
 
     default:
-      dft = dft512;
+      dftsizeidx = DFT_512;
       break;
   }
 
@@ -118,13 +118,13 @@ int slot_fep(PHY_VARS_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsizeidx,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 #if UE_TIMING_TRACE
         start_meas(&ue->rx_dft_stats);
 #endif
-        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
 #if UE_TIMING_TRACE
         stop_meas(&ue->rx_dft_stats);
@@ -153,10 +153,10 @@ int slot_fep(PHY_VARS_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsizeidx,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
-        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 
@@ -247,36 +247,36 @@ int front_end_fft(PHY_VARS_UE *ue,
   unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
   LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
   int uespec_pilot[9][1200];*/
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsizeidx;
   int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
 
   switch (frame_parms->ofdm_symbol_size) {
     case 128:
-      dft = dft128;
-      break;
-
-    case 256:
-      dft = dft256;
-      break;
-
-    case 512:
-      dft = dft512;
-      break;
-
-    case 1024:
-      dft = dft1024;
-      break;
-
-    case 1536:
-      dft = dft1536;
-      break;
-
-    case 2048:
-      dft = dft2048;
-      break;
-
-    default:
-      dft = dft512;
+      dftsizeidx = DFT_128;
+      break;       
+                   
+    case 256:      
+      dftsizeidx = DFT_256;
+      break;       
+                   
+    case 512:      
+      dftsizeidx = DFT_512;
+      break;       
+                   
+    case 1024:     
+      dftsizeidx = DFT_1024;
+      break;       
+                   
+    case 1536:     
+      dftsizeidx = DFT_1536;
+      break;       
+                   
+    case 2048:     
+      dftsizeidx = DFT_2048;
+      break;       
+                   
+    default:       
+      dftsizeidx = DFT_512;
       break;
   }
 
@@ -319,11 +319,11 @@ int front_end_fft(PHY_VARS_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsizeidx,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
         start_meas(&ue->rx_dft_stats);
-        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
         stop_meas(&ue->rx_dft_stats);
       }
@@ -349,10 +349,10 @@ int front_end_fft(PHY_VARS_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsizeidx,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
-        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 
diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
index 38d78119e3f..60367450297 100644
--- a/openair1/PHY/MODULATION/slot_fep_mbsfn.c
+++ b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
@@ -42,35 +42,35 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
   unsigned int subframe_offset;
   //   int i;
   unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsizeidx;
 
   switch (frame_parms->ofdm_symbol_size) {
     case 128:
-      dft = dft128;
-      break;
-
-    case 256:
-      dft = dft256;
-      break;
-
-    case 512:
-      dft = dft512;
-      break;
-
-    case 1024:
-      dft = dft1024;
-      break;
-
-    case 1536:
-      dft = dft1536;
-      break;
-
-    case 2048:
-      dft = dft2048;
-      break;
-
-    default:
-      dft = dft512;
+      dftsizeidx = DFT_128;
+      break;       
+                   
+    case 256:      
+      dftsizeidx = DFT_256;
+      break;       
+                   
+    case 512:      
+      dftsizeidx = DFT_512;
+      break;       
+                   
+    case 1024:     
+      dftsizeidx = DFT_1024;
+      break;       
+                   
+    case 1536:     
+      dftsizeidx = DFT_1536;
+      break;       
+                   
+    case 2048:     
+      dftsizeidx = DFT_2048;
+      break;       
+                   
+    default:       
+      dftsizeidx = DFT_512;
       break;
   }
 
@@ -110,7 +110,7 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
 #if UE_TIMING_TRACE
       start_meas(&ue->rx_dft_stats);
 #endif
-      dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
+      dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(sample_offset +
                                               nb_prefix_samples0 +
                                               subframe_offset -
                                               SOFFSET) % frame_length_samples],
@@ -131,7 +131,7 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
 #if UE_TIMING_TRACE
       start_meas(&ue->rx_dft_stats);
 #endif
-      dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
+      dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(sample_offset +
                                               (frame_parms->ofdm_symbol_size+nb_prefix_samples0+nb_prefix_samples) +
                                               (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1) +
                                               subframe_offset-
@@ -208,43 +208,43 @@ int slot_fep_mbsfn_khz_1dot25(PHY_VARS_UE *ue,
   int ofdm_symbol_size;
   unsigned int subframe_offset;
   unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsizeidx;
   AssertFatal(frame_parms->frame_type == FDD, "Frame is TDD!\n");
 
   switch (frame_parms->ofdm_symbol_size) {
     case 128:
-      dft = dft1536;
+      dftsizeidx = DFT_1536;
       ofdm_symbol_size=1536;
       nb_prefix_samples=384;
       break;
 
     case 256:
       AssertFatal(1==0,"FeMBMS dft3072 not implemented\n");
-      dft = dft3072;
+      dftsizeidx = DFT_3072;
       ofdm_symbol_size=3072;
       nb_prefix_samples=768;
       break;
 
     case 512:
-      dft = dft6144;
+      dftsizeidx = DFT_6144;
       nb_prefix_samples=1536;
       ofdm_symbol_size=6144;
       break;
 
     case 1024:
-      dft = dft12288;
+      dftsizeidx = DFT_12288;
       nb_prefix_samples=3072;
       ofdm_symbol_size=12288;
       break;
 
     case 1536:
-      dft = dft18432;
+      dftsizeidx = DFT_18432;
       nb_prefix_samples=4608;
       ofdm_symbol_size=18432;
       break;
 
     case 2048:
-      dft = dft24576;
+      dftsizeidx = DFT_24576;
       nb_prefix_samples=6144;
       ofdm_symbol_size=24576;
       break;
@@ -265,7 +265,7 @@ int slot_fep_mbsfn_khz_1dot25(PHY_VARS_UE *ue,
 #if UE_TIMING_TRACE
     start_meas(&ue->rx_dft_stats);
 #endif
-    dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
+    dft(dftsizeidx,(int16_t *)&common_vars->rxdata[aa][(sample_offset +
                                             nb_prefix_samples +
                                             subframe_offset -
                                             SOFFSET) % frame_length_samples],
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index f2e5d24badb..7fe8437c4e6 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -25,6 +25,7 @@
 #include "nr_modulation.h"
 #include "PHY/LTE_ESTIMATION/lte_estimation.h"
 #include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
+#include <common/utils/LOG/log.h>
 
 //#define DEBUG_FEP
 
@@ -62,44 +63,44 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
   unsigned int rx_offset;
 
 
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsize;
   int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
 
   switch (frame_parms->ofdm_symbol_size) {
   case 128:
-    dft = dft128;
+    dftsize = DFT_128;
     break;
 
   case 256:
-    dft = dft256;
+    dftsize = DFT_256;
     break;
 
   case 512:
-    dft = dft512;
+    dftsize = DFT_512;
     break;
 
   case 1024:
-    dft = dft1024;
+    dftsize = DFT_1024;
     break;
 
   case 1536:
-    dft = dft1536;
+    dftsize = DFT_1536;
     break;
 
   case 2048:
-    dft = dft2048;
+    dftsize = DFT_2048;
     break;
 
   case 3072:
-    dft = dft3072;
+    dftsize = DFT_3072;
     break;
 
   case 4096:
-    dft = dft4096;
+    dftsize = DFT_4096;
     break;
 
   case 8192:
-    dft = dft8192;
+    dftsize = DFT_8192;
     break;
 
   default:
@@ -155,14 +156,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsize,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 #if UE_TIMING_TRACE
           start_meas(&ue->rx_dft_stats);
 #endif
 
-        dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
 #if UE_TIMING_TRACE
         stop_meas(&ue->rx_dft_stats);
@@ -183,11 +184,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsize,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 
-        dft((int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 #if UE_TIMING_TRACE
@@ -237,44 +238,44 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
   unsigned int rx_offset;
 
 
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsize;
   int tmp_dft_in[8192] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
 
   switch (frame_parms->ofdm_symbol_size) {
   case 128:
-    dft = dft128;
+    dftsize = DFT_128;
     break;
 
   case 256:
-    dft = dft256;
+    dftsize = DFT_256;
     break;
 
   case 512:
-    dft = dft512;
+    dftsize = DFT_512;
     break;
 
   case 1024:
-    dft = dft1024;
+    dftsize = DFT_1024;
     break;
 
   case 1536:
-    dft = dft1536;
+    dftsize = DFT_1536;
     break;
 
   case 2048:
-    dft = dft2048;
+    dftsize = DFT_2048;
     break;
 
   case 3072:
-    dft = dft3072;
+    dftsize = DFT_3072;
     break;
 
   case 4096:
-    dft = dft4096;
+    dftsize = DFT_4096;
     break;
 
   case 8192:
-    dft = dft8192;
+    dftsize = DFT_8192;
     break;
 
   default:
@@ -330,14 +331,15 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *) &common_vars->rxdata[aa][rx_offset],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsize,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 #if UE_TIMING_TRACE
           start_meas(&ue->rx_dft_stats);
 #endif
 
-        dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+
+        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
 #if UE_TIMING_TRACE
         stop_meas(&ue->rx_dft_stats);
@@ -358,11 +360,10 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
         memcpy((void *)tmp_dft_in,
                (void *) &common_vars->rxdata[aa][rx_offset],
                frame_parms->ofdm_symbol_size*sizeof(int));
-        dft((int16_t *)tmp_dft_in,
+        dft(dftsize,(int16_t *)tmp_dft_in,
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
-
-        dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+        dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
             (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 #if UE_TIMING_TRACE
@@ -400,43 +401,43 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
   unsigned int nb_prefix_samples  = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
   unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
   
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsize;
 
   switch (frame_parms->ofdm_symbol_size) {
     case 128:
-      dft = dft128;
+      dftsize = DFT_128;
       break;
 
     case 256:
-      dft = dft256;
+      dftsize = DFT_256;
       break;
 
     case 512:
-      dft = dft512;
+      dftsize = DFT_512;
       break;
 
     case 1024:
-      dft = dft1024;
+      dftsize = DFT_1024;
       break;
 
     case 1536:
-      dft = dft1536;
+      dftsize = DFT_1536;
       break;
 
     case 2048:
-      dft = dft2048;
+      dftsize = DFT_2048;
       break;
 
     case 4096:
-      dft = dft4096;
+      dftsize = DFT_4096;
       break;
 
     case 8192:
-      dft = dft8192;
+      dftsize = DFT_8192;
       break;
 
     default:
-      dft = dft512;
+      dftsize = DFT_512;
       break;
   }
   
@@ -448,7 +449,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
   else
     rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
 
-  dft((int16_t *)&rxdata[rxdata_offset],
+  dft(dftsize,(int16_t *)&rxdata[rxdata_offset],
        (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
 
   return(0);
diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c
index 3ac8537c696..746f8dbc0e1 100644
--- a/openair1/PHY/MODULATION/slot_fep_ul.c
+++ b/openair1/PHY/MODULATION/slot_fep_ul.c
@@ -44,7 +44,7 @@ int slot_fep_ul(RU_t *ru,
   unsigned int slot_offset;
 
 
-  void (*dft)(int16_t *,int16_t *, int);
+  dft_size_idx_t dftsize;
 
   int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
   unsigned int frame_length_samples = fp->samples_per_tti * 10;
@@ -52,31 +52,31 @@ int slot_fep_ul(RU_t *ru,
 
   switch (fp->ofdm_symbol_size) {
   case 128:
-    dft = dft128;
+    dftsize = DFT_128;
     break;
 
   case 256:
-    dft = dft256;
+    dftsize = DFT_256;
     break;
 
   case 512:
-    dft = dft512;
+    dftsize = DFT_512;
     break;
 
   case 1024:
-    dft = dft1024;
+    dftsize = DFT_1024;
     break;
 
   case 1536:
-    dft = dft1536;
+    dftsize = DFT_1536;
     break;
 
   case 2048:
-    dft = dft2048;
+    dftsize = DFT_2048;
     break;
 
   default:
-    dft = dft512;
+    dftsize = DFT_512;
     break;
   }
 
@@ -109,7 +109,7 @@ int slot_fep_ul(RU_t *ru,
       LOG_D(PHY,"slot_fep: symbol 0 %d dB\n",
 	    dB_fixed(signal_energy(&common->rxdata_7_5kHz[aa][rx_offset],fp->ofdm_symbol_size)));
 #endif
-      dft( (int16_t *)&common->rxdata_7_5kHz[aa][rx_offset],
+      dft( dftsize,(int16_t *)&common->rxdata_7_5kHz[aa][rx_offset],
            (int16_t *)&common->rxdataF[aa][fp->ofdm_symbol_size*symbol],
            1
          );
@@ -121,13 +121,13 @@ int slot_fep_ul(RU_t *ru,
         memcpy((void *)&tmp_dft_in,
 	       (void *)&common->rxdata_7_5kHz[aa][(rx_offset % frame_length_samples)],
 	       fp->ofdm_symbol_size*sizeof(int));
-        dft( (short *) tmp_dft_in,
+        dft( dftsize,(short *) tmp_dft_in,
              (short*)  &common->rxdataF[aa][fp->ofdm_symbol_size*symbol],
              1
            );
       }
       else{
-      dft( (short *)&common->rxdata_7_5kHz[aa][rx_offset],
+      dft( dftsize,(short *)&common->rxdata_7_5kHz[aa][rx_offset],
            (short*)&common->rxdataF[aa][fp->ofdm_symbol_size*symbol],
            1
          );
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 0d7732599fc..f94a82c1118 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -430,55 +430,55 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
       switch (gNB->frame_parms.ofdm_symbol_size) {
         case 128:
-          idft128((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_128,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 256:
-          idft256((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_256,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 512:
-          idft512((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_512,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 1024:
-          idft1024((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_1024,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 1536:
-          idft1536((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_1536,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 2048:
-          idft2048((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_2048,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 4096:
-          idft4096((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_4096,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         case 8192:
-          idft8192((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_8192,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
 
         default:
-          idft512((int16_t*) &ul_ch_estimates[aarx][symbol_offset],
+          idft(IDFT_512,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
                  (int16_t*) ul_ch_estimates_time[aarx],
                  1);
           break;
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index ed37a79d0f2..8718fc86102 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -35,143 +35,6 @@
 
 /***********************************************************************/
 
-// TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
-// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
-// When l' = l0, it is represented by 1
-// E.g. when symbol duration is 12 in colomn 7, value 1057 ('10000100001') which means l' =  l0, 5, 10.
-
-int32_t table_6_4_1_1_3_3_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
-{-1,          -1,          -1,         -1,          1,          1,         1,         1},       //<4              // (DMRS l' position)
-{1,            1,           1,          1,          1,          1,         1,         1},       //4               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //5               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //6               // (DMRS l' position)
-{1,            1,           1,          1,          1,          5,         5,         5},       //7               // (DMRS l' position)
-{1,          129,         129,        129,          1,         65,        73,        73},       //8               // (DMRS l' position)
-{1,          129,         129,        129,          1,         65,        73,        73},       //9               // (DMRS l' position)
-{1,          513,         577,        577,          1,        257,       273,       585},       //10              // (DMRS l' position)
-{1,          513,         577,        577,          1,        257,       273,       585},       //11              // (DMRS l' position)
-{1,          513,         577,       2337,          1,       1025,      1057,       585},       //12              // (DMRS l' position)
-{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //13              // (DMRS l' position)
-{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //14              // (DMRS l' position)
-};
-
-
-// TS 38.211 Table 6.4.1.1.3-4: PUSCH DMRS positions l' within a slot for double-symbol DMRS and intra-slot frequency hopping disabled.
-// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
-// When l' = l0, it is represented by 1
-
-int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
-{-1,          -1,          -1,         -1,         -1,         -1,        -1,         -1},       //<4              // (DMRS l' position)
-{1,            1,          -1,         -1,         -1,         -1,        -1,         -1},       //4               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //5               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //6               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //7               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //8               // (DMRS l' position)
-{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //9               // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //10              // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //11              // (DMRS l' position)
-{1,          257,          -1,         -1,          1,        513,        -1,         -1},       //12              // (DMRS l' position)
-{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //13              // (DMRS l' position)
-{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //14              // (DMRS l' position)
-};
-
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength) {
-
-  uint8_t row, colomn;
-  int32_t l_prime;
-
-  colomn = additional_pos;
-
-  if (mapping_type == typeB)
-    colomn += 4;
-
-  if (duration_in_symbols < 4)
-    row = 0;
-  else
-    row = duration_in_symbols - 3;
-
-  if (pusch_maxLength == pusch_len1)
-    l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn];
-  else
-    l_prime = table_6_4_1_1_3_4_pusch_dmrs_positions_l[row][colomn];
-
-  AssertFatal(l_prime>0,"invalid l_prime < 0\n");
-
-  return l_prime;
-}
-
-/*******************************************************************
-*
-* NAME :         is_dmrs_symbol
-*
-* PARAMETERS : l                      ofdm symbol index within slot
-*              k                      subcarrier index
-*              start_sc               first subcarrier index
-*              k_prime                index alternating 0 and 1
-*              n                      index starting 0,1,...
-*              delta                  see Table 6.4.1.1.3
-*              duration_in_symbols    number of scheduled PUSCH ofdm symbols
-*              dmrs_UplinkConfig      DMRS uplink configuration
-*              mapping_type           PUSCH mapping type (A or B)
-*              ofdm_symbol_size       IFFT size
-*
-* RETURN :       0 if symbol(k,l) is data, or 1 if symbol(k,l) is dmrs
-*
-* DESCRIPTION :  3GPP TS 38.211 6.4.1.1 Demodulation reference signal for PUSCH
-*
-*********************************************************************/
-
-uint8_t is_dmrs_symbol(uint8_t l,
-                       uint16_t k,
-                       uint16_t start_sc,
-                       uint8_t k_prime,
-                       uint16_t n,
-                       uint8_t delta,
-                       uint8_t duration_in_symbols,
-                       uint8_t dmrs_type,
-                       uint16_t ofdm_symbol_size) {
-
-  uint8_t is_dmrs_freq, is_dmrs_time, l0;
-  int32_t l_prime_mask;
-  pusch_dmrs_AdditionalPosition_t additional_pos = pusch_dmrs_pos0;
-  pusch_maxLength_t pusch_maxLength = pusch_len1;
-  uint8_t mapping_type = typeB;
-
-  is_dmrs_freq = 0;
-  is_dmrs_time = 0;
-
-
-  l0 = get_l0_ul(mapping_type, 2);
-  l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, pusch_maxLength);
-
-  if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%ofdm_symbol_size))
-    is_dmrs_freq = 1;
-
-
-  if (l_prime_mask == 1){
-
-    if (l == l0)
-      is_dmrs_time = 1;
-
-  } else if ( (l==l0) || (((l_prime_mask>>l)&1) == 1 && l!=0) )
-    is_dmrs_time = 1;
-
-  if (pusch_maxLength == pusch_len2){
-
-    if (((l_prime_mask>>(l-1))&1) == 1 && l!=0 && l!=1)
-      is_dmrs_time = 1;
-
-    if (l-1 == l0)
-      is_dmrs_time = 1;
-
-  }
-
-  if (is_dmrs_time && is_dmrs_freq)
-    return 1;
-  else
-    return 0;
-
-}
 
 /*******************************************************************
 *
@@ -364,25 +227,6 @@ void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2
 #endif
 }
 
-/*******************************************************************
-*
-* NAME :         get_l0_ul
-*
-* PARAMETERS :   mapping_type : PUSCH mapping type
-*                dmrs_typeA_position  : higher layer parameter
-*
-* RETURN :       demodulation reference signal for PUSCH
-*
-* DESCRIPTION :  see TS 38.211 V15.4.0 Demodulation reference signals for PUSCH
-*
-*********************************************************************/
-
-uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
-
-  return ((mapping_type==typeA)?dmrs_typeA_position:0);
-
-}
-
 /*******************************************************************
 *
 * NAME :         get_dmrs_freq_idx_ul
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h
index f1dfffff8b5..6badf71745f 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h
@@ -54,21 +54,8 @@
 int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit);
 void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell);
 void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell);
-uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
 uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
 
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
-
-uint8_t is_dmrs_symbol(uint8_t l,
-                       uint16_t k,
-                       uint16_t start_sc,
-                       uint8_t k_prime,
-                       uint16_t n,
-                       uint8_t delta,
-                       uint8_t duration_in_symbols,
-                       uint8_t dmrs_type,
-                       uint16_t ofdm_symbol_size);
-
 #undef EXTERN
 
 #endif /* DMRS_NR_H */
diff --git a/openair1/PHY/NR_REFSIG/nr_mod_table.h b/openair1/PHY/NR_REFSIG/nr_mod_table.h
index a9984296990..c34dadb663e 100644
--- a/openair1/PHY/NR_REFSIG/nr_mod_table.h
+++ b/openair1/PHY/NR_REFSIG/nr_mod_table.h
@@ -1,3 +1,27 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef __PHY_NR_REFSIG_NR_MOD_TABLE__H__
+#define __PHY_NR_REFSIG_NR_MOD_TABLE__H__
+
 #define NR_MOD_TABLE_SIZE_SHORT 686
 #define NR_MOD_TABLE_BPSK_OFFSET 1
 #define NR_MOD_TABLE_QPSK_OFFSET 3
@@ -5,3 +29,5 @@
 #define NR_MOD_TABLE_QAM64_OFFSET 23
 #define NR_MOD_TABLE_QAM256_OFFSET 87
 short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
+
+#endif
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index 5af0e880999..d18f6405d7b 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -26,7 +26,7 @@
 
 #include "PHY/defs_gNB.h"
 #include "PHY/LTE_REFSIG/lte_refsig.h"
-
+#include "PHY/sse_intrin.h"
 
 /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
 @param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
@@ -49,4 +49,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
                      unsigned char lp,
                      unsigned short nb_pusch_rb,
                      uint8_t dmrs_type);
+
+void init_scrambling_luts(void);
+
+extern __m64 byte2m64_re[256];
+extern __m64 byte2m64_im[256];
+
 #endif
diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h
index a2e66d4e110..19b9736bcbe 100644
--- a/openair1/PHY/NR_REFSIG/pss_nr.h
+++ b/openair1/PHY/NR_REFSIG/pss_nr.h
@@ -127,8 +127,8 @@ time_stats_t generic_time[TIME_LAST];
 
 /************** FUNCTION ******************************************/
 
-void *get_idft(int ofdm_symbol_size);
-void *get_dft(int ofdm_symbol_size);
+idft_size_idx_t get_idft(int ofdm_symbol_size);
+dft_size_idx_t get_dft(int ofdm_symbol_size);
 void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
 void free_context_synchro_nr(void);
 void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c
index 12f76b950f1..785252126af 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c
@@ -38,18 +38,18 @@
 /***********************************************************************/
 
 
- //#define max(a,b) (((a) > (b)) ? (a) : (b))
+//#define max(a,b) (((a) > (b)) ? (a) : (b))
 
 // TS 38.211 Table 6.4.1.2.2.1-1: The parameter kRE_ref.
 // The first 4 colomns are DM-RS Configuration type 1 and the last 4 colomns are DM-RS Configuration type 2.
 
 int16_t table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref [6][8] = {
-{ 0,            2,           6,          8,          0,          1,         6,         7},
-{ 2,            4,           8,         10,          1,          6,         7,         0},
-{ 1,            3,           7,          9,          2,          3,         8,         9},
-{ 3,            5,           9,         11,          3,          8,         9,         2},
-{-1,           -1,          -1,         -1,          4,          5,        10,        11},
-{-1,           -1,          -1,         -1,          5,         10,        11,         4},
+  { 0,            2,           6,          8,          0,          1,         6,         7},
+  { 2,            4,           8,         10,          1,          6,         7,         0},
+  { 1,            3,           7,          9,          2,          3,         8,         9},
+  { 3,            5,           9,         11,          3,          8,         9,         2},
+  {-1,           -1,          -1,         -1,          4,          5,        10,        11},
+  {-1,           -1,          -1,         -1,          5,         10,        11,         4},
 };
 
 
@@ -68,55 +68,20 @@ int16_t table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref [6][8] = {
 *********************************************************************/
 
 int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset) {
-
   uint8_t colomn;
   int16_t k_RE_ref;
-
   colomn = resourceElementOffset;
 
   if (pusch_dmrs_type == 2)
     colomn += 4;
 
   k_RE_ref = table_6_4_1_2_2_1_1_pusch_ptrs_kRE_ref[dmrs_antenna_port][colomn];
-
   AssertFatal(k_RE_ref>=0,"invalid k_RE_ref < 0. Check PTRS Configuration\n");
-
   return k_RE_ref;
 }
 
 
-/*******************************************************************
-*
-* NAME :         get_K_ptrs
-*
-* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
-*                N_RB                   number of RBs scheduled for PUSCH
-*
-* RETURN :       the parameter K_ptrs
-*
-* DESCRIPTION :  3GPP TS 38.214 6.2.3 Table 6.2.3.1-2
-*
-*********************************************************************/
-
-uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
-
-	uint16_t nrb0, nrb1;
-
-	nrb0 = ptrs_UplinkConfig->frequencyDensity.n_rb0;
-	nrb1 = ptrs_UplinkConfig->frequencyDensity.n_rb1;
 
-	if (nrb0 == 0 || nrb0 == 0)
-		return 2;
-
-	if (N_RB < nrb0){
-		LOG_I(PHY,"PUSH PT-RS is not present.\n");
-		return 0;
-	}
-	else if (N_RB >= nrb0 && N_RB < nrb1)
-		return 2;
-	else
-		return 4;
-}
 
 /*******************************************************************
 *
@@ -126,7 +91,7 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
 *                duration_in_symbols    number of scheduled PUSCH ofdm symbols
 *                start_symbol           first ofdm symbol of PUSCH within slot
 *                L_ptrs                 the parameter L_ptrs
-*                ofdm_symbol_size       FFT size
+*                ul_dmrs_symb_pos       bitmap of the time domain positions of the DMRS symbols in the scheduled PUSCH
 *
 * RETURN :       sets the bit map of PTRS ofdm symbol indicies
 *
@@ -137,54 +102,31 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
 void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
                        uint8_t duration_in_symbols,
                        uint8_t start_symbol,
-                       uint8_t dmrs_type,
                        uint8_t L_ptrs,
-                       uint8_t pusch_maxLength,
-                       uint16_t ofdm_symbol_size) {
+                       uint16_t ul_dmrs_symb_pos) {
 
-  uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
-  int16_t l_ref;
-
-  *ptrs_symbols = 0;
-  i = 0;
-  is_dmrs_symbol1 = 0;
-  is_dmrs_symbol2 = 0;
-  l_ref = start_symbol;
-  last_symbol = start_symbol + duration_in_symbols - 1;
+  uint8_t i = 0, last_symbol, is_dmrs_symbol, l_ref;
+  int8_t l_counter;
+  l_ref         = start_symbol;
+  last_symbol   = start_symbol + duration_in_symbols - 1;
 
   while ( (l_ref + i*L_ptrs) <= last_symbol) {
 
-    is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
-                                     0,
-                                     0,
-                                     0,
-                                     0,
-                                     0,
-                                     duration_in_symbols,
-                                     dmrs_type,
-                                     ofdm_symbol_size);
-
-    is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
-                                     0,
-                                     0,
-                                     0,
-                                     0,
-                                     0,
-                                     duration_in_symbols,
-                                     dmrs_type,
-                                     ofdm_symbol_size);
-
-    if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
-
-      if (pusch_maxLength == 2)
-        l_ref = l_ref + i*L_ptrs + 1;
-      else
-        l_ref = l_ref + i*L_ptrs;
-
-       i = 1;
-
-       continue;
+    is_dmrs_symbol = 0;
+
+    for(l_counter = l_ref + i*L_ptrs; l_counter >= max(l_ref + (i-1)*L_ptrs + 1, l_ref); l_counter--) {
 
+      if((ul_dmrs_symb_pos >> l_counter) & 0x01) {
+        is_dmrs_symbol = 1;
+        break;
+      }
+
+    }
+
+    if (is_dmrs_symbol) {
+      l_ref = l_counter;
+      i     = 1;
+      continue;
     }
 
     *ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
@@ -192,53 +134,19 @@ void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
   }
 }
 
-/*******************************************************************
-*
-* NAME :         get_L_ptrs
-*
-* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
-*                I_mcs                  MCS index used for PUSCH
-*
-* RETURN :       the parameter L_ptrs
-*
-* DESCRIPTION :  3GPP TS 38.214 6.2.3 Table 6.2.3.1-1
-*
-*********************************************************************/
-
-uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs) {
-
-	uint8_t mcs1, mcs2, mcs3;
-
-	mcs1 = ptrs_UplinkConfig->timeDensity.ptrs_mcs1;
-	mcs2 = ptrs_UplinkConfig->timeDensity.ptrs_mcs2;
-	mcs3 = ptrs_UplinkConfig->timeDensity.ptrs_mcs3;
-
-	if (mcs1 == 0 || mcs2 == 0 || mcs3 == 0)
-		return 1;
-
-	if (I_mcs < mcs1){
-		LOG_I(PHY,"PUSH PT-RS is not present.\n");
-		return 0;
-	}
-	else if (I_mcs >= mcs1 && I_mcs < mcs2)
-		return 4;
-	else if (I_mcs >= mcs2 && I_mcs < mcs3)
-		return 2;
-	else
-		return 1;
-}
-
 /*******************************************************************
 *
 * NAME :         is_ptrs_subcarrier
 *
 * PARAMETERS : k                      subcarrier index
-*              K_ptrs                 the parameter K_ptrs
 *              n_rnti                 UE CRNTI
+*              dmrs_antenna_port      DMRS antenna port
+*              K_ptrs                 the parameter K_ptrs
+*              pusch_dmrs_type        the DMRS configuration type used for PUSCH
 *              N_RB                   number of RBs scheduled for PUSCH
 *              k_RE_ref               the parameter k_RE_ref
 *              start_sc               first subcarrier index
-*              ofdm_symbol_size       FFT size
+*              ofdm_symbol_size       number of samples in an OFDM symbol
 *
 * RETURN :       1 if subcarrier k is PTRS, or 0 otherwise
 *
@@ -246,107 +154,48 @@ uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs) {
 *
 *********************************************************************/
 
-uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size) {
-
-	uint16_t k_RB_ref, i, sc;
-
-	i = 0;
-	sc = 0;
-	k_RB_ref = 0;
-
-	if (N_RB % K_ptrs == 0)
-		k_RB_ref = n_rnti % K_ptrs;
-	else
-		k_RB_ref = n_rnti % (N_RB % K_ptrs);
-
-	while (k > sc){
-
-		sc = (start_sc + k_RE_ref + (i*K_ptrs + k_RB_ref)*NR_NB_SC_PER_RB)%ofdm_symbol_size;
-		i++;
-
-	}
-
-	if (k == sc)
-        return 1;
-	else
-        return 0;
-
-}
-
-/*******************************************************************
-*
-* NAME :         is_ptrs_symbol
-*
-* PARAMETERS : l                      ofdm symbol index within slot
-*              k                      subcarrier index
-*              n_rnti                 UE CRNTI
-*              N_RB                   number of RBs scheduled for PUSCH
-*              duration_in_symbols    number of scheduled PUSCH ofdm symbols
-*              dmrs_antenna_port      DMRS antenna port
-*              K_ptrs                 the parameter K_ptrs
-*              ptrs_symbols           bit mask of ptrs
-*              start_sc               first subcarrier index
-*              ofdm_symbol_size       FFT size
-*              pusch_dmrs_type        PUSCH DMRS type (1 or 2)
-*              ptrs_UplinkConfig      PTRS uplink configuration
-*
-* RETURN :       0 if symbol(k,l) is data, or 1 if symbol(k,l) is ptrs
-*
-* DESCRIPTION :  3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH
-*
-*********************************************************************/
-
-uint8_t is_ptrs_symbol(uint8_t l,
-                       uint16_t k,
-                       uint16_t n_rnti,
-                       uint16_t N_RB,
-                       uint8_t duration_in_symbols,
-                       uint8_t dmrs_antenna_port,
-                       uint8_t K_ptrs,
-                       uint16_t ptrs_symbols,
-                       uint16_t start_sc,
-                       uint16_t ofdm_symbol_size,
-                       pusch_dmrs_type_t pusch_dmrs_type,
-                       uint8_t resourceElementOffset) {
-
-  uint8_t is_ptrs_freq, is_ptrs_time;
-  int16_t k_RE_ref;
-
-  is_ptrs_freq = 0;
-  is_ptrs_time = 0;
-
-  k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, resourceElementOffset);
-
-  is_ptrs_freq = is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref, start_sc, ofdm_symbol_size);
+uint8_t is_ptrs_subcarrier(uint16_t k,
+                           uint16_t n_rnti,
+                           uint8_t dmrs_antenna_port,
+                           uint8_t pusch_dmrs_type,
+                           uint8_t K_ptrs,
+                           uint16_t N_RB,
+                           uint8_t k_RE_ref,
+                           uint16_t start_sc,
+                           uint16_t ofdm_symbol_size)
+{
+  // int16_t k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, resourceElementOffset);
+  uint16_t k_RB_ref;
 
-  if (is_ptrs_freq == 0)
-    return 0;
+  if (N_RB % K_ptrs == 0)
+    k_RB_ref = n_rnti % K_ptrs;
+  else
+    k_RB_ref = n_rnti % (N_RB % K_ptrs);
 
-  if (((ptrs_symbols>>l)&1) == 1)
-    is_ptrs_time = 1;
+  if (k < start_sc)
+    k += ofdm_symbol_size;
 
-  if (is_ptrs_time && is_ptrs_freq)
+  if ((k - k_RE_ref - k_RB_ref*NR_NB_SC_PER_RB - start_sc) % (K_ptrs*NR_NB_SC_PER_RB) == 0)
     return 1;
-  else
-    return 0;
 
+  return 0;
 }
 
 /*
 int main(int argc, char const *argv[])
 {
 
-	dmrs_UplinkConfig_t dmrs_Uplink_Config;
-	ptrs_UplinkConfig_t ptrs_Uplink_Config;
-	uint8_t resourceElementOffset;
-	uint8_t dmrs_antenna_port;
-	uint8_t L_ptrs, K_ptrs;
-	int16_t k_RE_ref;
-	uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k;
-	uint8_t duration_in_symbols, I_mcs;
-	uint8_t start_symbol, l;
-	uint8_t ptrs_symbol_flag;
-	uint16_t n_rnti;
+  dmrs_UplinkConfig_t dmrs_Uplink_Config;
+  ptrs_UplinkConfig_t ptrs_Uplink_Config;
+  uint8_t resourceElementOffset;
+  uint8_t dmrs_antenna_port;
+  uint8_t L_ptrs, K_ptrs;
+  int16_t k_RE_ref;
+  uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k;
+  uint8_t duration_in_symbols, I_mcs;
+  uint8_t start_symbol, l;
+  uint8_t ptrs_symbol_flag;
+  uint16_t n_rnti;
 
     dmrs_Uplink_Config.pusch_dmrs_type = pusch_dmrs_type1;
     dmrs_Uplink_Config.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos1;
@@ -362,13 +211,13 @@ int main(int argc, char const *argv[])
     n_rnti = 0x1234;
     resourceElementOffset = 0;
     ptrs_symbols = 0;
-	dmrs_antenna_port = 0;
-	N_RB = 50;
-	duration_in_symbols = 14;
-	ofdm_symbol_size = 2048;
-	I_mcs = 9;
-	start_symbol = 0;
-	ptrs_symbol_flag = 0;
+  dmrs_antenna_port = 0;
+  N_RB = 50;
+  duration_in_symbols = 14;
+  ofdm_symbol_size = 2048;
+  I_mcs = 9;
+  start_symbol = 0;
+  ptrs_symbol_flag = 0;
 
     k_RE_ref = get_kRE_ref(dmrs_antenna_port, dmrs_Uplink_Config.pusch_dmrs_type, resourceElementOffset);
 
@@ -418,6 +267,6 @@ int main(int argc, char const *argv[])
 
     printf("\n");
 
-	return 0;
+  return 0;
 }
 */
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h
index 291ff4a5558..e8a4e612322 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h
@@ -49,32 +49,36 @@
 
 int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t resourceElementOffset);
 
-uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB);
-
 void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
                        uint8_t duration_in_symbols,
                        uint8_t start_symbol,
-                       uint8_t dmrs_type,
                        uint8_t L_ptrs,
-                       uint8_t pusch_maxLength,
-                       uint16_t ofdm_symbol_size);
-
-uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs);
-
-uint8_t is_ptrs_subcarrier(uint16_t k, uint8_t K_ptrs, uint16_t n_rnti, uint16_t N_RB, int16_t k_RE_ref, uint16_t start_sc, uint16_t ofdm_symbol_size);
+                       uint16_t ul_dmrs_symb_pos);
+
+uint8_t is_ptrs_subcarrier(uint16_t k,
+                           uint16_t n_rnti,
+                           uint8_t dmrs_antenna_port,
+                           uint8_t pusch_dmrs_type,
+                           uint8_t K_ptrs,
+                           uint16_t N_RB,
+                           uint8_t k_RE_ref,
+                           uint16_t start_sc,
+                           uint16_t ofdm_symbol_size);
+
+/*******************************************************************
+*
+* NAME :         is_ptrs_symbol
+*
+* PARAMETERS : l                      ofdm symbol index within slot
+*              ptrs_symbols           bit mask of ptrs
+*
+* RETURN :       1 if symbol is ptrs, or 0 otherwise
+*
+* DESCRIPTION :  3GPP TS 38.211 6.4.1.2 Phase-tracking reference signal for PUSCH
+*
+*********************************************************************/
 
-uint8_t is_ptrs_symbol(uint8_t l,
-                       uint16_t k,
-                       uint16_t n_rnti,
-                       uint16_t N_RB,
-                       uint8_t duration_in_symbols,
-                       uint8_t dmrs_antenna_port,
-                       uint8_t K_ptrs,
-                       uint16_t ptrs_symbols,
-                       uint16_t start_sc,
-                       uint16_t ofdm_symbol_size,
-                       pusch_dmrs_type_t pusch_dmrs_type,
-                       uint8_t resourceElementOffset);
+static inline uint8_t is_ptrs_symbol(uint8_t l, uint16_t ptrs_symbols) { return ((ptrs_symbols >> l) & 1); }
 
 
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index ccec73d40e9..c7b14571b7d 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -137,7 +137,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
 
 
   int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
-  int C;
+  int C=-1;
 
   for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
     int  L = pdcch_pdu_rel15->AggregationLevel[d];
@@ -210,7 +210,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
 
   for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
 
-    uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+    //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
 
 
     int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
@@ -248,7 +248,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
 
   for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
 
-    uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+    //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
 
     // if there's no DL DCI then generate CCE list
     if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);  
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 856a7863f43..f1208641842 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -64,7 +64,6 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
       a_segments = a_segments/273;
     }  
 
-    uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
 
 
 #ifdef DEBUG_DLSCH_FREE
@@ -82,7 +81,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
 #endif
 
         if (dlsch->harq_processes[i]->b) {
-          free16(dlsch->harq_processes[i]->b,dlsch_bytes);
+          free16(dlsch->harq_processes[i]->b,a_segments*1056);
           dlsch->harq_processes[i]->b = NULL;
 #ifdef DEBUG_DLSCH_FREE
           LOG_D(PHY,"Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index 5710499e1ae..5c4d048a77a 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -175,39 +175,39 @@ void rx_nr_prach_ru(RU_t *ru,
 	//50 MHz @ 61.44 Ms/s
 	prach2 = prach[aa] + (Ncp<<2);
 	if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
-	  dft49152(prach2,rxsigF[aa],1);
+	  dft(DFT_49152,prach2,rxsigF[aa],1);
 	if (prach_fmt == 1 || prach_fmt == 2) {
-	  dft49152(prach2+98304,rxsigF[aa]+98304,1);
+	  dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
 	  reps++;
 	}
 	if (prach_fmt == 2) {
-	  dft49152(prach2+(98304*2),rxsigF[aa]+(98304*2),1);
-	  dft49152(prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+	  dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+	  dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
 	  reps+=2;
 	}
 	if (prach_fmt == 3) { 
-	  for (int i=0;i<4;i++) dft12288(prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
+	  for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
 	  reps=4;
 	}
 	if (prach_fmt >3) {
-	  dft2048(prach2,rxsigF[aa],1);
+	  dft(DFT_2048,prach2,rxsigF[aa],1);
 	  if (prach_fmt != 0xc0) {
-	    dft2048(prach2+4096,rxsigF[aa]+4096,1);
+	    dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
 	    reps++;
 	  }
 	} 
 	if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {     
-	  dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1);
-	  dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1);
+	  dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
+	  dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {     
-	  dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1);
-	  dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1);
+	  dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
+	  dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xc2) {
-	  for (int i=6;i<11;i++) dft2048(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+	  for (int i=6;i<11;i++) dft(DFT_2048,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
 	  reps+=6;
 	}
       } else {
@@ -215,41 +215,41 @@ void rx_nr_prach_ru(RU_t *ru,
 	prach2 = prach[aa] + (3*Ncp);
 	AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
 	if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
-	  dft36864(prach2,rxsigF[aa],1);
+	  dft(DFT_36864,prach2,rxsigF[aa],1);
 	  reps++;
 	}
 	if (prach_fmt == 1 || prach_fmt == 2) {
-	  dft36864(prach2+73728,rxsigF[aa]+73728,1);
+	  dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
 	  reps++;
 	}
 	if (prach_fmt == 2) {
-	  dft36864(prach2+(98304*2),rxsigF[aa]+(98304*2),1);
-	  dft36864(prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+	  dft(DFT_36864,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+	  dft(DFT_36864,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
 	  reps+=2;
 	}
 	if (prach_fmt == 3) {
-	  for (int i=0;i<4;i++) dft9216(prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
+	  for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
 	  reps=4;
 	}
 	if (prach_fmt >3) {
-	  dft1536(prach2,rxsigF[aa],1);
+	  dft(DFT_1536,prach2,rxsigF[aa],1);
 	  if (prach_fmt != 0xc0) {
-	    dft1536(prach2+3072,rxsigF[aa]+3072,1);
+	    dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
 	    reps++;
 	  }
 	}  
 	if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {     
-	  dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1);
-	  dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1);
+	  dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
+	  dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {     
-	  dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1);
-	  dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1);
+	  dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
+	  dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xc2) {
-	  for (int i=6;i<11;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+	  for (int i=6;i<11;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
 	  reps+=6;
 	}
       }
@@ -260,41 +260,41 @@ void rx_nr_prach_ru(RU_t *ru,
 	dftlen=98304;
 	//80,90,100 MHz @ 61.44 Ms/s 
 	if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
-	  dft98304(prach2,rxsigF[aa],1);
+	  dft(DFT_98304,prach2,rxsigF[aa],1);
 	if (prach_fmt == 1 || prach_fmt == 2) {
-	  dft98304(prach2+196608,rxsigF[aa]+196608,1);
+	  dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
 	  reps++;
 	}
 	if (prach_fmt == 1 || prach_fmt == 2) {
-	  dft98304(prach2+196608,rxsigF[aa]+196608,1);
-	  dft98304(prach2+(196608*2),rxsigF[aa]+(196608*2),1);
+	  dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
+	  dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
 	  reps+=2;
 	}
 	if (prach_fmt == 3) {
-	  dft24576(prach2+(2*49152),rxsigF[aa]+(2*49152),1);
+	  dft(DFT_24576,prach2+(2*49152),rxsigF[aa]+(2*49152),1);
 	  reps=4;
 	  dftlen=24576;
 	}
 	if (prach_fmt >3) {
 	  dftlen=4096;
-	  dft4096(prach2,rxsigF[aa],1);
+	  dft(DFT_4096,prach2,rxsigF[aa],1);
 	  if (prach_fmt != 0xc0) { 
-	    dft4096(prach2+8192,rxsigF[aa]+8192,1);
+	    dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
 	    reps++;
 	  }
 	} 
 	if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {     
-	  dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1);
-	  dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1);
+	  dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
+	  dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {     
-	  dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1);
-	  dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1);
+	  dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
+	  dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xc2) {
-	  for (int i=6;i<11;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1);
+	  for (int i=6;i<11;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
 	  reps+=6;
 	}
       } else {
@@ -303,39 +303,39 @@ void rx_nr_prach_ru(RU_t *ru,
 	//	80 MHz @ 46.08 Ms/s
 	dftlen=73728;
 	if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
-	  dft73728(prach2,rxsigF[aa],1);
+	  dft(DFT_73728,prach2,rxsigF[aa],1);
 	  reps++;
 	}
 	if (prach_fmt == 1 || prach_fmt == 2) {
-	  dft73728(prach2+(2*73728),rxsigF[aa]+(2*73728),1);
+	  dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
 	  reps++;
 	}
 	if (prach_fmt == 3) {
-	  dft73728(prach2+(4*73728),rxsigF[aa]+(4*73728),1);
+	  dft(DFT_73728,prach2+(4*73728),rxsigF[aa]+(4*73728),1);
 	  reps=4;
 	  dftlen=18432;
 	}
 
 	if (prach_fmt >3) {
 	  dftlen=3072;
-	  dft3072(prach2,rxsigF[aa],1);
+	  dft(DFT_3072,prach2,rxsigF[aa],1);
 	  if (prach_fmt != 0xc0) {
-	    dft3072(prach2+6144,rxsigF[aa]+6144,1);
+	    dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
 	    reps++;
 	  }
 	} 
 	if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {     
-	  dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1);
-	  dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1);
+	  dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
+	  dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {     
-	  dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1);
-	  dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1);
+	  dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
+	  dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
 	  reps+=2;
 	} 
 	if (prach_fmt == 0xc2) {
-	  for (int i=6;i<11;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1);
+	  for (int i=6;i<11;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
 	  reps+=6;
 	}
       }
@@ -366,6 +366,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
 		 uint16_t *max_preamble_delay
 		 )
 {
+  AssertFatal(gNB!=NULL,"Can only be called from gNB\n");
 
   int i;
 
@@ -405,7 +406,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
   
   nr_frequency_range_e freq_range;
 
-  AssertFatal(gNB!=NULL,"Can only be called from gNB\n");
   fp    = &gNB->frame_parms;
   nb_rx = fp->nb_antennas_rx;
   
@@ -420,8 +420,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
   uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,freq_range);
   uint16_t N_ZC = (prach_fmt <4)?839:139;
 
-  AssertFatal(gNB!=NULL,"gNB is null\n");
-
   prach_ifft        = gNB->prach_vars.prach_ifft;
   prachF            = gNB->prach_vars.prachF;
   if (LOG_DEBUGFLAG(PRACH)){
@@ -456,8 +454,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
 
   AssertFatal(NCS!=99,"NCS has not been set\n");
 
-  if (gNB) start_meas(&gNB->rx_prach);
-
+  start_meas(&gNB->rx_prach);
 
   prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
 
@@ -590,12 +587,12 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
 	// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
 	if (N_ZC == 839) {
 	  log2_ifft_size = 10;
-	  idft1024(prachF,prach_ifft_tmp,1);
+	  idft(IDFT_1024,prachF,prach_ifft_tmp,1);
 	  // compute energy and accumulate over receive antennas
 	  for (i=0;i<2048;i++)
 	    prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
 	} else {
-	  idft256(prachF,prach_ifft_tmp,1);
+	  idft(IDFT_256,prachF,prach_ifft_tmp,1);
 	  log2_ifft_size = 8;
 	  // compute energy and accumulate over receive antennas and repetitions for BR
 	  for (i=0;i<256;i++)
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h
index be738750588..98e5930c4c3 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h
@@ -123,4 +123,32 @@ void rx_nr_prach_ru(RU_t *ru,
 		    int frame,
 		    int subframe);
 
+void compute_nr_prach_seq(uint16_t rootSequenceIndex,
+			  uint8_t prach_ConfigIndex,
+			  uint8_t zeroCorrelationZoneConfig,
+			  uint8_t highSpeedFlag,
+			  lte_frame_type_t frame_type,
+			  nr_frequency_range_e fr,
+			  uint32_t X_u[64][839]);
+
+void nr_decode_pucch1(int32_t **rxdataF,
+                      pucch_GroupHopping_t pucch_GroupHopping,
+                      uint32_t n_id,       // hoppingID higher layer parameter
+                      uint64_t *payload,
+                      NR_DL_FRAME_PARMS *frame_parms,
+                      int16_t amp,
+                      int nr_tti_tx,
+                      uint8_t m0,
+                      uint8_t nrofSymbols,
+                      uint8_t startingSymbolIndex,
+                      uint16_t startingPRB,
+                      uint16_t startingPRB_intraSlotHopping,
+                      uint8_t timeDomainOCC,
+                      uint8_t nr_bit);
+
+void nr_decode_pucch0(PHY_VARS_gNB *gNB,
+		      int slot,
+                      nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
+                      nfapi_nr_pucch_pdu_t* pucch_pdu);
+
 #endif /*__NR_TRANSPORT__H__*/
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 762346048f9..ab5b0c38acf 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -41,7 +41,19 @@
 #define NR_PUSCH_y 3 // UCI placeholder bit 
 
 
+void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
+                               uint32_t n_id,
+                               uint8_t n_hop,
+                               int nr_tti_tx,
+                               uint8_t *u,
+                               uint8_t *v);
 
+double nr_cyclic_shift_hopping(uint32_t n_id,
+                               uint8_t m0,
+                               uint8_t mcs,
+                               uint8_t lnormal,
+                               uint8_t lprime,
+                               int nr_tti_tx);
 
 
 /** \brief Computes available bits G. */
@@ -49,4 +61,5 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint
 
 uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
 
+void init_pucch2_luts(void);
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
index dd37455e262..fe61733f49a 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
@@ -29,8 +29,8 @@
  * \note
  * \warning
  */
-#ifndef __NR_TRANSPORT_PROTO_UE__H__
-#define __NR_TRANSPORT_PROTO_UE__H__
+#ifndef __NR_TRANSPORT_PROTO_COMMON_H__
+#define __NR_TRANSPORT_PROTO_COMMON_H__
 #include "PHY/defs_nr_UE.h"
 #include "SCHED_NR_UE/defs.h"
 //#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
@@ -43,29 +43,6 @@
  * @{
  */
 
-/** \fn free_ue_dlsch(NR_UE_DLSCH_t *dlsch)
-    \brief This function frees memory allocated for a particular DLSCH at UE
-    @param dlsch Pointer to DLSCH to be removed
-*/
-void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
-
-/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
-    \brief This function allocates structures for a particular DLSCH at UE
-    @returns Pointer to DLSCH to be removed
-    @param Kmimo Kmimo factor from 36-212/36-213
-    @param Mdlharq Maximum number of HARQ rounds (36-212/36-213)
-    @param Nsoft Soft-LLR buffer size from UE-Category
-    @params N_RB_DL total number of resource blocks (determine the operating BW)
-    @param abstraction_flag Flag to indicate abstracted interface
-*/
-NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
-
-
-void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch);
-
-
-NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
-
 void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
 
 int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
@@ -1051,25 +1028,6 @@ uint32_t  nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                          uint8_t is_crnti,
                          uint8_t llr8_flag);
 
-int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
-                     NR_DL_FRAME_PARMS* frame_parms,
-                     uint8_t harq_pid);
-
-/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
-  @param[in] in Pointer to input bits
-  @param[in] size of input bits
-  @param[in] Nid cell id
-  @param[in] n_RNTI CRNTI
-  @param[out] out the scrambled bits
-*/
-
-void nr_pusch_codeword_scrambling(uint8_t *in,
-                         uint16_t size,
-                         uint32_t Nid,
-                         uint32_t n_RNTI,
-                         uint32_t* out);
-
-
 uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 						 UE_nr_rxtx_proc_t *proc,
                          int eNB_id,
@@ -1128,17 +1086,6 @@ int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
                  uint8_t i_mod,
                  uint8_t harq_pid);
 
-int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
-                    uint32_t frame,
-                    uint8_t nr_tti_rx,
-                    uint8_t eNB_id,
-                    MIMO_mode_t mimo_mode,
-                    uint32_t high_speed_flag,
-                    uint8_t is_secondary_ue,
-                    int nb_coreset_active,
-                    uint16_t symbol_mon,
-                    NR_SEARCHSPACE_TYPE_t searchSpaceType);
-
 /*! \brief Extract PSS and SSS resource elements
   @param phy_vars_ue Pointer to UE variables
   @param[out] pss_ext contain the PSS signals after the extraction
@@ -1471,18 +1418,6 @@ void init_transport_channels(uint8_t);
 
 void generate_RIV_tables(void);
 
-/*!
-  \brief This function performs the initial cell search procedure - PSS detection, SSS detection and PBCH detection.  At the
-  end, the basic frame parameters are known (Frame configuration - TDD/FDD and cyclic prefix length,
-  N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest.  Once these
-  parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.)
-  @param phy_vars_ue Pointer to UE variables
-  @param mode current running mode
-*/
-int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
-                    PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
-
-
 /*!
   \brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
   @param a Pointer to ulsch SDU
@@ -1724,10 +1659,6 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
 			     uint8_t n_ra_prboffset,
 			     uint8_t tdd_mapindex, uint16_t Nf);
 
-void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx,
-			   int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common);
-
-
 uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
 
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index e8a961360f4..6c6ff4fd05b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -70,13 +70,12 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
       a_segments = a_segments/273;
     }  
 
-    uint16_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
 
     for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
 
       if (ulsch->harq_processes[i]) {
         if (ulsch->harq_processes[i]->b) {
-          free16(ulsch->harq_processes[i]->b,ulsch_bytes);
+          free16(ulsch->harq_processes[i]->b,a_segments*1056);
           ulsch->harq_processes[i]->b = NULL;
         }
         for (r=0; r<a_segments; r++) {
@@ -458,9 +457,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
   for (r=0; r<harq_process->C; r++) {
     E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
 
-#if gNB_TIMING_TRACE
-    start_meas(ulsch_deinterleaving_stats);
-#endif
+
+    start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
 
     ////////////////////////////////////////////////////////////////////////////////////////////
     ///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
@@ -476,13 +474,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
     //for (int i =0; i<16; i++)
     //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
 
-#if gNB_TIMING_TRACE
-    stop_meas(ulsch_deinterleaving_stats);
-#endif
+    stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
 
-#if gNB_TIMING_TRACE
-    start_meas(ulsch_rate_unmatching_stats);
-#endif
 
 #ifdef DEBUG_ULSCH_DECODING
     LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
@@ -504,6 +497,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
     ///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
 
+    start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
+
     Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
 
     if (nr_rate_matching_ldpc_rx(Ilbrm,
@@ -518,15 +513,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
                                  E,
 				 harq_process->F,
 				 Kr-harq_process->F-2*(p_decParams->Z))==-1) {
-#if gNB_TIMING_TRACE
-      stop_meas(ulsch_rate_unmatching_stats);
-#endif
+
+      stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
+
       LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
       return (ulsch->max_ldpc_iterations + 1);
     } else {
-#if gNB_TIMING_TRACE
-      stop_meas(ulsch_rate_unmatching_stats);
-#endif
+      stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
     }
 
     r_offset += E;
@@ -564,9 +557,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
 
     if (err_flag == 0) {
 
-#if gNB_TIMING_TRACE
-      start_meas(ulsch_turbo_decoding_stats);
-#endif
+      start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
 
       //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
 
@@ -636,9 +627,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
       //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
 #endif
 
-#if gNB_TIMING_TRACE
-      stop_meas(ulsch_turbo_decoding_stats);
-#endif
+      stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
     }
 
     if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index bce8ddcc291..363b67960da 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -44,7 +44,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
 
   switch (Msc_PUSCH) {
     case 12:
-      dft12((int16_t *)idft_in0, (int16_t *)idft_out0);
+      dft(DFT_12,(int16_t *)idft_in0, (int16_t *)idft_out0,0);
 
 #if defined(__x86_64__)||defined(__i386__)
       norm128 = _mm_set1_epi16(9459);
@@ -63,135 +63,135 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
       break;
 
     case 24:
-      dft24(idft_in0, idft_out0, 1);
+      dft(DFT_24,idft_in0, idft_out0, 1);
       break;
 
     case 36:
-      dft36(idft_in0, idft_out0, 1);
+      dft(DFT_36,idft_in0, idft_out0, 1);
       break;
 
     case 48:
-      dft48(idft_in0, idft_out0, 1);
+      dft(DFT_48,idft_in0, idft_out0, 1);
       break;
 
     case 60:
-      dft60(idft_in0, idft_out0, 1);
+      dft(DFT_60,idft_in0, idft_out0, 1);
       break;
 
     case 72:
-      dft72(idft_in0, idft_out0, 1);
+      dft(DFT_72,idft_in0, idft_out0, 1);
       break;
 
     case 96:
-      dft96(idft_in0, idft_out0, 1);
+      dft(DFT_96,idft_in0, idft_out0, 1);
       break;
 
     case 108:
-      dft108(idft_in0, idft_out0, 1);
+      dft(DFT_108,idft_in0, idft_out0, 1);
       break;
 
     case 120:
-      dft120(idft_in0, idft_out0, 1);
+      dft(DFT_120,idft_in0, idft_out0, 1);
       break;
 
     case 144:
-      dft144(idft_in0, idft_out0, 1);
+      dft(DFT_144,idft_in0, idft_out0, 1);
       break;
 
     case 180:
-      dft180(idft_in0, idft_out0, 1);
+      dft(DFT_180,idft_in0, idft_out0, 1);
       break;
 
     case 192:
-      dft192(idft_in0, idft_out0, 1);
+      dft(DFT_192,idft_in0, idft_out0, 1);
       break;
 
     case 216:
-      dft216(idft_in0, idft_out0, 1);
+      dft(DFT_216,idft_in0, idft_out0, 1);
       break;
 
     case 240:
-      dft240(idft_in0, idft_out0, 1);
+      dft(DFT_240,idft_in0, idft_out0, 1);
       break;
 
     case 288:
-      dft288(idft_in0, idft_out0, 1);
+      dft(DFT_288,idft_in0, idft_out0, 1);
       break;
 
     case 300:
-      dft300(idft_in0, idft_out0, 1);
+      dft(DFT_300,idft_in0, idft_out0, 1);
       break;
 
     case 324:
-      dft324((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_324,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 360:
-      dft360((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_360,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 384:
-      dft384((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_384,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 432:
-      dft432((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_432,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 480:
-      dft480((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_480,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 540:
-      dft540((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_540,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 576:
-      dft576((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_576,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 600:
-      dft600((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_600,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 648:
-      dft648((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_648,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 720:
-      dft720((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_720,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 768:
-      dft768((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_768,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 864:
-      dft864((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_864,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 900:
-      dft900((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_900,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 960:
-      dft960((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_960,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 972:
-      dft972((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_972,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 1080:
-      dft1080((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_1080,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 1152:
-      dft1152((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
+      dft(DFT_1152,(int16_t*)idft_in0, (int16_t*)idft_out0, 1);
       break;
 
     case 1200:
-      dft1200(idft_in0, idft_out0, 1);
+      dft(DFT_1200,idft_in0, idft_out0, 1);
       break;
 
     default:
@@ -284,19 +284,17 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
       else
         is_dmrs_re = 0;
 
-      if ( ((pusch_pdu->pdu_bit_map)>>2)& 0x01 ) {
-        is_ptrs_symbol_flag = is_ptrs_symbol(symbol,
-                                             (start_re + re)%frame_parms->ofdm_symbol_size,
-                                             n_rnti,
-                                             pusch_pdu->rb_size,
-                                             pusch_pdu->nr_of_symbols,
-                                             aarx,
-                                             K_ptrs,
-                                             pusch_vars->ptrs_symbols,
-                                             start_re,
-                                             frame_parms->ofdm_symbol_size,
-                                             pusch_pdu->dmrs_config_type,
-                                             pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
+      if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+        if(is_ptrs_symbol(symbol, pusch_vars->ptrs_symbols))
+            is_ptrs_symbol_flag = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
+                                                     n_rnti,
+                                                     aarx,
+                                                     pusch_pdu->dmrs_config_type,
+                                                     K_ptrs,
+                                                     pusch_pdu->rb_size,
+                                                     pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
+                                                     start_re,
+                                                     frame_parms->ofdm_symbol_size);
 
         if (is_ptrs_symbol_flag == 1)
           num_ptrs_symbols++;
@@ -304,7 +302,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
       }
 
   #ifdef DEBUG_RB_EXT
-      printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol);
+      printf("re = %d, is_ptrs_symbol_flag = %d, symbol = %d\n", re, is_ptrs_symbol_flag, symbol);
   #endif
 
       if ( is_dmrs_re == 0 && is_ptrs_symbol_flag == 0) {
@@ -315,8 +313,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
         ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
 
   #ifdef DEBUG_RB_EXT
-        printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]);
-        printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]);
+        printf("rxF_ext[%d] = %d, %d\n", rxF_ext_index, rxF_ext[rxF_ext_index], rxF_ext[rxF_ext_index+1]);
   #endif
 
         ul_ch0_ext_index++;
@@ -1026,7 +1023,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                  unsigned char harq_pid)
 {
 
-  uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
+  uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
   uint32_t nb_re_pusch, bwp_start_subcarrier;
   uint8_t L_ptrs = 0; // PTRS parameter
   int avgs;
@@ -1035,7 +1032,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
   nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu;
 
   dmrs_symbol_flag = 0;
-  ptrs_symbol_flag = 0;
   first_symbol_flag = 0;
   gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
 
@@ -1046,16 +1042,14 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
     gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
     first_symbol_flag = 1;
 
-    if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) {  // if there is ptrs pdu
+    if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {  // if there is ptrs pdu
       L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
 
       set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols,
                         rel15_ul->nr_of_symbols,
                         rel15_ul->start_symbol_index,
-                        rel15_ul->dmrs_config_type,
                         L_ptrs,
-                        1, // only dmrs of length 1 is currently supported
-                        frame_parms->ofdm_symbol_size);
+                        rel15_ul->ul_dmrs_symb_pos);
     }
   }
 
@@ -1070,30 +1064,16 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
     nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
   }
 
-  if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) {  // if there is ptrs pdu
-    ptrs_symbol_flag = is_ptrs_symbol(symbol,
-                                      0,
-                                      rel15_ul->rnti,
-                                      rel15_ul->rb_size,
-                                      rel15_ul->nr_of_symbols,
-                                      0,
-                                      (rel15_ul->pusch_ptrs.ptrs_freq_density)?4:2,
-                                      gNB->pusch_vars[UE_id]->ptrs_symbols,
-                                      0,
-                                      frame_parms->ofdm_symbol_size,
-                                      rel15_ul->dmrs_config_type,
-                                      rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
-  }
-
-  if (ptrs_symbol_flag == 1){
-    gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
+  if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {  // if there is ptrs pdu
+    if(is_ptrs_symbol(symbol, gNB->pusch_vars[UE_id]->ptrs_symbols))
+      gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
   }
 
 
   //----------------------------------------------------------
   //--------------------- Channel estimation ---------------------
   //----------------------------------------------------------
-
+  start_meas(&gNB->ulsch_channel_estimation_stats);
   if (dmrs_symbol_flag == 1)
     nr_pusch_channel_estimation(gNB,
                                 nr_tti_rx,
@@ -1101,17 +1081,19 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                                 symbol,
                                 bwp_start_subcarrier,
                                 rel15_ul);
-
+  stop_meas(&gNB->ulsch_channel_estimation_stats);
   //----------------------------------------------------------
   //--------------------- RBs extraction ---------------------
   //----------------------------------------------------------
 
+  start_meas(&gNB->ulsch_rbs_extraction_stats);
   nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
                               gNB->pusch_vars[UE_id],
                               symbol,
                               dmrs_symbol_flag,
                               rel15_ul,
                               frame_parms);
+  stop_meas(&gNB->ulsch_rbs_extraction_stats);
 
   nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
                          frame_parms,
@@ -1140,6 +1122,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
 
   }
 
+  start_meas(&gNB->ulsch_channel_compensation_stats);
   nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
                                 gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
                                 gNB->pusch_vars[UE_id]->ul_ch_mag0,
@@ -1152,6 +1135,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                                 rel15_ul->qam_mod_order,
                                 rel15_ul->rb_size,
                                 gNB->pusch_vars[UE_id]->log2_maxh);
+  stop_meas(&gNB->ulsch_channel_compensation_stats);
 
 #ifdef NR_SC_FDMA
   nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
@@ -1160,7 +1144,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
   //----------------------------------------------------------
   //-------------------- LLRs computation --------------------
   //----------------------------------------------------------
-
+  start_meas(&gNB->ulsch_llr_stats);
   nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
                        gNB->pusch_vars[UE_id]->ul_ch_mag0,
                        gNB->pusch_vars[UE_id]->ul_ch_magb0,
@@ -1169,6 +1153,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
                        nb_re_pusch,
                        symbol,
                        rel15_ul->qam_mod_order);
+  stop_meas(&gNB->ulsch_llr_stats);
 
   gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset +  nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
   
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index b74b078dfd6..6dfbffc46e2 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -1,3 +1,34 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_TRANSPORT/pucch_rx.c
+* \brief Top-level routines for decoding the PUCCH physical channel
+* \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
+* \date 2020
+* \version 0.2
+* \company Eurecom
+* \email:
+* \note
+* \warning
+*/
 #include<stdio.h>
 #include <string.h>
 #include <math.h>
@@ -8,38 +39,113 @@
 
 #include "PHY/impl_defs_nr.h"
 #include "PHY/defs_nr_common.h"
-#include "PHY/defs_nr_UE.h"
+#include "PHY/defs_gNB.h"
+#include "PHY/sse_intrin.h"
 #include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
-#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
-
+#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_REFSIG/nr_refsig.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
 #include "T.h"
 
+//#define DEBUG_NR_PUCCH_RX 1
+
+int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) {
+
+  int i=0;
+
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("getting index for LUT with %d entries, Nid %d\n",gNB->pucch0_lut.nb_id, pucch_pdu->hopping_id);
+#endif
+
+  for (i=0;i<gNB->pucch0_lut.nb_id;i++) {
+    if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id) break;
+  }
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("found index %d\n",i);
+#endif
+  if (i<gNB->pucch0_lut.nb_id) return(i);
+
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("Initializing PUCCH0 LUT index %i with Nid %d\n",i, pucch_pdu->hopping_id);
+#endif
+  // initialize
+  gNB->pucch0_lut.Nid[gNB->pucch0_lut.nb_id]=pucch_pdu->hopping_id;
+  for (int slot=0;slot<10<<pucch_pdu->subcarrier_spacing;slot++)
+    for (int symbol=0;symbol<14;symbol++)
+      gNB->pucch0_lut.lut[gNB->pucch0_lut.nb_id][slot][symbol] = (int)floor(nr_cyclic_shift_hopping(pucch_pdu->hopping_id,0,0,symbol,0,slot)/0.5235987756);
+  gNB->pucch0_lut.nb_id++;
+  return(gNB->pucch0_lut.nb_id-1);
+}
+
+
+  
+int16_t idft12_re[12][12] = {
+  {23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170},
+  {23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066},
+  {23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
+  {23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
+  {23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
+  {23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
+  {23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170},
+  {23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
+  {23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
+  {23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
+  {23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
+  {23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066}
+};
+
+int16_t idft12_im[12][12] = {
+  {0,0,0,0,0,0,0,0,0,0,0,0},
+  {0,11585,20066,23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585},
+  {0,20066,20066,0,-20066,-20066,0,20066,20066,0,-20066,-20066},
+  {0,23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170},
+  {0,20066,-20066,0,20066,-20066,0,20066,-20066,0,20066,-20066},
+  {0,11585,-20066,23170,-20066,11585,0,-11585,20066,-23170,20066,-11585},
+  {0,0,0,0,0,0,0,0,0,0,0,0},
+  {0,-11585,20066,-23170,20066,-11585,0,11585,-20066,23170,-20066,11585},
+  {0,-20066,20066,0,-20066,20066,0,-20066,20066,0,-20066,20066},
+  {0,-23170,0,23170,0,-23170,0,23170,0,-23170,0,23170},
+  {0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066},
+  {0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585}
+};
+
+
+void nr_decode_pucch0(PHY_VARS_gNB *gNB,
+                      int slot,
+                      nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
+                      nfapi_nr_pucch_pdu_t* pucch_pdu) {
+
+
+  int32_t **rxdataF = gNB->common_vars.rxdataF;
+  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
 
-void nr_decode_pucch0( int32_t **rxdataF,
-			pucch_GroupHopping_t pucch_GroupHopping,
-			uint32_t n_id,       // hoppingID higher layer parameter                                        
-                        uint64_t *payload,
-                        NR_DL_FRAME_PARMS *frame_parms,
-                        int16_t amp,
-                        int nr_tti_tx,
-                        uint8_t m0,                                          // should come from resource set
-                        uint8_t nrofSymbols,				    // should come from resource set	
-                        uint8_t startingSymbolIndex,			    // should come from resource set
-                        uint16_t startingPRB,				   // should come from resource set
-			uint8_t nr_bit) {                                 // is number of UCI bits to be decoded
   int nr_sequences;
   const uint8_t *mcs;
-  if(nr_bit==1){
+
+  pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+
+  AssertFatal(pucch_pdu->bit_len_harq > 0 || pucch_pdu->sr_flag > 0,
+	      "Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n",
+	      pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
+
+  if(pucch_pdu->bit_len_harq==0){
     mcs=table1_mcs;
-    nr_sequences=4;
+    nr_sequences=1;
+  }
+  else if(pucch_pdu->bit_len_harq==1){
+    mcs=table1_mcs;
+    nr_sequences=4>>(1-pucch_pdu->sr_flag);
   }
   else{
     mcs=table2_mcs;
-    nr_sequences=8;
+    nr_sequences=8>>(1-pucch_pdu->sr_flag);
   }
+
+  int cs_ind = get_pucch0_cs_lut_index(gNB,pucch_pdu);
   /*
    * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation
    *
@@ -53,8 +159,6 @@ void nr_decode_pucch0( int32_t **rxdataF,
   //uint8_t lnormal;
   // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
   //uint8_t lprime;
-  // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME!
-  //uint8_t mcs;
 
   /*
    * in TS 38.213 Subclause 9.2.1 it is said that:
@@ -73,76 +177,76 @@ void nr_decode_pucch0( int32_t **rxdataF,
   // if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping
   //              n_hop = 0 for first hop
   //              n_hop = 1 for second hop
-  uint8_t n_hop = 0;
-  //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!!
+  uint8_t n_hop = 0;  // Frequnecy hopping not implemented FIXME!!
 
   // x_n contains the sequence r_u_v_alpha_delta(n)
-  int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
+
   int n,i,l;
+  nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,slot,&u,&v); // calculating u and v value
+
+  uint32_t re_offset=0;
+  uint8_t l2;
+
+#ifdef OLD_IMPL
+  int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
+
   for(i=0;i<nr_sequences;i++){ 
   // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
-    for (l=0; l<nrofSymbols; l++){
-    // if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!!
-    // if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1;
-      nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
-      alpha = nr_cyclic_shift_hopping(n_id,m0,mcs[i],l,startingSymbolIndex,nr_tti_tx);
-      #ifdef DEBUG_NR_PUCCH_RX
-        printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l);
-      #endif
+    for (l=0; l<pucch_pdu->nr_of_symbols; l++){
+      alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
+#ifdef DEBUG_NR_PUCCH_RX
+      printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d/%d,mcs %d)\n",u,v,alpha,l,l+pucch_pdu->start_symbol_index,mcs[i]);
+      printf("lut output %d\n",gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index]);
+#endif
+      alpha=0.0;
       for (n=0; n<12; n++){
-        x_n_re[i][(12*l)+n] = (int16_t)((int32_t)(amp)*(int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
-                                  - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha
-        x_n_im[i][(12*l)+n] =(int16_t)((int32_t)(amp)* (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
-                                  + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha
-        #ifdef DEBUG_NR_PUCCH_RX
-          printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n",
-                u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]);
-        #endif
+        x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
+                                  - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
+        x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
+                                  + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
+#ifdef DEBUG_NR_PUCCH_RX
+          printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
+		 u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
+		 (int32_t)(round(32767*cos(alpha*n))),
+		 (int32_t)(round(32767*sin(alpha*n))));
+#endif
       }
     }
   }
-  int16_t r_re[24],r_im[24];
   /*
-   * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME!
+   * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources
    */
-  uint32_t re_offset=0;
-  for (l=0; l<nrofSymbols; l++) {
-    if ((startingPRB <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
-    if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
-    }
-    if ((startingPRB <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB is lower band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
-    if ((startingPRB >  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB is upper band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
-    }
-    if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB contains DC
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
+
+  int16_t r_re[24],r_im[24];
+
+  for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
+
+    l2 = l+pucch_pdu->start_symbol_index;
+    re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
+    if (re_offset>= frame_parms->ofdm_symbol_size) 
+      re_offset-=frame_parms->ofdm_symbol_size;
+
     for (n=0; n<12; n++){
-      if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
-        // if number RBs in bandwidth is odd  and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
-        re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
-      }
-      r_re[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[0];
-      r_im[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[1];
+
+      r_re[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0];
+      r_im[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1];
       #ifdef DEBUG_NR_PUCCH_RX
-        printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
-                amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset,
-                l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
+        printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
+                frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
+                l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
+                ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
       #endif
       re_offset++;
+      if (re_offset>= frame_parms->ofdm_symbol_size) 
+        re_offset-=frame_parms->ofdm_symbol_size;
     }
-  }   
+  }  
   double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences];
   memset(corr,0,nr_sequences*sizeof(double));
   memset(corr_re,0,nr_sequences*sizeof(double));
   memset(corr_im,0,nr_sequences*sizeof(double));
   for(i=0;i<nr_sequences;i++){
-    for(l=0;l<nrofSymbols;l++){
+    for(l=0;l<pucch_pdu->nr_of_symbols;l++){
       for(n=0;n<12;n++){
         corr_re[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767+(double)(r_im[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767;
 	corr_im[i]+= (double)(r_re[12*l+n])/32767*(double)(x_n_im[i][12*l+n])/32767-(double)(r_im[12*l+n])/32767*(double)(x_n_re[i][12*l+n])/32767;
@@ -151,14 +255,122 @@ void nr_decode_pucch0( int32_t **rxdataF,
     corr[i]=corr_re[i]*corr_re[i]+corr_im[i]*corr_im[i];
   }
   float max_corr=corr[0];
-  int index=0;
+  uint8_t index=0;
   for(i=1;i<nr_sequences;i++){
     if(corr[i]>max_corr){
       index= i;
       max_corr=corr[i];
     }
   }
-  *payload=(uint64_t)index;  // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits
+#else
+
+  const int16_t *x_re = table_5_2_2_2_2_Re[u],*x_im = table_5_2_2_2_2_Im[u];
+  int16_t xr[24]  __attribute__((aligned(32)));
+  int16_t xrt[24] __attribute__((aligned(32)));
+  int32_t xrtmag=0;
+  int maxpos=0;
+  int n2=0;
+  uint8_t index=0;
+  memset((void*)xr,0,24*sizeof(int16_t));
+
+  for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
+
+    l2 = l+pucch_pdu->start_symbol_index;
+    re_offset = (12*pucch_pdu->prb_start) + frame_parms->first_carrier_offset;
+    if (re_offset>= frame_parms->ofdm_symbol_size) 
+      re_offset-=frame_parms->ofdm_symbol_size;
+  
+    AssertFatal(re_offset+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
+
+    int16_t *r=(int16_t*)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size+re_offset)];
+    for (n=0;n<12;n++,n2+=2) {
+      xr[n2]  =(int16_t)(((int32_t)x_re[n]*r[n2]+(int32_t)x_im[n]*r[n2+1])>>15);
+      xr[n2+1]=(int16_t)(((int32_t)x_re[n]*r[n2+1]-(int32_t)x_im[n]*r[n2])>>15);
+#ifdef DEBUG_NR_PUCCH_RX
+      printf("x (%d,%d), r (%d,%d), xr (%d,%d)\n",
+	     x_re[n],x_im[n],r[n2],r[n2+1],xr[n2],xr[n2+1]);
+#endif
+    }
+  }
+  int32_t corr_re,corr_im,temp;
+  int seq_index;
+
+  for(i=0;i<nr_sequences;i++){
+    corr_re=0;corr_im=0;
+    n2=0;
+    for (l=0;l<pucch_pdu->nr_of_symbols;l++) {
+
+       seq_index = (pucch_pdu->initial_cyclic_shift+
+		   mcs[i]+
+		   gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
+      for (n=0;n<12;n++,n2+=2) {
+	corr_re+=(xr[n2]*idft12_re[seq_index][n]+xr[n2+1]*idft12_im[seq_index][n])>>15;
+	corr_im+=(xr[n2]*idft12_im[seq_index][n]-xr[n2+1]*idft12_re[seq_index][n])>>15;
+      }
+    }
+
+#ifdef DEBUG_NR_PUCCH_RX
+    printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
+#endif
+    if ((temp=corr_re*corr_re + corr_im*corr_im)>xrtmag) {
+      xrtmag=temp;
+      maxpos=i;
+    }
+  }
+
+  uint8_t xrtmag_dB = dB_fixed(xrtmag);
+  
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("PUCCH 0 : maxpos %d\n",maxpos);
+#endif
+
+  index=maxpos;
+#endif
+  // first bit of bitmap for sr presence and second bit for acknack presence
+  uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
+  uci_pdu->pucch_format = 0; // format 0
+  uci_pdu->ul_cqi = 0xff; // currently not valid
+  uci_pdu->timing_advance = 0xffff; // currently not valid
+  uci_pdu->rssi = 0xffff; // currently not valid
+
+  if (pucch_pdu->bit_len_harq==0) {
+    uci_pdu->harq = NULL;
+    uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
+    if (xrtmag_dB>(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)) {
+      uci_pdu->sr->sr_indication = 1;
+      uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
+    } else {
+      uci_pdu->sr->sr_indication = 0;
+      uci_pdu->sr->sr_confidence_level = (gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)-xrtmag_dB;
+    }
+  }
+  else if (pucch_pdu->bit_len_harq==1) {
+    uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
+    uci_pdu->harq->num_harq = 1;
+    uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
+    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
+    uci_pdu->harq->harq_list[0].harq_value = index&0x01;
+    if (pucch_pdu->sr_flag == 1) {
+      uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
+      uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
+      uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
+    }
+  }
+  else {
+    uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
+    uci_pdu->harq->num_harq = 2;
+    uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
+    uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
+
+    uci_pdu->harq->harq_list[0].harq_value = index&0x01;
+    uci_pdu->harq->harq_list[1].harq_value = (index>>1)&0x01;
+
+    if (pucch_pdu->sr_flag == 1) {
+      uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
+      uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
+      uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
+    }
+  }
 }
 
 
@@ -180,7 +392,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
                         uint8_t timeDomainOCC,
                         uint8_t nr_bit) {
 #ifdef DEBUG_NR_PUCCH_RX
-  printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
+  printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%lp m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
          nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
 #endif
   /*
@@ -190,7 +402,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
   // complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
   int16_t d_re=0, d_im=0,d1_re=0,d1_im=0;
 #ifdef DEBUG_NR_PUCCH_RX
-  printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
+  printf("\t [nr_generate_pucch1] sequence modulation: payload=%lp \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
 #endif
   /*
    * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
@@ -274,7 +486,6 @@ void nr_decode_pucch1(  int32_t **rxdataF,
       re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
     }
 
-    //txptr = &txdataF[0][re_offset];
     for (int n=0; n<12; n++) {
       if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
         // if number RBs in bandwidth is odd  and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
@@ -285,9 +496,9 @@ void nr_decode_pucch1(  int32_t **rxdataF,
         z_re_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[0];
         z_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1];
 #ifdef DEBUG_NR_PUCCH_RX
-        printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
+        printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
                amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
-               l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
+               l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
 #endif
       }
 
@@ -296,9 +507,9 @@ void nr_decode_pucch1(  int32_t **rxdataF,
         z_dmrs_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1];
 //	printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
 #ifdef DEBUG_NR_PUCCH_RX
-        printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
+        printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
                amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
-               l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
+               l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
 #endif
 //        printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
       }
@@ -409,7 +620,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
                      mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
                      table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
                      table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
-                     z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+                     z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
 #endif   
 	      // multiplying with conjugate of low papr sequence  
 	      z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
@@ -443,7 +654,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
                      mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
                      table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],
                      table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],
-                     z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+                     z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
 #endif
               //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
               z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
@@ -494,7 +705,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
                        mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
                        table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
                        table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
-                       z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+                       z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
 #endif 
                 z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
                             + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); 
@@ -522,7 +733,7 @@ void nr_decode_pucch1(  int32_t **rxdataF,
                        mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
                        table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],
                        table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],
-                       z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+                       z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
 #endif
                 //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
                 z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
@@ -641,3 +852,496 @@ void nr_decode_pucch1(  int32_t **rxdataF,
   }
 }
 
+__m256i pucch2_3bit[8*2];
+__m256i pucch2_4bit[16*2];
+__m256i pucch2_5bit[32*2];
+__m256i pucch2_6bit[64*2];
+__m256i pucch2_7bit[128*2];
+__m256i pucch2_8bit[256*2];
+__m256i pucch2_9bit[512*2];
+__m256i pucch2_10bit[1024*2];
+__m256i pucch2_11bit[2048*2];
+
+__m256i *pucch2_lut[9]={pucch2_3bit,
+			pucch2_4bit,
+			pucch2_5bit,
+			pucch2_6bit,
+			pucch2_7bit,
+			pucch2_8bit,
+			pucch2_9bit,
+			pucch2_10bit,
+			pucch2_11bit};
+
+void init_pucch2_luts() {
+
+  uint32_t out;
+  int8_t bit; 
+  
+  for (int b=3;b<12;b++) {
+    for (uint16_t i=0;i<(1<<b);i++) {
+      out=encodeSmallBlock(&i,b);
+      if (b==3) printf("in %d, out %x\n",i,out);
+      __m256i *lut_i=&pucch2_lut[b-3][i<<1];
+      __m256i *lut_ip1=&pucch2_lut[b-3][1+(i<<1)];
+      bit = (out&0x1) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,0);
+      bit = (out&0x2) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,0);
+      bit = (out&0x4) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,1);
+      bit = (out&0x8) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,1);
+      bit = (out&0x10) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,2);
+      bit = (out&0x20) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,2);
+      bit = (out&0x40) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,3);
+      bit = (out&0x80) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,3);
+      bit = (out&0x100) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,4);
+      bit = (out&0x200) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,4);
+      bit = (out&0x400) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,5);
+      bit = (out&0x800) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,5);
+      bit = (out&0x1000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,6);
+      bit = (out&0x2000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,6);
+      bit = (out&0x4000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,7);
+      bit = (out&0x8000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,7);
+      bit = (out&0x10000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,8);
+      bit = (out&0x20000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,8);
+      bit = (out&0x40000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,9);
+      bit = (out&0x80000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,9);
+      bit = (out&0x100000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,10);
+      bit = (out&0x200000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,10);
+      bit = (out&0x400000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,11);
+      bit = (out&0x800000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,11);
+      bit = (out&0x1000000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,12);
+      bit = (out&0x2000000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,12);
+      bit = (out&0x4000000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,13);
+      bit = (out&0x8000000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,13);
+      bit = (out&0x10000000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,14);
+      bit = (out&0x20000000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,14);
+      bit = (out&0x40000000) > 0 ? -1 : 1;
+      *lut_i = _mm256_insert_epi16(*lut_i,bit,15);
+      bit = (out&0x80000000) > 0 ? -1 : 1;
+      *lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,15);
+    }
+  }
+}
+
+
+void nr_decode_pucch2(PHY_VARS_gNB *gNB,
+                      int slot,
+                      nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
+                      nfapi_nr_pucch_pdu_t* pucch_pdu) {
+
+  int32_t **rxdataF = gNB->common_vars.rxdataF;
+  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+  pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+
+  AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2,
+	      "Illegal number of symbols  for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols);
+
+
+  //extract pucch and dmrs first
+
+  int l2=-1;
+  int re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
+  if (re_offset>= frame_parms->ofdm_symbol_size) 
+    re_offset-=frame_parms->ofdm_symbol_size;
+  
+  AssertFatal(pucch_pdu->prb_size*pucch_pdu->nr_of_symbols > 1,"number of PRB*SYMB (%d,%d)< 2",
+	      pucch_pdu->prb_size,pucch_pdu->nr_of_symbols);
+
+  int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
+  int Prx2 = (Prx==1)?2:Prx;
+  // use 2 for Nb antennas in case of single antenna to allow the following allocations
+  int16_t r_re_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+  int16_t r_im_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+  int16_t r_re_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+  int16_t r_im_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+  int16_t rd_re_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+  int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+
+  int16_t *rp[Prx2];
+  __m64 dmrs_re,dmrs_im;
+
+  for (int aa=0;aa<Prx;aa++) rp[aa] = ((int16_t *)&rxdataF[aa][(l2*frame_parms->ofdm_symbol_size)+re_offset]);
+
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("Decoding pucch2 for %d symbols, %d PRB\n",pucch_pdu->nr_of_symbols,pucch_pdu->prb_size);
+#endif
+
+  int nc_group_size=1; // 2 PRB
+  int ngroup = pucch_pdu->prb_size/nc_group_size/2;
+  int32_t corr32_re[ngroup][Prx2],corr32_im[ngroup][Prx2];
+  for (int aa=0;aa<Prx;aa++) for (int group=0;group<ngroup;group++) { corr32_re[group][aa]=0; corr32_im[group][aa]=0;}
+
+  if (pucch_pdu->nr_of_symbols == 1) {
+     AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
+     // 24 PRBs contains 48x16-bit, so 6x8x16-bit 
+     for (int prb=0;prb<pucch_pdu->prb_size;prb+=2) {
+        for (int aa=0;aa<Prx;aa++) {
+
+	  r_re_ext[aa][0]=rp[aa][0];
+	  r_im_ext[aa][0]=rp[aa][1];
+	  rd_re_ext[aa][0]=rp[aa][2];
+	  rd_im_ext[aa][0]=rp[aa][3];
+	  r_re_ext[aa][1]=rp[aa][4];
+	  r_im_ext[aa][1]=rp[aa][5];
+
+	  r_re_ext[aa][2]=rp[aa][6];
+	  r_im_ext[aa][2]=rp[aa][7];
+	  rd_re_ext[aa][1]=rp[aa][8];
+	  rd_im_ext[aa][1]=rp[aa][9];
+	  r_re_ext[aa][3]=rp[aa][10];
+	  r_im_ext[aa][3]=rp[aa][11];
+
+	  r_re_ext[aa][4]=rp[aa][12];
+	  r_im_ext[aa][4]=rp[aa][13];
+	  rd_re_ext[aa][2]=rp[aa][14];
+	  rd_im_ext[aa][2]=rp[aa][15];
+	  r_re_ext[aa][5]=rp[aa][16];
+	  r_im_ext[aa][5]=rp[aa][17];
+
+	  r_re_ext[aa][6]=rp[aa][18];
+	  r_im_ext[aa][6]=rp[aa][19];
+	  rd_re_ext[aa][3]=rp[aa][20];
+	  rd_im_ext[aa][3]=rp[aa][21];
+	  r_re_ext[aa][7]=rp[aa][22];
+	  r_im_ext[aa][7]=rp[aa][23];
+
+	  r_re_ext[aa][8]=rp[aa][24];
+	  r_im_ext[aa][8]=rp[aa][25];
+	  rd_re_ext[aa][4]=rp[aa][26];
+	  rd_im_ext[aa][4]=rp[aa][27];
+	  r_re_ext[aa][9]=rp[aa][28];
+	  r_im_ext[aa][9]=rp[aa][29];
+
+	  r_re_ext[aa][10]=rp[aa][30];
+	  r_im_ext[aa][10]=rp[aa][31];
+	  rd_re_ext[aa][5]=rp[aa][32];
+	  rd_im_ext[aa][5]=rp[aa][33];
+	  r_re_ext[aa][11]=rp[aa][34];
+	  r_im_ext[aa][11]=rp[aa][35];
+
+	  r_re_ext[aa][12]=rp[aa][36];
+	  r_im_ext[aa][12]=rp[aa][37];
+	  rd_re_ext[aa][6]=rp[aa][38];
+	  rd_im_ext[aa][6]=rp[aa][39];
+	  r_re_ext[aa][13]=rp[aa][40];
+	  r_im_ext[aa][13]=rp[aa][41];
+
+	  r_re_ext[aa][14]=rp[aa][42];
+	  r_im_ext[aa][14]=rp[aa][43];
+	  rd_re_ext[aa][7]=rp[aa][44];
+	  rd_im_ext[aa][7]=rp[aa][45];
+	  r_re_ext[aa][15]=rp[aa][46];
+	  r_im_ext[aa][15]=rp[aa][47];
+		  
+#ifdef DEBUG_NR_PUCCH_RX
+	  for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext[aa][i],rd_im_ext[aa]);
+#endif
+	} // aa
+     } // prb
+
+
+     // first compute DMRS component
+     uint32_t x1, x2, s=0;
+     x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+#ifdef DEBUG_NR_PUCCH_RX
+     printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
+       slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
+#endif
+     s = lte_gold_generic(&x1, &x2, 1);
+
+
+     for (int group=0;group<ngroup;group++) {
+     // each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
+     // non-coherent combining across groups
+       dmrs_re = byte2m64_re[((uint8_t*)&s)[(group&1)<<1]];
+       dmrs_im = byte2m64_im[((uint8_t*)&s)[(group&1)<<1]];
+#ifdef DEBUG_NR_PUCCH_RX
+       printf("Group %d: s %x x2 %x ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+	      group,
+	      ((uint16_t*)&s)[0],x2,
+	      ((int16_t*)&dmrs_re)[0],((int16_t*)&dmrs_im)[0],    
+	      ((int16_t*)&dmrs_re)[1],((int16_t*)&dmrs_im)[1],    
+	      ((int16_t*)&dmrs_re)[2],((int16_t*)&dmrs_im)[2],    
+	      ((int16_t*)&dmrs_re)[3],((int16_t*)&dmrs_im)[3]);   
+#endif
+       for (int aa=0;aa<Prx;aa++) {
+#ifdef DEBUG_NR_PUCCH_RX
+	 printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		group,
+		rd_re_ext[aa][0],rd_im_ext[aa][0],
+		rd_re_ext[aa][1],rd_im_ext[aa][1],
+		rd_re_ext[aa][2],rd_im_ext[aa][2],
+		rd_re_ext[aa][3],rd_im_ext[aa][3]);
+#endif
+	 corr32_re[group][aa]+=(rd_re_ext[aa][0]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][0]*((int16_t*)&dmrs_im)[0]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][0]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][0]*((int16_t*)&dmrs_re)[0]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][1]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][1]*((int16_t*)&dmrs_im)[1]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][1]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][1]*((int16_t*)&dmrs_re)[1]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][2]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][2]*((int16_t*)&dmrs_im)[2]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][2]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][2]*((int16_t*)&dmrs_re)[2]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][3]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][3]*((int16_t*)&dmrs_im)[3]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][3]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][3]*((int16_t*)&dmrs_re)[3]); 
+       }
+       dmrs_re = byte2m64_re[((uint8_t*)&s)[1+((group&1)<<1)]];
+       dmrs_im = byte2m64_im[((uint8_t*)&s)[1+((group&1)<<1)]];
+#ifdef DEBUG_NR_PUCCH_RX
+       printf("Group %d: s %x ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+	      group,
+	      ((uint16_t*)&s)[1],
+	      ((int16_t*)&dmrs_re)[0],((int16_t*)&dmrs_im)[0],    
+	      ((int16_t*)&dmrs_re)[1],((int16_t*)&dmrs_im)[1],    
+	      ((int16_t*)&dmrs_re)[2],((int16_t*)&dmrs_im)[2],    
+	      ((int16_t*)&dmrs_re)[3],((int16_t*)&dmrs_im)[3]);
+#endif
+       for (int aa=0;aa<Prx;aa++) {
+#ifdef DEBUG_NR_PUCCH_RX
+	 printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		group,
+		rd_re_ext[aa][4],rd_im_ext[aa][4],
+		rd_re_ext[aa][5],rd_im_ext[aa][5],
+		rd_re_ext[aa][6],rd_im_ext[aa][6],
+		rd_re_ext[aa][7],rd_im_ext[aa][7]);
+#endif
+	 corr32_re[group][aa]+=(rd_re_ext[aa][4]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_im)[0]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][4]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_re)[0]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][5]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_im)[1]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][5]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_re)[1]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][6]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_im)[2]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][6]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_re)[2]); 
+	 corr32_re[group][aa]+=(rd_re_ext[aa][7]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_im)[3]); 
+	 corr32_im[group][aa]+=(-rd_re_ext[aa][7]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_re)[3]); 
+	 corr32_re[group][aa]>>=5;
+	 corr32_im[group][aa]>>=5;
+#ifdef DEBUG_NR_PUCCH_RX
+	 printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
+#endif
+       } //aa    
+       
+       if ((group&3) == 3) s = lte_gold_generic(&x1, &x2, 0);
+     } // group
+  }
+  else { // 2 symbol case
+     AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
+  }
+
+  uint32_t x1, x2, s=0;  
+  // unscrambling
+  x2 = ((pucch_pdu->rnti)<<15)+pucch_pdu->data_scrambling_id;
+  s = lte_gold_generic(&x1, &x2, 1);
+#ifdef DEBUG_NR_PUCCH_RX
+  printf("x2 %x, s %x\n",x2,s);
+#endif
+  __m64 c_re0,c_im0,c_re1,c_im1,c_re2,c_im2,c_re3,c_im3;
+  re_offset=0;
+  for (int prb=0;prb<pucch_pdu->prb_size;prb+=2,re_offset+=16) {
+    c_re0 = byte2m64_re[((uint8_t*)&s)[0]];
+    c_im0 = byte2m64_im[((uint8_t*)&s)[0]];
+    c_re1 = byte2m64_re[((uint8_t*)&s)[1]];
+    c_im1 = byte2m64_im[((uint8_t*)&s)[1]];
+    c_re2 = byte2m64_re[((uint8_t*)&s)[2]];
+    c_im2 = byte2m64_im[((uint8_t*)&s)[2]];
+    c_re3 = byte2m64_re[((uint8_t*)&s)[3]];
+    c_im3 = byte2m64_im[((uint8_t*)&s)[3]];
+
+    for (int aa=0;aa<Prx;aa++) {
+#ifdef DEBUG_NR_PUCCH_RX
+      printf("prb %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		prb,
+		r_re_ext[aa][re_offset],r_im_ext[aa][re_offset],
+		r_re_ext[aa][re_offset+1],r_im_ext[aa][re_offset+1],
+		r_re_ext[aa][re_offset+2],r_im_ext[aa][re_offset+2],
+		r_re_ext[aa][re_offset+3],r_im_ext[aa][re_offset+3],
+		r_re_ext[aa][re_offset+4],r_im_ext[aa][re_offset+4],
+		r_re_ext[aa][re_offset+5],r_im_ext[aa][re_offset+5],
+		r_re_ext[aa][re_offset+6],r_im_ext[aa][re_offset+6],
+		r_re_ext[aa][re_offset+7],r_im_ext[aa][re_offset+7]);
+      printf("prb %d: c ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		prb,
+		((int16_t*)&c_re0)[0],((int16_t*)&c_im0)[0],
+		((int16_t*)&c_re0)[1],((int16_t*)&c_im0)[1],
+		((int16_t*)&c_re0)[2],((int16_t*)&c_im0)[2],
+		((int16_t*)&c_re0)[3],((int16_t*)&c_im0)[3],
+		((int16_t*)&c_re1)[0],((int16_t*)&c_im1)[0],
+		((int16_t*)&c_re1)[1],((int16_t*)&c_im1)[1],
+		((int16_t*)&c_re1)[2],((int16_t*)&c_im1)[2],
+		((int16_t*)&c_re1)[3],((int16_t*)&c_im1)[3]
+		);
+      printf("prb %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		prb+1,
+		r_re_ext[aa][re_offset+8],r_im_ext[aa][re_offset+8],
+		r_re_ext[aa][re_offset+9],r_im_ext[aa][re_offset+9],
+		r_re_ext[aa][re_offset+10],r_im_ext[aa][re_offset+10],
+		r_re_ext[aa][re_offset+11],r_im_ext[aa][re_offset+11],
+		r_re_ext[aa][re_offset+12],r_im_ext[aa][re_offset+12],
+		r_re_ext[aa][re_offset+13],r_im_ext[aa][re_offset+13],
+		r_re_ext[aa][re_offset+14],r_im_ext[aa][re_offset+14],
+		r_re_ext[aa][re_offset+15],r_im_ext[aa][re_offset+15]);
+      printf("prb %d: c ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+		prb+1,
+		((int16_t*)&c_re2)[0],((int16_t*)&c_im2)[0],
+		((int16_t*)&c_re2)[1],((int16_t*)&c_im2)[1],
+		((int16_t*)&c_re2)[2],((int16_t*)&c_im2)[2],
+		((int16_t*)&c_re2)[3],((int16_t*)&c_im2)[3],
+		((int16_t*)&c_re3)[0],((int16_t*)&c_im3)[0],
+		((int16_t*)&c_re3)[1],((int16_t*)&c_im3)[1],
+		((int16_t*)&c_re3)[2],((int16_t*)&c_im3)[2],
+		((int16_t*)&c_re3)[3],((int16_t*)&c_im3)[3]
+		);
+#endif
+
+      ((__m64*)&r_re_ext2[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[0],c_im0);
+      ((__m64*)&r_re_ext[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[0],c_re0);
+      ((__m64*)&r_im_ext2[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[0],c_re0);
+      ((__m64*)&r_im_ext[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[0],c_im0);
+
+      ((__m64*)&r_re_ext2[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[1],c_im1);
+      ((__m64*)&r_re_ext[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[1],c_re1);
+      ((__m64*)&r_im_ext2[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[1],c_re1);
+      ((__m64*)&r_im_ext[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[1],c_im1);
+
+      ((__m64*)&r_re_ext2[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[2],c_im2);
+      ((__m64*)&r_re_ext[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[2],c_re2);
+      ((__m64*)&r_im_ext2[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[2],c_re2);
+      ((__m64*)&r_im_ext[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[2],c_im2);
+
+      ((__m64*)&r_re_ext2[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[3],c_im3);
+      ((__m64*)&r_re_ext[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[3],c_re3);
+      ((__m64*)&r_im_ext2[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[3],c_re3);
+      ((__m64*)&r_im_ext[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[3],c_im3);
+
+#ifdef DEBUG_NR_PUCCH_RX
+      printf("prb %d: r ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+	     prb,
+	     r_re_ext[aa][re_offset],r_im_ext[aa][re_offset],
+	     r_re_ext[aa][re_offset+1],r_im_ext[aa][re_offset+1],
+	     r_re_ext[aa][re_offset+2],r_im_ext[aa][re_offset+2],
+	     r_re_ext[aa][re_offset+3],r_im_ext[aa][re_offset+3],
+	     r_re_ext[aa][re_offset+4],r_im_ext[aa][re_offset+4],
+	     r_re_ext[aa][re_offset+5],r_im_ext[aa][re_offset+5],
+	     r_re_ext[aa][re_offset+6],r_im_ext[aa][re_offset+6],
+	     r_re_ext[aa][re_offset+7],r_im_ext[aa][re_offset+7]);
+      printf("prb %d: r ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+	     prb+1,
+	     r_re_ext[aa][re_offset+8],r_im_ext[aa][re_offset+8],
+	     r_re_ext[aa][re_offset+9],r_im_ext[aa][re_offset+9],
+	     r_re_ext[aa][re_offset+10],r_im_ext[aa][re_offset+10],
+	     r_re_ext[aa][re_offset+11],r_im_ext[aa][re_offset+11],
+	     r_re_ext[aa][re_offset+12],r_im_ext[aa][re_offset+12],
+	     r_re_ext[aa][re_offset+13],r_im_ext[aa][re_offset+13],
+	     r_re_ext[aa][re_offset+14],r_im_ext[aa][re_offset+14],
+	     r_re_ext[aa][re_offset+15],r_im_ext[aa][re_offset+15]);
+#endif      
+    }
+    s = lte_gold_generic(&x1, &x2, 0);
+  }
+  AssertFatal(pucch_pdu->bit_len_csi_part1 + pucch_pdu->bit_len_csi_part2 == 0,"no csi for now\n");
+  AssertFatal((pucch_pdu->bit_len_harq+pucch_pdu->sr_flag > 2 ) && (pucch_pdu->bit_len_harq+pucch_pdu->sr_flag < 12),"illegal length (%d,%d)\n",pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
+  int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag;
+  __m256i *rp_re[Prx2];
+  __m256i *rp2_re[Prx2];
+  __m256i *rp_im[Prx2];
+  __m256i *rp2_im[Prx2];
+  for (int aa=0;aa<Prx;aa++) {
+    rp_re[aa] = (__m256i*)r_re_ext[aa];
+    rp_im[aa] = (__m256i*)r_im_ext[aa];
+    rp2_re[aa] = (__m256i*)r_re_ext2[aa];
+    rp2_im[aa] = (__m256i*)r_im_ext2[aa];
+  }
+  __m256i prod_re[Prx2],prod_im[Prx2];
+  int64_t corr=0;
+  int cw_ML=0;
+
+  for (int cw=0;cw<1<<nb_bit;cw++) {
+#ifdef DEBUG_NR_PUCCH_RX
+    printf("cw %d:",cw);
+    for (int i=0;i<32;i+=2) {
+      printf("%d,%d,",
+	     ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[i>>1],
+	     ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
+    }
+    printf("\n");
+#endif
+    // do complex correlation
+    for (int aa=0;aa<Prx;aa++) {
+      prod_re[aa] = _mm256_srai_epi16(_mm256_adds_epi16(_mm256_mullo_epi16(pucch2_lut[nb_bit-3][cw<<1],rp_re[aa][0]),
+							_mm256_mullo_epi16(pucch2_lut[nb_bit-3][(cw<<1)+1],rp_im[aa][0])),5);
+      prod_im[aa] = _mm256_srai_epi16(_mm256_subs_epi16(_mm256_mullo_epi16(pucch2_lut[nb_bit-3][cw<<1],rp2_im[aa][0]),
+							_mm256_mullo_epi16(pucch2_lut[nb_bit-3][(cw<<1)+1],rp2_re[aa][0])),5);
+      prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
+      prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+      prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+      prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+      prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
+      prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+      prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
+      prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+    }
+    int64_t corr_re=0,corr_im=0;
+
+    for (int aa=0;aa<Prx;aa++) {
+      LOG_D(PHY,"pucch2 cw %d aa %d: (%d,%d)+(%d,%d) = (%d,%d)\n",cw,aa,
+	    corr32_re[0][aa],corr32_im[0][aa],
+	    ((int16_t*)(&prod_re[aa]))[0],
+	    ((int16_t*)(&prod_im[aa]))[0],
+	    corr32_re[0][aa]+((int16_t*)(&prod_re[0]))[0],
+	    corr32_im[0][aa]+((int16_t*)(&prod_im[0]))[0]);
+	     
+      corr_re += ( corr32_re[0][aa]+((int16_t*)(&prod_re[0]))[0]);
+      corr_im += ( corr32_im[0][aa]+((int16_t*)(&prod_im[0]))[0]);
+
+    }
+    int64_t corr_tmp = corr_re*corr_re + corr_im*corr_im;
+    if (corr_tmp > corr) {
+      corr = corr_tmp;
+      cw_ML=cw;
+    }
+  }
+  uint8_t corr_dB = dB_fixed64((uint64_t)corr);
+  LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
+  uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
+
+  
+  int harq_bytes=pucch_pdu->bit_len_harq>>3;
+  if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
+  uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
+  uci_pdu->harq.harq_crc = 2;
+  for (int i=0;i<harq_bytes;i++) {
+    uci_pdu->harq.harq_payload[i] = cw_ML & 255;
+    cw_ML>>=8;
+  }
+  
+  if (pucch_pdu->sr_flag == 1) {
+    uci_pdu->sr.sr_bit_len = 1;
+    uci_pdu->sr.sr_payload = malloc(1);
+    uci_pdu->sr.sr_payload[0] = cw_ML;
+  }
+}
+    
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index cc22e5f7d78..7f5872e8858 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -23,7 +23,6 @@
 #include "PHY/defs_nr_UE.h"
 #include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
 #include "PHY/impl_defs_top.h"
-//#include "openair2/LAYER2/MAC/mac_proto.h"
 
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index be5c754bebf..71a5771f5be 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -405,39 +405,39 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
     }
 
-    void (*idft)(int16_t *,int16_t *, int);
+    idft_size_idx_t idftsizeidx;
 
     switch (ue->frame_parms.ofdm_symbol_size) {
     case 128:
-      idft = idft128;
+      idftsizeidx = IDFT_128;
       break;
 
     case 256:
-      idft = idft256;
+      idftsizeidx = IDFT_256;
       break;
 
     case 512:
-      idft = idft512;
+      idftsizeidx = IDFT_512;
       break;
 
     case 1024:
-      idft = idft1024;
+      idftsizeidx = IDFT_1024;
       break;
 
     case 1536:
-      idft = idft1536;
+      idftsizeidx = IDFT_1536;
       break;
 
     case 2048:
-      idft = idft2048;
+      idftsizeidx = IDFT_2048;
       break;
 
     case 3072:
-      idft = idft3072;
+      idftsizeidx = IDFT_3072;
       break;
 
     case 4096:
-      idft = idft4096;
+      idftsizeidx = IDFT_4096;
       break;
 
     default:
@@ -453,7 +453,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                 if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
                 {
   		LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset);
-  		idft((int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
+  		idft(idftsizeidx,
+  			 (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
   		     (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
                 }
             }
@@ -617,7 +618,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
         ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
 
 #ifdef DEBUG_PDCCH
-	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
 #endif
 
         multadd_real_vector_complex_scalar(fr,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h
index 95b6cfd2e2f..5f1321dd321 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.h
@@ -29,6 +29,10 @@
 * \note
 * \warning
 */
+
+#ifndef __PHY_NR_UE_TRANSPORT_DCI_NR__H__
+#define __PHY_NR_UE_TRANSPORT_DCI_NR__H__
+
 #ifndef USER_MODE
 #include "PHY/types.h"
 #else
@@ -118,4 +122,5 @@ typedef struct NR_DCI_INFO_EXTRACTED NR_DCI_INFO_EXTRACTED_t;
 
 
 #endif
+#endif
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 00167507ce5..e5cbc4e07ae 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -69,12 +69,11 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
       a_segments = a_segments/273;
     }  
  
-    uint16_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
 
     for (i=0; i<dlsch->Mdlharq; i++) {
       if (dlsch->harq_processes[i]) {
         if (dlsch->harq_processes[i]->b) {
-          free16(dlsch->harq_processes[i]->b,dlsch_bytes);
+          free16(dlsch->harq_processes[i]->b,a_segments*1056);
           dlsch->harq_processes[i]->b = NULL;
         }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index f4071190247..013b5ca4a6d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -38,8 +38,10 @@
 
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
+#include <openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h>
 
 #include "T.h"
+#include <openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h>
 
 
 
@@ -88,7 +90,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
   uint16_t *prach_root_sequence_map;
   uint16_t preamble_offset,preamble_shift;
   uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
-  uint16_t d_start,numshift;
+  uint16_t d_start=-1,numshift;
 
   uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
   //uint8_t Nsp=2;
@@ -398,7 +400,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       // This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s
       prach2 = prach+(Ncp<<1);
       if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
-	idft49152(prachF,prach2,1);
+	idft(IDFT_49152,prachF,prach2,1);
 	// here we have |empty | Prach49152|
 	memmove(prach,prach+(49152<<1),(Ncp<<3));
 	// here we have |Prefix | Prach49152|
@@ -406,7 +408,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	dftlen=49152;
       }
       else if (prach_fmt == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
-	idft49152(prachF,prach2,1);
+	idft(IDFT_49152,prachF,prach2,1);
 	memmove(prach2+(49152<<1),prach2,(49152<<2));
 	// here we have |empty | Prach49152 | Prach49152|
 	memmove(prach,prach+(49152<<2),(Ncp<<3));
@@ -415,7 +417,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	dftlen=49152;
       }
       else if (prach_fmt == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
-	idft49152(prachF,prach2,1);
+	idft(IDFT_49152,prachF,prach2,1);
 	memmove(prach2+(49152<<1),prach2,(49152<<2));
 	// here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
 	memmove(prach2+(49152<<2),prach2,(49152<<3));
@@ -426,7 +428,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	dftlen=49152;
       }
       else if (prach_fmt == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
-	idft12288(prachF,prach2,1);
+	idft(IDFT_12288,prachF,prach2,1);
 	memmove(prach2+(12288<<1),prach2,(12288<<2));
 	// here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
 	memmove(prach2+(12288<<2),prach2,(12288<<3));
@@ -438,7 +440,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       }
       else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
 	prach2 = prach+(Ncp<<1);
-	idft2048(prachF,prach2,1);
+	idft(IDFT_2048,prachF,prach2,1);
 	dftlen=2048;
 	// here we have |empty | Prach2048 |
 	if (prach_fmt != 0xc0) {
@@ -450,7 +452,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	// here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0)  | 
       }
       else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048
-	idft2048(prachF,prach2,1);
+	idft(IDFT_2048,prachF,prach2,1);
 	dftlen=2048;
 	// here we have |empty | Prach2048 |
 	memmove(prach2+(2048<<1),prach2,(2048<<2));
@@ -463,7 +465,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       }
       else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048
 	prach2 = prach+(Ncp<<1);
-	idft2048(prachF,prach2,1);
+	idft(IDFT_2048,prachF,prach2,1);
 	dftlen=2048;
 	// here we have |empty | Prach2048 |
 	memmove(prach2+(2048<<1),prach2,(2048<<2));
@@ -477,7 +479,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (2048*6)+Ncp; 
       }
       else if (prach_fmt == 0xb4) { // 12x2048
-	idft2048(prachF,prach2,1);
+	idft(IDFT_2048,prachF,prach2,1);
 	dftlen=2048;
 	// here we have |empty | Prach2048 |
 	memmove(prach2+(2048<<1),prach2,(2048<<2));
@@ -498,7 +500,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       Ncp = (Ncp*3)/2;
       prach2 = prach+(Ncp<<1);
       if (prach_fmt == 0) {
-	idft36864(prachF,prach2,1);
+	idft(IDFT_36864,prachF,prach2,1);
 	dftlen=36864;
 	// here we have |empty | Prach73728|
 	memmove(prach,prach+(36864<<1),(Ncp<<2));
@@ -506,7 +508,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (36864*1)+Ncp;
       }
       else if (prach_fmt == 1) {
-	idft36864(prachF,prach2,1);
+	idft(IDFT_36864,prachF,prach2,1);
 	dftlen=36864;
 	memmove(prach2+(36864<<1),prach2,(36864<<2));
 	// here we have |empty | Prach73728 | Prach73728|
@@ -515,7 +517,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (36864*2)+Ncp;
       }
       if (prach_fmt == 2) {
-	idft36864(prachF,prach2,1);
+	idft(IDFT_36864,prachF,prach2,1);
 	dftlen=36864;
 	memmove(prach2+(36864<<1),prach2,(36864<<2));
 	// here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
@@ -526,7 +528,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (36864*4)+Ncp;
       }
       else if (prach_fmt == 3) {
-	idft9216(prachF,prach2,1);
+	idft(IDFT_9216,prachF,prach2,1);
 	dftlen=36864;
 	memmove(prach2+(9216<<1),prach2,(9216<<2));
 	// here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
@@ -537,7 +539,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (9216*4)+Ncp;
       }
       else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
-	idft1536(prachF,prach2,1);
+	idft(IDFT_1536,prachF,prach2,1);
 	dftlen=1536;
 	// here we have |empty | Prach1536 |
 	if (prach_fmt != 0xc0)
@@ -547,7 +549,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (1536*2)+Ncp;
       }
       else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536
-	idft1536(prachF,prach2,1);
+	idft(IDFT_1536,prachF,prach2,1);
 	dftlen=1536;
 	// here we have |empty | Prach1536 |
 	memmove(prach2+(1536<<1),prach2,(1536<<2));
@@ -559,7 +561,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (1536*4)+Ncp; 
       }
       else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536
-	idft1536(prachF,prach2,1);
+	idft(IDFT_1536,prachF,prach2,1);
 	dftlen=1536;
 	// here we have |empty | Prach1536 |
 	memmove(prach2+(1536<<1),prach2,(1536<<2));
@@ -573,7 +575,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (1536*6)+Ncp; 
       }
       else if (prach_fmt == 0xb4) { // 12x1536
-	idft1536(prachF,prach2,1);
+	idft(IDFT_1536,prachF,prach2,1);
 	dftlen=1536;
 	// here we have |empty | Prach1536 |
 	memmove(prach2+(1536<<1),prach2,(1536<<2));
@@ -595,7 +597,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       Ncp<<=2;
       prach2 = prach+(Ncp<<1);
       if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
-	idft98304(prachF,prach2,1);
+	idft(IDFT_98304,prachF,prach2,1);
 	dftlen=98304;
 	// here we have |empty | Prach98304|
 	memmove(prach,prach+(98304<<1),(Ncp<<2));
@@ -603,7 +605,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (98304*1)+Ncp;
       }
       else if (prach_fmt == 1) {
-	idft98304(prachF,prach2,1);
+	idft(IDFT_98304,prachF,prach2,1);
 	dftlen=98304;
 	memmove(prach2+(98304<<1),prach2,(98304<<2));
 	// here we have |empty | Prach98304 | Prach98304|
@@ -612,7 +614,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (98304*2)+Ncp;
       }
       else if (prach_fmt == 2) {
-	idft98304(prachF,prach2,1);
+	idft(IDFT_98304,prachF,prach2,1);
 	dftlen=98304;
 	memmove(prach2+(98304<<1),prach2,(98304<<2));
 	// here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
@@ -623,7 +625,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (98304*4)+Ncp;
       }
       else if (prach_fmt == 3) { // 4x6144, Ncp 3168
-	idft24576(prachF,prach2,1);
+	idft(IDFT_24576,prachF,prach2,1);
 	dftlen=24576;
 	memmove(prach2+(24576<<1),prach2,(24576<<2));
 	// here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
@@ -634,7 +636,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (24576*4)+(Ncp<<1);
       }
       else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
-	idft4096(prachF,prach2,1);
+	idft(IDFT_4096,prachF,prach2,1);
 	dftlen=4096;
 	// here we have |empty | Prach4096 |
 	if (prach_fmt != 0xc0) {
@@ -647,7 +649,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 
       }
       else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096
-	idft4096(prachF,prach2,1);
+	idft(IDFT_4096,prachF,prach2,1);
 	dftlen=4096;
 	// here we have |empty | Prach4096 |
 	memmove(prach2+(4096<<1),prach2,(4096<<2));
@@ -659,7 +661,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (4096*4)+Ncp;  
       }
       else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096
-	idft4096(prachF,prach2,1);
+	idft(IDFT_4096,prachF,prach2,1);
 	dftlen=4096;
 	// here we have |empty | Prach4096 |
 	memmove(prach2+(4096<<1),prach2,(4096<<2));
@@ -673,7 +675,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (4096*6)+Ncp; 
       }
       else if (prach_fmt == 0xb4) { // 12x4096
-	idft4096(prachF,prach2,1);
+	idft(IDFT_4096,prachF,prach2,1);
 	dftlen=4096;
 	// here we have |empty | Prach4096 |
 	memmove(prach2+(4096<<1),prach2,(4096<<2));
@@ -693,7 +695,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
       Ncp = (Ncp*3);
       prach2 = prach+(Ncp<<1);
       if (prach_fmt == 0) {
-	idft73728(prachF,prach2,1);
+	idft(IDFT_73728,prachF,prach2,1);
 	dftlen=73728;
 	// here we have |empty | Prach73728|
 	memmove(prach,prach+(73728<<1),(Ncp<<4));
@@ -701,7 +703,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (73728*1)+Ncp;
       }
       else if (prach_fmt == 1) {
-	idft73728(prachF,prach2,1);
+	idft(IDFT_73728,prachF,prach2,1);
 	dftlen=73728;
 	memmove(prach2+(73728<<1),prach2,(73728<<2));
 	// here we have |empty | Prach73728 | Prach73728|
@@ -710,7 +712,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (73728*2)+Ncp;
       }
       if (prach_fmt == 2) {
-	idft73728(prachF,prach2,1);
+	idft(IDFT_73728,prachF,prach2,1);
 	dftlen=73728;
 	memmove(prach2+(73728<<1),prach2,(73728<<2));
 	// here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
@@ -721,7 +723,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (73728*4)+Ncp;
       }
       else if (prach_fmt == 3) {
-	idft18432(prachF,prach2,1);
+	idft(IDFT_18432,prachF,prach2,1);
 	dftlen=18432;
 	memmove(prach2+(18432<<1),prach2,(18432<<2));
 	// here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
@@ -732,7 +734,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (18432*4)+Ncp;
       }
       else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
-	idft3072(prachF,prach2,1);
+	idft(IDFT_3072,prachF,prach2,1);
 	dftlen=3072;
 	// here we have |empty | Prach3072 |
 	if (prach_fmt != 0xc0) {
@@ -744,7 +746,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	// here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0)  | 
       }
       else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072
-	idft3072(prachF,prach2,1);
+	idft(IDFT_3072,prachF,prach2,1);
 	dftlen=3072;
 	// here we have |empty | Prach3072 |
 	memmove(prach2+(3072<<1),prach2,(3072<<2));
@@ -758,7 +760,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (3072*6)+Ncp;
       }
       else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072
-	idft3072(prachF,prach2,1);
+	idft(IDFT_3072,prachF,prach2,1);
 	dftlen=3072;
 	// here we have |empty | Prach3072 |
 	memmove(prach2+(3072<<1),prach2,(3072<<2));
@@ -770,7 +772,7 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
 	prach_len = (3072*4)+Ncp;
       }
       else if (prach_fmt == 0xb4) { // 12x3072
-	idft3072(prachF,prach2,1);
+	idft(IDFT_3072,prachF,prach2,1);
 	dftlen=3072;
 	// here we have |empty | Prach3072 |
 	memmove(prach2+(3072<<1),prach2,(3072<<2));
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 35fe8bc8992..4aae9ef7b42 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1053,7 +1053,8 @@ uint32_t  nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
 int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
                      NR_DL_FRAME_PARMS* frame_parms,
-                     uint8_t harq_pid);
+                     uint8_t harq_pid,
+                     unsigned int G);
 
 /*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
   @param[in] in, Pointer to input bits
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index fb560f229d2..bb92508934d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -43,7 +43,7 @@
 #endif
 
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
-
+#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
 //#include "../LTE_TRANSPORT/transport_common.h"
 
 // structures below implement 36-211 and 36-212
@@ -86,40 +86,26 @@ typedef struct {
 #endif
 
 typedef struct {
+  /// NDAPI struct for UE
+  nfapi_nr_ue_pusch_pdu_t pusch_pdu;
   /// Indicator of first transmission
   uint8_t first_tx;
-  /// Last Ndi received for this process on DCI (used for C-RNTI only)
-  uint8_t DCINdi;
   /// HARQ tx status
   harq_result_t tx_status;
-  /// Flag indicating that this ULSCH has a new packet (start of new round)
-  //  uint8_t Ndi;
   /// Status Flag indicating for this ULSCH (idle,active,disabled)
   SCH_status_t status;
   /// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
   uint8_t subframe_scheduling_flag;
   /// Subframe cba scheduling indicator (i.e. Transmission opportunity indicator)
   uint8_t subframe_cba_scheduling_flag;
-  /// First Allocated RB
-  uint16_t first_rb;
-  /// Current Number of RBs
-  uint16_t nb_rb;
-  /// number of layers
-  uint8_t Nl;
   /// Last TPC command
   uint8_t TPC;
-  /// Transport block size
-  uint32_t TBS;
   /// The payload + CRC size in bits, "B" from 36-212
   uint32_t B;
   /// Length of ACK information (bits)
   uint8_t O_ACK;
   /// Index of current HARQ round for this ULSCH
   uint8_t round;
-  /// MCS format of this ULSCH
-  uint8_t mcs;
-  /// Redundancy-version of the current sub-frame
-  uint8_t rvidx;
   /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
   unsigned char *a;
   /// Pointer to the payload + CRC 
@@ -152,19 +138,11 @@ typedef struct {
   uint32_t G;
   // Number of modulated symbols carrying data
   uint32_t num_of_mod_symbols;
-  // This is "L" in  TS 38.214 V15.4.0 subclause 6.1.2.1
-  uint8_t number_of_symbols;
-  // This is "S" in  TS 38.214 V15.4.0 subclause 6.1.2.1
-  uint8_t start_symbol;
   // decode phich
   uint8_t decode_phich;
 } NR_UL_UE_HARQ_t;
 
 typedef struct {
-  /// number of DMRS resource elements
-  uint8_t nb_re_dmrs;
-  /// DMRS length
-  uint8_t length_dmrs;
   /// SRS active flag
   uint8_t srs_active; 
 //#if defined(UPGRADE_RAT_NR)
@@ -226,8 +204,6 @@ typedef struct {
   uint8_t power_offset;
   // for cooperative communication
   uint8_t cooperation_flag;
-  /// RNTI attributed to this ULSCH
-  uint16_t rnti;
   /// RNTI type
   uint8_t rnti_type;
   /// Cell ID
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 55bac905208..7299b085bb7 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -60,17 +60,16 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
     a_segments = a_segments/273;
   }  
 
-  uint16_t ulsch_bytes = a_segments*1056;  // allocated bytes per segment
 
     for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
       if (ulsch->harq_processes[i]) {
 
         if (ulsch->harq_processes[i]->a) {
-          free16(ulsch->harq_processes[i]->a,ulsch_bytes);
+          free16(ulsch->harq_processes[i]->a,a_segments*1056);
           ulsch->harq_processes[i]->a = NULL;
         }
         if (ulsch->harq_processes[i]->b) {
-          free16(ulsch->harq_processes[i]->b,ulsch_bytes);
+          free16(ulsch->harq_processes[i]->b,a_segments*1056);
           ulsch->harq_processes[i]->b = NULL;
         }
         if (ulsch->harq_processes[i]->e) {
@@ -217,12 +216,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
 
 int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
                       NR_DL_FRAME_PARMS* frame_parms,
-                      uint8_t harq_pid)
+                      uint8_t harq_pid,
+                      unsigned int G)
 {
 /////////////////////////parameters and variables declaration/////////////////////////
 ///////////
 
-  unsigned int G,crc;
+  unsigned int crc;
   NR_UL_UE_HARQ_t *harq_process; 
   uint16_t nb_rb ;
   uint8_t nb_symb_sch ;
@@ -235,8 +235,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   uint32_t E,Kb;
   uint8_t Ilbrm; 
   uint32_t Tbslbrm; 
-  uint8_t nb_re_dmrs; 
-  uint16_t length_dmrs;
   uint16_t R;
   float Coderate;
 
@@ -249,20 +247,17 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 
   crc = 1;
   harq_process = ulsch->harq_processes[harq_pid];
-  nb_rb = harq_process->nb_rb;
-  nb_symb_sch = harq_process->number_of_symbols;
-  A = harq_process->TBS;
+  nb_rb = harq_process->pusch_pdu.rb_size;
+  A = harq_process->pusch_pdu.pusch_data.tb_size;
   pz = &Z;
-  mod_order = nr_get_Qm_ul(harq_process->mcs,0);
-  R = nr_get_code_rate_ul(harq_process->mcs, 0);
+  mod_order = nr_get_Qm_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
+  R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
   Kr=0;
   r_offset=0;
   BG = 1;
   F=0;
   Ilbrm = 0;
   Tbslbrm = 950984; //max tbs
-  nb_re_dmrs = ulsch->nb_re_dmrs;
-  length_dmrs = ulsch->length_dmrs;
   Coderate = 0.0;
 
 ///////////
@@ -271,10 +266,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
 
-  LOG_D(PHY,"ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d, harq_process->Nl = %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs, harq_process->Nl);
-
-
-  G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl);
+  LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
   LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
 
   //  if (harq_process->Ndi == 1) {  // this is a new packet
@@ -356,11 +348,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
     Kr_bytes = Kr>>3;
 #endif
 
-///////////
-/////////////////////////////////////////////////////////////////////////////////////
-
-opp_enabled=0;
-
 ///////////////////////// c---->| LDCP coding |---->d /////////////////////////
 ///////////
 
@@ -386,6 +373,12 @@ opp_enabled=0;
     //for (int i=0;i<68*384;i++)
       //        printf("channel_input[%d]=%d\n",i,channel_input[i]);
 
+    int temp_opp = 0;
+
+    if (opp_enabled) {
+      opp_enabled = 0;
+      temp_opp = 1;
+    }
 
 
     /*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
@@ -402,10 +395,12 @@ opp_enabled=0;
     //stop_meas(te_stats);
     //printf("end ldpc encoder -- output\n");
 #ifdef DEBUG_DLSCH_CODING
-      write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
-      write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
+    write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
+    write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
 #endif
 
+    if (temp_opp) opp_enabled = 1;
+
 ///////////
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -431,15 +426,15 @@ opp_enabled=0;
 
     //start_meas(rm_stats);
 #ifdef DEBUG_DLSCH_CODING
-  printf("rvidx in encoding = %d\n", harq_process->rvidx);
+  printf("rvidx in encoding = %d\n", harq_process->pusch_pdu.pusch_data.rv_index);
 #endif
 
 ///////////////////////// d---->| Rate matching bit selection |---->e /////////////////////////
 ///////////
 
-    E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r);
+    E = nr_get_E(G, harq_process->C, mod_order, harq_process->pusch_pdu.nrOfLayers, r);
 
-    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->Nl,harq_process->C);
+    Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers,harq_process->C);
 
     nr_rate_matching_ldpc(Ilbrm,
                           Tbslbrm,
@@ -450,7 +445,7 @@ opp_enabled=0;
                           harq_process->C,
 			  F,
                           Kr-F-2*(*pz),
-                          harq_process->rvidx,
+                          harq_process->pusch_pdu.pusch_data.rv_index,
                           E);
 
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index f1d4a304f97..69b3421ace1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -98,7 +98,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
                                uint8_t thread_id,
                                int gNB_id) {
 
-  uint32_t available_bits;
+  uint32_t available_bits, TBS;
   uint8_t mod_order, cwd_index, num_of_codewords, l;
   uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
   uint32_t ***pusch_dmrs;
@@ -106,67 +106,66 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   int32_t **txdataF;
   uint16_t start_sc, start_rb;
   int8_t Wf[2], Wt[2], l_prime[2], delta;
-  uint16_t n_dmrs, code_rate, number_dmrs_symbols, k;
-  uint8_t dmrs_type;
+  uint16_t rnti, n_dmrs, code_rate, number_dmrs_symbols, nb_rb, k;
+  uint8_t dmrs_type, nb_dmrs_re_per_rb, number_of_symbols, mcs, Nl;
   int ap, start_symbol, Nid_cell, i;
   int sample_offsetF, N_RE_prime, N_PRB_oh;
-  uint16_t n_rnti;
+  uint16_t n_rnti, ul_dmrs_symb_pos;
   uint8_t data_existing =0;
   uint8_t L_ptrs, K_ptrs; // PTRS parameters
   uint16_t beta_ptrs; // PTRS parameter related to power control
 
   NR_UE_ULSCH_t *ulsch_ue;
-  NR_UL_UE_HARQ_t *harq_process_ul_ue;
+  NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
   NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
   NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
   uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
-  ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
+  // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
 
   num_of_codewords = 1; // tmp assumption
-  n_rnti = 0x1234;
   Nid_cell = 0;
   N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
   number_dmrs_symbols = 0;
-  uint8_t mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
 
   for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
 
     ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
     harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
 
-    start_symbol = harq_process_ul_ue->start_symbol;
-
-    for (i = start_symbol; i < start_symbol + harq_process_ul_ue->number_of_symbols; i++)
-      number_dmrs_symbols += is_dmrs_symbol((mapping_type)?i-start_symbol:i,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            harq_process_ul_ue->number_of_symbols,
-                                            UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
-                                            frame_parms->ofdm_symbol_size);
-
-    ulsch_ue->length_dmrs = number_dmrs_symbols; // pusch.MaxLenght is redundant here as number_dmrs_symbols
-                                                 // contains all dmrs symbols even for double symbol dmrs
-    ulsch_ue->rnti        = n_rnti;
+    start_symbol      = harq_process_ul_ue->pusch_pdu.start_symbol_index;
+    ul_dmrs_symb_pos  = harq_process_ul_ue->pusch_pdu.ul_dmrs_symb_pos;
+    number_of_symbols = harq_process_ul_ue->pusch_pdu.nr_of_symbols;
+    dmrs_type         = harq_process_ul_ue->pusch_pdu.dmrs_config_type;
+
+    for (i = start_symbol; i < start_symbol + number_of_symbols; i++) {
+
+      if((ul_dmrs_symb_pos >> i) & 0x01)
+        number_dmrs_symbols += 1;
+
+    }
+
+    rnti                  = harq_process_ul_ue->pusch_pdu.rnti;
     ulsch_ue->Nid_cell    = Nid_cell;
-    ulsch_ue->nb_re_dmrs  = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4);
+    nb_dmrs_re_per_rb     = ((dmrs_type == pusch_dmrs_type1) ? 6:4);
+
+    N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
 
-    N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs*number_dmrs_symbols - N_PRB_oh;
+    nb_rb = harq_process_ul_ue->pusch_pdu.rb_size;
 
-    harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords;
+    harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
 
-    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
-    code_rate      = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 0);
+    mcs            = harq_process_ul_ue->pusch_pdu.mcs_index;
+    Nl             = harq_process_ul_ue->pusch_pdu.nrOfLayers;
+    mod_order      = nr_get_Qm_ul(mcs, 0);
+    code_rate      = nr_get_code_rate_ul(mcs, 0);
 
-    harq_process_ul_ue->TBS = nr_compute_tbs(mod_order, 
+    harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = nr_compute_tbs(mod_order,
                                              code_rate,
-                                             harq_process_ul_ue->nb_rb,
-                                             harq_process_ul_ue->number_of_symbols,
-                                             ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs,
+                                             nb_rb,
+                                             number_of_symbols,
+                                             nb_dmrs_re_per_rb*number_dmrs_symbols,
                                              0,
-                                             harq_process_ul_ue->Nl);
+                                             harq_process_ul_ue->pusch_pdu.nrOfLayers);
 
     uint8_t access_mode = SCHEDULED_ACCESS;
 
@@ -174,19 +173,20 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     // to be removed later when MAC is ready
 
     if (harq_process_ul_ue != NULL){
+      TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size;
       data_existing = 0;
 
     	if (IS_SOFTMODEM_NOS1){
-    		data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
-    				slot, 0, ulsch_input_buffer, harq_process_ul_ue->TBS/8, &access_mode);
+        data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
+                                      slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
     		//IP traffic to be transmitted
-    		if(data_existing){
-    			//harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char));
-    			memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8);
+        if(data_existing){
+          //harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
+          memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8);
 
     			#ifdef DEBUG_MAC_PDU
-    				LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", harq_process_ul_ue->TBS/8);
-    				for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) {
+            LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
+            for (i = 0; i < TBS / 8; i++) {
     					printf("0x%02x",harq_process_ul_ue->a[i]);
     				}
     				printf("\n");
@@ -203,7 +203,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
         for (i = 0; i<payload_offset; i++)
           harq_process_ul_ue->a[i] = 0;
 
-        for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) {
+        for (i = payload_offset; i < TBS / 8; i++) {
           harq_process_ul_ue->a[i] = (unsigned char) rand();
           //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
         }
@@ -218,8 +218,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     /////////////////////////ULSCH coding/////////////////////////
     ///////////
 
+    unsigned int G = nr_get_G(nb_rb, number_of_symbols,
+                              nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
 
-    nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid);
+    nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
 
     ///////////
     ////////////////////////////////////////////////////////////////////
@@ -227,21 +229,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
     /////////////////////////ULSCH scrambling/////////////////////////
     ///////////
 
-    mod_order      = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
-
-    available_bits = nr_get_G(harq_process_ul_ue->nb_rb,
-                              harq_process_ul_ue->number_of_symbols,
-                              ulsch_ue->nb_re_dmrs,
-                              ulsch_ue->length_dmrs,
-                              mod_order,
-                              1);
+    available_bits = G;
 
     memset(scrambled_output[cwd_index], 0, ((available_bits>>5)+1)*sizeof(uint32_t));
 
     nr_pusch_codeword_scrambling(ulsch_ue->g,
                                  available_bits,
                                  ulsch_ue->Nid_cell,
-                                 ulsch_ue->rnti,
+                                 rnti,
                                  scrambled_output[cwd_index]); // assume one codeword for the moment
 
 
@@ -269,9 +264,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   /////////////////////////DMRS Modulation/////////////////////////
   ///////////
   pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
-  n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs);
+  n_dmrs = (nb_rb*nb_dmrs_re_per_rb*number_dmrs_symbols);
   int16_t mod_dmrs[n_dmrs<<1];
-  dmrs_type = UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type;
   ///////////
   ////////////////////////////////////////////////////////////////////////
 
@@ -279,26 +273,23 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   /////////////////////////PTRS parameters' initialization/////////////////////////
   ///////////
 
-  int16_t mod_ptrs[(harq_process_ul_ue->nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
+  int16_t mod_ptrs[(nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
   K_ptrs = 0; // just to avoid a warning
 
-  if (UE->ptrs_configured == 1) {
-
-    K_ptrs = get_K_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->nb_rb);
+  if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
 
-    L_ptrs = get_L_ptrs(ptrs_Uplink_Config, harq_process_ul_ue->mcs);
+    K_ptrs = (harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density)?4:2;
+    L_ptrs = 1<<harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_time_density;
 
     beta_ptrs = 1; // temp value until power control is implemented
 
     ulsch_ue->ptrs_symbols = 0;
 
     set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols,
-                      harq_process_ul_ue->number_of_symbols,
+                      number_of_symbols,
                       start_symbol,
-                      dmrs_type,
                       L_ptrs,
-                      ulsch_ue->length_dmrs,
-                      frame_parms->ofdm_symbol_size);
+                      ul_dmrs_symb_pos);
   }
 
   ///////////
@@ -310,7 +301,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   tx_layers = (int16_t **)pusch_ue->txdataF_layers;
 
   nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id],
-                   harq_process_ul_ue->Nl,
+                   Nl,
                    available_bits/mod_order,
                    tx_layers);
 
@@ -327,24 +318,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
   uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
   uint32_t y_offset = 0;
 
-  for (l = start_symbol; l < start_symbol + harq_process_ul_ue->number_of_symbols; l++) {
+  for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
 
-    is_dmrs = is_dmrs_symbol((mapping_type)?l-start_symbol:l,
-                             0,
-                             0,
-                             0,
-                             0,
-                             0,
-                             harq_process_ul_ue->number_of_symbols,
-                             dmrs_type,
-                             frame_parms->ofdm_symbol_size);
+    if((ul_dmrs_symb_pos >> l) & 0x01)
+      is_dmrs = 1;
+    else
+      is_dmrs = 0;
 
     if (is_dmrs == 1)
-      nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs;
+      nb_re_dmrs_per_rb = nb_dmrs_re_per_rb;
     else
       nb_re_dmrs_per_rb = 0;
     
-    nb_re_pusch = harq_process_ul_ue->nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
+    nb_re_pusch = nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
 
     nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
 
@@ -364,13 +350,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
   txdataF = UE->common_vars.txdataF;
 
-  start_rb = harq_process_ul_ue->first_rb;
+  start_rb = harq_process_ul_ue->pusch_pdu.rb_start;
   start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
 
   if (start_sc >= frame_parms->ofdm_symbol_size)
     start_sc -= frame_parms->ofdm_symbol_size;
 
-  for (ap=0; ap<harq_process_ul_ue->Nl; ap++) {
+  for (ap=0; ap< Nl; ap++) {
 
     // DMRS params for this ap
     get_Wt(Wt, ap, dmrs_type);
@@ -380,46 +366,38 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
 
     uint8_t k_prime=0;
     uint8_t is_dmrs, is_ptrs;
-    uint8_t l_ref;
     uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
 
-    for (l=start_symbol; l<start_symbol+harq_process_ul_ue->number_of_symbols; l++) {
+    for (l=start_symbol; l<start_symbol+number_of_symbols; l++) {
 
       k = start_sc;
       n = 0;
       dmrs_idx = 0;
-      l_ref = (mapping_type) ? l-start_symbol : l;
 
-      for (i=0; i<harq_process_ul_ue->nb_rb*NR_NB_SC_PER_RB; i++) {
+      for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
 
         sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
 
         is_dmrs = 0;
         is_ptrs = 0;
 
-        is_dmrs = is_dmrs_symbol(l_ref,
-                                 k,
-                                 start_sc,
-                                 k_prime,
-                                 n,
-                                 delta,
-                                 harq_process_ul_ue->number_of_symbols,
-                                 dmrs_type,
-                                 frame_parms->ofdm_symbol_size);
-
-        if (UE->ptrs_configured == 1){
-          is_ptrs = is_ptrs_symbol(l,
-                                   k,
-                                   ulsch_ue->rnti,
-                                   harq_process_ul_ue->nb_rb,
-                                   harq_process_ul_ue->number_of_symbols,
-                                   ap,
-                                   K_ptrs,
-                                   ulsch_ue->ptrs_symbols,
-                                   start_sc,
-                                   frame_parms->ofdm_symbol_size,
-                                   UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
-                                   ptrs_Uplink_Config->resourceElementOffset);
+        if((ul_dmrs_symb_pos >> l) & 0x01) {
+          if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
+            is_dmrs = 1;
+        }
+
+        if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS){
+
+          if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols))
+            is_ptrs = is_ptrs_subcarrier(k,
+                                         rnti,
+                                         ap,
+                                         dmrs_type,
+                                         K_ptrs,
+                                         nb_rb,
+                                         harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
+                                         start_sc,
+                                         frame_parms->ofdm_symbol_size);
         }
 
         if (is_dmrs == 1) {
@@ -446,7 +424,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
         }  else if (is_ptrs == 1) {
 
           if (k == start_sc){
-            nr_modulation(pusch_dmrs[l][0], harq_process_ul_ue->nb_rb/2, DMRS_MOD_ORDER, mod_ptrs);
+            nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
           }
 
           ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
@@ -494,7 +472,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
   int32_t **txdata;
   int32_t **txdataF;
   int timing_advance;
-  uint8_t Nl = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->Nl; // cw 0
+  uint8_t Nl = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers; // cw 0
 
   /////////////////////////IFFT///////////////////////
   ///////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index e8eceb77a6d..baf34ade92a 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -52,7 +52,7 @@
 *
 * PARAMETERS :   size of ofdm symbol
 *
-* RETURN :       function idft
+* RETURN :       index pointing to the dft func in the dft library
 *
 * DESCRIPTION :  get idft function depending of ofdm size
 *
@@ -60,45 +60,45 @@
 
 //#define DBG_PSS_NR
 
-void *get_idft(int ofdm_symbol_size)
+idft_size_idx_t get_idft(int ofdm_symbol_size)
 {
-  void (*idft)(int16_t *,int16_t *, int);
-
+  
+ 
   switch (ofdm_symbol_size) {
     case 128:
-      idft = idft128;
+      return IDFT_128;
       break;
 
     case 256:
-      idft = idft256;
+      return IDFT_256;
       break;
 
     case 512:
-      idft = idft512;
+      return IDFT_512;
       break;
 
     case 1024:
-      idft = idft1024;
+      return IDFT_1024;
       break;
 
     case 1536:
-      idft = idft1536;
+      return IDFT_1536;
       break;
 
     case 2048:
-      idft = idft2048;
+      return IDFT_2048;
       break;
 
     case 3072:
-      idft = idft3072;
+      return IDFT_3072;
       break;
 
     case 4096:
-      idft = idft4096;
+      return IDFT_4096;
       break;
 
     case 8192:
-      idft = idft8192;
+      return IDFT_8192;
       break;
 
     default:
@@ -106,7 +106,7 @@ void *get_idft(int ofdm_symbol_size)
       assert(0);
       break;
  }
- return idft;
+ return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function
 }
 
 /*******************************************************************
@@ -121,41 +121,41 @@ void *get_idft(int ofdm_symbol_size)
 *
 *********************************************************************/
 
-void *get_dft(int ofdm_symbol_size)
+dft_size_idx_t get_dft(int ofdm_symbol_size)
 {
-  void (*dft)(int16_t *,int16_t *, int);
+
 
   switch (ofdm_symbol_size) {
     case 128:
-      dft = dft128;
+      return DFT_128;
       break;
 
     case 256:
-      dft = dft256;
+      return DFT_256;
       break;
 
     case 512:
-      dft = dft512;
+      return DFT_512;
       break;
 
     case 1024:
-      dft = dft1024;
+      return DFT_1024;
       break;
 
     case 1536:
-      dft = dft1536;
+      return DFT_1536;
       break;
 
     case 2048:
-      dft = dft2048;
+      return DFT_2048;
       break;
 
     case 4096:
-      dft = dft4096;
+      return DFT_4096;
       break;
 
     case 8192:
-      dft = dft8192;
+      return DFT_8192;
       break;
 
     default:
@@ -163,7 +163,7 @@ void *get_dft(int ofdm_symbol_size)
       assert(0);
       break;
  }
- return dft;
+ return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function;
 }
 
 /*******************************************************************
@@ -191,7 +191,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
   unsigned int size = length * IQ_SIZE; /* i & q */
   int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
   int16_t *primary_synchro2 = primary_synchro_nr2[N_ID_2]; /* pss in complex with alternatively i then q */
-  void (*idft)(int16_t *,int16_t *, int);
+
 
   #define INITIAL_PSS_NR    (7)
   const int x_initial[INITIAL_PSS_NR] = {0, 1, 1 , 0, 1, 1, 1};
@@ -282,9 +282,10 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
 
   /* IFFT will give temporal signal of Pss */
 
-  idft = get_idft(length);
-
-  idft(synchroF_tmp,          /* complex input */
+ 
+ 
+  idft((int16_t)get_idft(length),
+  	   synchroF_tmp,          /* complex input */
        synchro_tmp,           /* complex output */
        1);                 /* scaling factor */
 
@@ -312,6 +313,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
 #endif
 
 
+
 #if 0
 
 /* it allows checking that process of idft on a signal and then dft gives same signal with limited errors */
@@ -323,10 +325,11 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2)
 
     bzero(synchroF_tmp, size);
 
-    void (*dft)(int16_t *,int16_t *, int) = get_dft(length);
+  
 
     /* get pss in the time domain by applying an inverse FFT */
-    dft(synchro_tmp,           /* complex input */
+    dft((int16_t)get_dft(length),
+    	synchro_tmp,           /* complex input */
         synchroF_tmp,          /* complex output */
         1);                 /* scaling factor */
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index 351c4ea22a5..c8f7268d04c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -37,157 +37,20 @@
 //#include "LAYER2/MAC/extern.h"
 #include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
-
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
 #include "T.h"
+//#define NR_UNIT_TEST 1
 #ifdef NR_UNIT_TEST
   #define DEBUG_PUCCH_TX
   #define DEBUG_NR_PUCCH_TX
 #endif
-//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
-
-void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping,
-  				uint32_t n_id,
-  				uint8_t n_hop,
-  				int nr_tti_tx,
-  				uint8_t *u,
-  				uint8_t *v) {
-  /*
-   * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping
-   * The following variables are set by higher layers:
-   *    - PUCCH_GroupHopping:
-   *    - n_id: higher-layer parameter hoppingId
-   *    - n_hop: frequency hopping index
-   *             if intra-slot frequency hopping is disabled by the higher-layer parameter PUCCH-frequency-hopping
-   *                n_hop=0
-   *             if frequency hopping is enabled by the higher-layer parameter PUCCH-frequency-hopping
-   *                n_hop=0 for the first hop
-   *                n_hop=1 for the second hop
-   */
-  // depending on the value of the PUCCH_GroupHopping, we will obtain different values for u,v
-  //pucch_GroupHopping_t PUCCH_GroupHopping = ue->pucch_config_common_nr->pucch_GroupHopping; // from higher layers FIXME!!!
-  // n_id defined as per TS 38.211 subclause 6.3.2.2.1 (is given by the higher-layer parameter hoppingId)
-  // it is hoppingId from PUCCH-ConfigCommon:
-  // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled
-  // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10))
-  //uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!!
-#ifdef DEBUG_NR_PUCCH_TX
-  // initialization to be removed
-  PUCCH_GroupHopping=neither;
-  n_id=10;
-  printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%u, n_id=%u -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id);
-#endif
-  uint8_t f_ss=0,f_gh=0;
-  *u=0;
-  *v=0;
-  uint32_t c_init = 0; 
-  uint32_t x1,s; // TS 38.211 Subclause 5.2.1
-  int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3);
-  int tmpShift =0;
-#ifdef DEBUG_NR_PUCCH_TX
-  printf("\t\t [nr_group_sequence_hopping] calculating u,v -> ");
-#endif
-
-  if (PUCCH_GroupHopping == neither) { // PUCCH_GroupHopping 'neither'
-    f_ss = n_id%30;
-  }
-
-  if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled'
-    c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211
-    s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
-    for (int m=0; m<8; m++) {
-      while(minShift >= l) {
-        s = lte_gold_generic(&x1, &c_init, 0);
-        l = l+32;
-      }
-
-      tmpShift = (minShift&((1<<5)-1)); //minShift%32;
-      f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1)));
-      minShift ++;
-    }
-
-    f_gh = f_gh%30;
-    f_ss = n_id%30;
-    /*    for (int m=0; m<8; m++){
-          f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!!
-        }
-        f_gh = f_gh%30;
-        f_ss = n_id%30;*/
-  }
-
-  if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled'
-    c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v
-    s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
-    f_ss = n_id%30;
-    l = 32, minShift = (2*nr_tti_tx+n_hop);
-
-    while(minShift >= l) {
-      s = lte_gold_generic(&x1, &c_init, 0);
-      l = l+32;
-    }
-
-    tmpShift = (minShift&((1<<5)-1)); //minShift%32;
-    *v = (uint8_t)((s>>tmpShift)&1);
-    //    *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!!
-  }
-
-  *u = (f_gh+f_ss)%30;
-#ifdef DEBUG_NR_PUCCH_TX
-  printf("%d,%d\n",*u,*v);
-#endif
-}
-
-double nr_cyclic_shift_hopping(uint32_t n_id,
-                               uint8_t m0,
-                               uint8_t mcs,
-                               uint8_t lnormal,
-                               uint8_t lprime,
-                               int nr_tti_tx) {
-  /*
-   * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping
-   *     - n_id: higher-layer parameter hoppingId
-   *     - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config
-   *     - mcs: mcs=0 except for PUCCH format 0 when it depends on information to be transmitted according to TS 38.213 subclause 9.2
-   *     - lnormal: lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission
-   *     - lprime: lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
-   */
-  // alpha_init initialized to 2*PI/12=0.5235987756
-  double alpha = 0.5235987756;
-  uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs
-#ifdef DEBUG_NR_PUCCH_TX
-  // initialization to be remo.ved
-  c_init=10;
-  printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%u -> variable initialization TO BE REMOVED\n",c_init);
-#endif
-  uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
-  uint8_t n_cs=0;
-  int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime);
-  int tmpShift =0;
-#ifdef DEBUG_NR_PUCCH_TX
-  printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init);
-#endif
-
-  for (int m=0; m<8; m++) {
-    while(minShift >= l) {
-      s = lte_gold_generic(&x1, &c_init, 0);
-      l = l+32;
-    }
 
-    tmpShift = (minShift&((1<<5)-1)); //minShift%32;
-    minShift ++;
-    n_cs = n_cs+((1<<m)*((uint8_t)((s>>tmpShift)&1)));
-    // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!)
-    // n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1)));
-  }
+//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
 
-  alpha = (alpha * (double)((m0+mcs+n_cs)%12));
-#ifdef DEBUG_NR_PUCCH_TX
-  printf("n_cs=%d -> %lf\n",n_cs,alpha);
-#endif
-  return(alpha);
-}
 void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
@@ -271,46 +134,31 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
    */
   //int32_t *txptr;
   uint32_t re_offset=0;
+  uint8_t l2;
 
   for (int l=0; l<nrofSymbols; l++) {
-    if ((startingPRB <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
-
-    if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
-    }
-
-    if ((startingPRB <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB is lower band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
-
-    if ((startingPRB >  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB is upper band
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
-    }
-
-    if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd  and current PRB contains DC
-      re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
-    }
+    l2=l+startingSymbolIndex;
+    re_offset = (12*startingPRB) + frame_parms->first_carrier_offset;
+    if (re_offset>= frame_parms->ofdm_symbol_size) 
+      re_offset-=frame_parms->ofdm_symbol_size;
 
     //txptr = &txdataF[0][re_offset];
     for (int n=0; n<12; n++) {
-      if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
-        // if number RBs in bandwidth is odd  and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
-        re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
-      }
 
-      ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15);
-      ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15);
+      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15);
+      ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15);
       //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15;
       //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15;
       //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n];
 #ifdef DEBUG_NR_PUCCH_TX
       printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
-             amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset,
-             l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
+             amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size) + re_offset,
+             l2,n,((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[0],
+             ((int16_t *)&txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset])[1]);
 #endif
       re_offset++;
+      if (re_offset>= frame_parms->ofdm_symbol_size) 
+        re_offset-=frame_parms->ofdm_symbol_size;
     }
   }
 }
@@ -1059,7 +907,9 @@ void nr_uci_encoding(uint64_t payload,
   if (A<=11) {
     // procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2)
     // CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
+    b[0] = encodeSmallBlock((uint16_t*)&payload,A);
   } else if (A>=12) {
+    AssertFatal(1==0,"Polar encoding not supported yet for UCI\n");
     // procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
     /*if ((A>=360 && E>=1088)||(A>=1013)) {
       I_seg = 1;
@@ -1078,10 +928,13 @@ void nr_uci_encoding(uint64_t payload,
     // code block segmentation and CRC attachment is performed according to subclause 5.2.1
     // polar coding subclause 5.3.1
   }
+  
 }
 //#if 0
 void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
                         uint16_t crnti,
+			uint32_t dmrs_scrambling_id,
+			uint32_t data_scrambling_id,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
                         PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
@@ -1115,14 +968,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
    */
   uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
   // rnti is given by the C-RNTI
-  uint16_t rnti=crnti, n_id=0;
+  uint16_t rnti=crnti;
 #ifdef DEBUG_NR_PUCCH_TX
   printf("\t [nr_generate_pucch2] rnti = %d ,\n",rnti);
 #endif
   /*
    * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
    */
-  nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
+  nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,b,btilde);
   /*
    * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
    * btilde shall be modulated as described in subclause 5.1 using QPSK
@@ -1170,10 +1023,10 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
   int m=0;
 
   for (int l=0; l<nrofSymbols; l++) {
-    x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*n_id) + 1)) + (2*n_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+    x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*dmrs_scrambling_id) + 1)) + (2*dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+
     s = lte_gold_generic(&x1, &x2, 1);
     m = 0;
-
     for (int rb=0; rb<nrofPRB; rb++) {
       //startingPRB = startingPRB + rb;
       if (((rb+startingPRB) <  (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
index e8cd147526b..a2446dccf99 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h
@@ -20,7 +20,7 @@
  */
 
 /*! \file PHY/NR_UE_TRANSPORT/pucch_nr.c
-* \brief Top-level routines for generating and decoding the PUCCH physical channel
+* \brief Top-level routines for generating the PUCCH physical channel
 * \author A. Mico Pereperez
 * \date 2018
 * \version 0.1
@@ -29,6 +29,9 @@
 * \note
 * \warning
 */
+#ifndef __PUCCH_NR__H__
+#define __PUCCH_NR__H__
+
 //#include "PHY/defs.h"
 #include "PHY/impl_defs_nr.h"
 #include "PHY/defs_nr_common.h"
@@ -42,46 +45,7 @@
 #include "T.h"
 #define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
 
-void nr_decode_pucch1(  int32_t **rxdataF,
-                        pucch_GroupHopping_t pucch_GroupHopping,
-                        uint32_t n_id,       // hoppingID higher layer parameter
-                        uint64_t *payload,
-                        NR_DL_FRAME_PARMS *frame_parms,
-                        int16_t amp,
-                        int nr_tti_tx,
-                        uint8_t m0,
-                        uint8_t nrofSymbols,
-                        uint8_t startingSymbolIndex,
-                        uint16_t startingPRB,
-                        uint16_t startingPRB_intraSlotHopping,
-                        uint8_t timeDomainOCC,
-                        uint8_t nr_bit);
-
-void nr_decode_pucch0( int32_t **rxdataF,
-			pucch_GroupHopping_t PUCCH_GroupHopping,
-                        uint32_t n_id,                                       //PHY_VARS_gNB *gNB, generally rxdataf is in gNB->common_vars
-                        uint64_t *payload,
-                        NR_DL_FRAME_PARMS *frame_parms,
-                        int16_t amp,
-                        int nr_tti_tx,
-                        uint8_t m0,                                          // should come from resource set
-                        uint8_t nrofSymbols,				    // should come from resource set	
-                        uint8_t startingSymbolIndex,			    // should come from resource set
-                        uint16_t startingPRB,				   // should come from resource set
-			uint8_t nr_bit);
 
-void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping,
-                                uint32_t n_id,
-                                uint8_t n_hop,
-                                int nr_tti_tx,
-                                uint8_t *u,
-                                uint8_t *v);
-double nr_cyclic_shift_hopping(uint32_t n_id,
-                               uint8_t m0,
-                               uint8_t mcs,
-                               uint8_t lnormal,
-                               uint8_t lprime,
-                               int nr_tti_tx);
 void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
@@ -109,6 +73,8 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
                         uint8_t nr_bit);
 void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
                         uint16_t crnti,
+			uint32_t dmrs_scrambling_id,
+			uint32_t data_scrambling_id,
                         int32_t **txdataF,
                         NR_DL_FRAME_PARMS *frame_parms,
                         PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
@@ -139,8 +105,8 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
                           uint8_t occ_index_format4);
 
 // tables for mcs values for different payloads 
- static const uint8_t table1_mcs[]={0,3,6,9};
- static const uint8_t table2_mcs[]={0,1,3,4,6,7,9,10};
+ static const uint8_t table1_mcs[]={0,6,3,9};
+ static const uint8_t table2_mcs[]={0,3,9,6,1,4,10,7};
 
   /*
    * The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1)
@@ -454,3 +420,4 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
                                          73, 79, 83, 89, 97, 101,103,107,109,113,
                                          127,131,137,139,149,151,157,163,167,173,
                                          179,181,191,193,197,199};
+#endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index 44d500b0b7e..e3f1f13a8d1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -182,7 +182,7 @@ void insert_sss_nr(int16_t *sss_time,
   }
 
   /* get sss in the frequency domain by applying an inverse FFT */
-  idft2048(synchroF_tmp,          /* complex input */
+  idft(IDFT_2048,synchroF_tmp,          /* complex input */
            synchro_tmp,           /* complex output */
    	   1);                    /* scaling factor */
 
diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c
deleted file mode 100644
index 2de8653ab39..00000000000
--- a/openair1/PHY/TOOLS/lte_dfts.c
+++ /dev/null
@@ -1,9688 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdint.h>
-#include <math.h>
-#include <pthread.h>
-#include <execinfo.h>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#ifndef MR_MAIN
-#include "PHY/defs_common.h"
-#include "PHY/impl_defs_top.h"
-#include "tools_defs.h"
-#else
-#include "time_meas.h"
-#include "LOG/log.h"
-#define debug_msg
-#define ONE_OVER_SQRT2_Q15 23170
-
-int oai_exit=0;
-#endif
-
-#define ONE_OVER_SQRT3_Q15 18919
-
-#include "../sse_intrin.h"
-
-#include "assertions.h"
-
-#define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
-#define print_shorts256(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7],(x)[8],(x)[9],(x)[10],(x)[11],(x)[12],(x)[13],(x)[14],(x)[15])
-
-#define print_ints(s,x) printf("%s %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
-
-
-const static int16_t conjugatedft[32] __attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1};
-
-
-const static int16_t reflip[32]  __attribute__((aligned(32))) = {1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1};
-
-
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void cmac(__m128i a,__m128i b, __m128i *re32, __m128i *im32) __attribute__((always_inline));
-static inline void cmac(__m128i a,__m128i b, __m128i *re32, __m128i *im32)
-{
-
-  __m128i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
-
-  cmac_tmp    = _mm_sign_epi16(b,*(__m128i*)reflip);
-  cmac_tmp_re32  = _mm_madd_epi16(a,cmac_tmp);
-
- 
-  //  cmac_tmp    = _mm_shufflelo_epi16(b,_MM_SHUFFLE(2,3,0,1));
-  //  cmac_tmp    = _mm_shufflehi_epi16(cmac_tmp,_MM_SHUFFLE(2,3,0,1));
-  cmac_tmp = _mm_shuffle_epi8(b,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  cmac_tmp_im32  = _mm_madd_epi16(cmac_tmp,a);
-
-  *re32 = _mm_add_epi32(*re32,cmac_tmp_re32);
-  *im32 = _mm_add_epi32(*im32,cmac_tmp_im32);
-}
-
-static inline void cmacc(__m128i a,__m128i b, __m128i *re32, __m128i *im32) __attribute__((always_inline));
-static inline void cmacc(__m128i a,__m128i b, __m128i *re32, __m128i *im32)
-{
-
-  __m128i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
-
-
-  cmac_tmp_re32  = _mm_madd_epi16(a,b);
-
-
-  cmac_tmp    = _mm_sign_epi16(b,*(__m128i*)reflip);
-  //  cmac_tmp    = _mm_shufflelo_epi16(b,_MM_SHUFFLE(2,3,0,1));
-  //  cmac_tmp    = _mm_shufflehi_epi16(cmac_tmp,_MM_SHUFFLE(2,3,0,1));
-  cmac_tmp = _mm_shuffle_epi8(cmac_tmp,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  cmac_tmp_im32  = _mm_madd_epi16(cmac_tmp,a);
-
-  *re32 = _mm_add_epi32(*re32,cmac_tmp_re32);
-  *im32 = _mm_add_epi32(*im32,cmac_tmp_im32);
-}
-
-#ifdef __AVX2__
-static inline void cmac_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) __attribute__((always_inline));
-static inline void cmac_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
-{
-
-  __m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
-  __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  cmac_tmp       = _mm256_sign_epi16(b,*(__m256i*)reflip);
-  cmac_tmp_re32  = _mm256_madd_epi16(a,cmac_tmp);
-
-  cmac_tmp       = _mm256_shuffle_epi8(b,imshuffle);
-  cmac_tmp_im32  = _mm256_madd_epi16(cmac_tmp,a);
-
-  *re32 = _mm256_add_epi32(*re32,cmac_tmp_re32);
-  *im32 = _mm256_add_epi32(*im32,cmac_tmp_im32);
-}
-
-static inline void cmacc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) __attribute__((always_inline));
-static inline void cmacc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
-{
-
-  __m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
-  __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  cmac_tmp_re32   = _mm256_madd_epi16(a,b);
-
-
-  cmac_tmp        = _mm256_sign_epi16(b,*(__m256i*)reflip);
-  cmac_tmp        = _mm256_shuffle_epi8(b,imshuffle);
-  cmac_tmp_im32   = _mm256_madd_epi16(cmac_tmp,a);
-
-  *re32 = _mm256_add_epi32(*re32,cmac_tmp_re32);
-  *im32 = _mm256_add_epi32(*im32,cmac_tmp_im32);
-}
-
-#endif
-
-static inline void cmult(__m128i a,__m128i b, __m128i *re32, __m128i *im32) __attribute__((always_inline));
-
-static inline void cmult(__m128i a,__m128i b, __m128i *re32, __m128i *im32)
-{
-
-  register __m128i mmtmpb;
-
-  mmtmpb    = _mm_sign_epi16(b,*(__m128i*)reflip);
-  *re32     = _mm_madd_epi16(a,mmtmpb);
-  //  mmtmpb    = _mm_shufflelo_epi16(b,_MM_SHUFFLE(2,3,0,1));
-  //  mmtmpb    = _mm_shufflehi_epi16(mmtmpb,_MM_SHUFFLE(2,3,0,1));
-  mmtmpb        = _mm_shuffle_epi8(b,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  *im32  = _mm_madd_epi16(a,mmtmpb);
-
-}
-
-#ifdef __AVX2__
-static inline void cmult_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) __attribute__((always_inline));
-
-static inline void cmult_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
-{
-
-  register __m256i mmtmpb;
-  __m256i const perm_mask = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  mmtmpb    = _mm256_sign_epi16(b,*(__m256i*)reflip);
-  *re32     = _mm256_madd_epi16(a,mmtmpb);
-  mmtmpb    = _mm256_shuffle_epi8(b,perm_mask);
-  *im32     = _mm256_madd_epi16(a,mmtmpb);
-
-}
-
-#endif
-
-static inline void cmultc(__m128i a,__m128i b, __m128i *re32, __m128i *im32) __attribute__((always_inline));
-
-static inline void cmultc(__m128i a,__m128i b, __m128i *re32, __m128i *im32)
-{
-
-  register __m128i mmtmpb;
-
-  *re32     = _mm_madd_epi16(a,b);
-  mmtmpb    = _mm_sign_epi16(b,*(__m128i*)reflip);
-  mmtmpb    = _mm_shuffle_epi8(mmtmpb,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  *im32  = _mm_madd_epi16(a,mmtmpb);
-
-}
-
-#ifdef __AVX2__
-static inline void cmultc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) __attribute__((always_inline));
-
-static inline void cmultc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
-{
-
-  register __m256i mmtmpb;
-  __m256i const perm_mask = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  *re32     = _mm256_madd_epi16(a,b);
-  mmtmpb    = _mm256_sign_epi16(b,*(__m256i*)reflip);
-  mmtmpb    = _mm256_shuffle_epi8(mmtmpb,perm_mask);
-  *im32     = _mm256_madd_epi16(a,mmtmpb);
-
-}
-
-#endif
-
-static inline __m128i cpack(__m128i xre,__m128i xim) __attribute__((always_inline));
-
-static inline __m128i cpack(__m128i xre,__m128i xim)
-{
-
-  register __m128i cpack_tmp1,cpack_tmp2;
-
-  cpack_tmp1 = _mm_unpacklo_epi32(xre,xim);
-  cpack_tmp2 = _mm_unpackhi_epi32(xre,xim);
-  return(_mm_packs_epi32(_mm_srai_epi32(cpack_tmp1,15),_mm_srai_epi32(cpack_tmp2,15)));
-
-}
-
-#ifdef __AVX2__
-static inline __m256i cpack_256(__m256i xre,__m256i xim) __attribute__((always_inline));
-
-static inline __m256i cpack_256(__m256i xre,__m256i xim)
-{
-
-  register __m256i cpack_tmp1,cpack_tmp2;
-
-  cpack_tmp1 = _mm256_unpacklo_epi32(xre,xim);
-  cpack_tmp2 = _mm256_unpackhi_epi32(xre,xim);
-  return(_mm256_packs_epi32(_mm256_srai_epi32(cpack_tmp1,15),_mm256_srai_epi32(cpack_tmp2,15)));
-
-}
-
-#endif
-
-static inline void packed_cmult(__m128i a,__m128i b, __m128i *c) __attribute__((always_inline));
-
-static inline void packed_cmult(__m128i a,__m128i b, __m128i *c)
-{
-
-  __m128i cre,cim;
-  cmult(a,b,&cre,&cim);
-  *c = cpack(cre,cim);
-
-}
-
-#ifdef __AVX2__
-static inline void packed_cmult_256(__m256i a,__m256i b, __m256i *c) __attribute__((always_inline));
-
-static inline void packed_cmult_256(__m256i a,__m256i b, __m256i *c)
-{
-
-  __m256i cre,cim;
-  cmult_256(a,b,&cre,&cim);
-  *c = cpack_256(cre,cim);
-
-}
-#endif
-
-static inline void packed_cmultc(__m128i a,__m128i b, __m128i *c) __attribute__((always_inline));
-
-static inline void packed_cmultc(__m128i a,__m128i b, __m128i *c)
-{
-
-  __m128i cre,cim;
-
-  cmultc(a,b,&cre,&cim);
-  *c = cpack(cre,cim);
-
-}
-
-#ifdef __AVX2__
-static inline void packed_cmultc_256(__m256i a,__m256i b, __m256i *c) __attribute__((always_inline));
-
-static inline void packed_cmultc_256(__m256i a,__m256i b, __m256i *c)
-{
-
-  __m256i cre,cim;
-
-  cmultc_256(a,b,&cre,&cim);
-  *c = cpack_256(cre,cim);
-
-}
-#endif
-
-static inline __m128i packed_cmult2(__m128i a,__m128i b,__m128i b2) __attribute__((always_inline));
-
-static inline __m128i packed_cmult2(__m128i a,__m128i b,__m128i b2)
-{
-
-
-  register __m128i cre,cim;
-
-  cre       = _mm_madd_epi16(a,b);
-  cim       = _mm_madd_epi16(a,b2);
-
-  return(cpack(cre,cim));
-
-}
-
-#ifdef __AVX2__
-static inline __m256i packed_cmult2_256(__m256i a,__m256i b,__m256i b2) __attribute__((always_inline));
-
-static inline __m256i packed_cmult2_256(__m256i a,__m256i b,__m256i b2)
-{
-
-
-  register __m256i cre,cim;
-
-  cre       = _mm256_madd_epi16(a,b);
-  cim       = _mm256_madd_epi16(a,b2);
-
-  return(cpack_256(cre,cim));
-
-}
-#endif
-
-#elif defined (__arm__)
-static inline void cmac(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32) __attribute__((always_inline));
-static inline void cmac(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32)
-{
-
-  
-  int32x4_t ab_re0,ab_re1,ab_im0,ab_im1;
-  int16x8_t bflip = vrev32q_s16(b);
-  int16x8_t bconj = vmulq_s16(b,*(int16x8_t *)reflip);
-
-  ab_re0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&bconj)[0]);
-  ab_re1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&bconj)[1]);
-  ab_im0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&bflip)[0]);
-  ab_im1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&bflip)[1]);
-  *re32 = vqaddq_s32(*re32,vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
-					vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1])));
-  *im32 = vqaddq_s32(*im32,vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
-					vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1])));
-}
-
-static inline void cmacc(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32) __attribute__((always_inline));
-static inline void cmacc(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32)
-{
-  int32x4_t ab_re0,ab_re1,ab_im0,ab_im1;
-  int16x8_t bconj = vmulq_s16(b,*(int16x8_t *)reflip);
-  int16x8_t bflip = vrev32q_s16(bconj);
-
-  ab_re0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&b)[0]);
-  ab_re1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&b)[1]);
-  ab_im0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&bflip)[0]);
-  ab_im1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&bflip)[1]);
-  *re32 = vqaddq_s32(*re32,vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
-					vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1])));
-  *im32 = vqaddq_s32(*im32,vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
-					vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1])));
-
-}
-
-static inline void cmult(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32) __attribute__((always_inline));
-static inline void cmult(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32)
-{
-  int32x4_t ab_re0,ab_re1,ab_im0,ab_im1;
-  int16x8_t bflip = vrev32q_s16(b);
-  int16x8_t bconj = vmulq_s16(b,*(int16x8_t *)reflip);
-  int16x4_t al,ah,bcl,bch,bfl,bfh;
-  int32x2_t abr0l,abr0h,abr1l,abr1h,abi0l,abi0h,abi1l,abi1h;
-
-  al  = vget_low_s16(a);      ah = vget_high_s16(a);
-  bcl = vget_low_s16(bconj);  bch = vget_high_s16(bconj);
-  bfl = vget_low_s16(bflip);  bfh = vget_high_s16(bflip);
-
-  ab_re0 = vmull_s16(al,bcl);
-  ab_re1 = vmull_s16(ah,bch);
-  ab_im0 = vmull_s16(al,bfl);
-  ab_im1 = vmull_s16(ah,bfh);
-  abr0l = vget_low_s32(ab_re0); abr0h = vget_high_s32(ab_re0);
-  abr1l = vget_low_s32(ab_re1); abr1h = vget_high_s32(ab_re1);
-  abi0l = vget_low_s32(ab_im0); abi0h = vget_high_s32(ab_im0);
-  abi1l = vget_low_s32(ab_im1); abi1h = vget_high_s32(ab_im1);
-
-  *re32 = vcombine_s32(vpadd_s32(abr0l,abr0h),
-                       vpadd_s32(abr1l,abr1h));
-  *im32 = vcombine_s32(vpadd_s32(abi0l,abi0h),
-                       vpadd_s32(abi1l,abi1h));
-}
-
-static inline void cmultc(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32) __attribute__((always_inline));
-
-static inline void cmultc(int16x8_t a,int16x8_t b, int32x4_t *re32, int32x4_t *im32)
-{
-  int32x4_t ab_re0,ab_re1,ab_im0,ab_im1;
-  int16x8_t bconj = vmulq_s16(b,*(int16x8_t *)reflip);
-  int16x8_t bflip = vrev32q_s16(bconj);
-  int16x4_t al,ah,bl,bh,bfl,bfh; 
-  int32x2_t abr0l,abr0h,abr1l,abr1h,abi0l,abi0h,abi1l,abi1h;
-  al  = vget_low_s16(a);     ah = vget_high_s16(a);
-  bl  = vget_low_s16(b);     bh = vget_high_s16(b);
-  bfl = vget_low_s16(bflip); bfh = vget_high_s16(bflip);
-
-  ab_re0 = vmull_s16(al,bl);
-  ab_re1 = vmull_s16(ah,bh);
-  ab_im0 = vmull_s16(al,bfl);
-  ab_im1 = vmull_s16(ah,bfh);
-
-  abr0l = vget_low_s32(ab_re0); abr0h = vget_high_s32(ab_re0);
-  abr1l = vget_low_s32(ab_re1); abr1h = vget_high_s32(ab_re1);
-  abi0l = vget_low_s32(ab_im0); abi0h = vget_high_s32(ab_im0);
-  abi1l = vget_low_s32(ab_im1); abi1h = vget_high_s32(ab_im1);
-
-  *re32 = vcombine_s32(vpadd_s32(abr0l,abr0h),
-		       vpadd_s32(abr1l,abr1h));
-  *im32 = vcombine_s32(vpadd_s32(abi0l,abi0h),
-		       vpadd_s32(abi1l,abi1h));
-
-}
-
-
-static inline int16x8_t cpack(int32x4_t xre,int32x4_t xim) __attribute__((always_inline));
-
-static inline int16x8_t cpack(int32x4_t xre,int32x4_t xim)
-{
-  int32x4x2_t xtmp;
-
-  xtmp = vzipq_s32(xre,xim);
-  return(vcombine_s16(vqshrn_n_s32(xtmp.val[0],15),vqshrn_n_s32(xtmp.val[1],15)));
-
-}
-
-
-static inline void packed_cmult(int16x8_t a,int16x8_t b, int16x8_t *c) __attribute__((always_inline));
-
-static inline void packed_cmult(int16x8_t a,int16x8_t b, int16x8_t *c)
-{
-
-  int32x4_t cre,cim;
-  cmult(a,b,&cre,&cim);
-  *c = cpack(cre,cim);
-
-}
-
-
-static inline void packed_cmultc(int16x8_t a,int16x8_t b, int16x8_t *c) __attribute__((always_inline));
-
-static inline void packed_cmultc(int16x8_t a,int16x8_t b, int16x8_t *c)
-{
-
-  int32x4_t cre,cim;
-
-  cmultc(a,b,&cre,&cim);
-  *c = cpack(cre,cim);
-
-}
-
-static inline int16x8_t packed_cmult2(int16x8_t a,int16x8_t b,  int16x8_t b2) __attribute__((always_inline));
-
-static inline int16x8_t packed_cmult2(int16x8_t a,int16x8_t b,  int16x8_t b2)
-{
-
-  
-
-  int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,cre,cim;
-  
-  ab_re0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&b)[0]);
-  ab_re1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&b)[1]);
-  ab_im0 = vmull_s16(((int16x4_t*)&a)[0],((int16x4_t*)&b2)[0]);
-  ab_im1 = vmull_s16(((int16x4_t*)&a)[1],((int16x4_t*)&b2)[1]);
-  cre = vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
-		     vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1]));
-  cim = vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
-		     vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1]));
-  return(cpack(cre,cim));
-
-}
-
-#endif
-
-const static int16_t W0s[16]__attribute__((aligned(32))) = {32767,0,32767,0,32767,0,32767,0,32767,0,32767,0,32767,0,32767,0};
-
-const static int16_t W13s[16]__attribute__((aligned(32))) = {-16384,-28378,-16384,-28378,-16384,-28378,-16384,-28378,-16384,-28378,-16384,-28378,-16384,-28378,-16384,-28378};
-const static int16_t W23s[16]__attribute__((aligned(32))) = {-16384,28378,-16384,28378,-16384,28378,-16384,28378,-16384,28378,-16384,28378,-16384,28378,-16384,28378};
-
-const static int16_t W15s[16]__attribute__((aligned(32))) = {10126,-31163,10126,-31163,10126,-31163,10126,-31163,10126,-31163,10126,-31163,10126,-31163,10126,-31163};
-const static int16_t W25s[16]__attribute__((aligned(32))) = {-26509,-19260,-26509,-19260,-26509,-19260,-26509,-19260,-26509,-19260,-26509,-19260,-26509,-19260,-26509,-19260};
-const static int16_t W35s[16]__attribute__((aligned(32))) = {-26510,19260,-26510,19260,-26510,19260,-26510,19260,-26510,19260,-26510,19260,-26510,19260,-26510,19260};
-const static int16_t W45s[16]__attribute__((aligned(32))) = {10126,31163,10126,31163,10126,31163,10126,31163,10126,31163,10126,31163,10126,31163,10126,31163};
-
-#if defined(__x86_64__) || defined(__i386__)
-const __m128i *W0 = (__m128i *)W0s;
-const __m128i *W13 = (__m128i *)W13s;
-const __m128i *W23 = (__m128i *)W23s;
-const __m128i *W15 = (__m128i *)W15s;
-const __m128i *W25 = (__m128i *)W25s;
-const __m128i *W35 = (__m128i *)W35s;
-const __m128i *W45 = (__m128i *)W45s;
-
-#ifdef __AVX2__
-const __m256i *W0_256 =  (__m256i *)W0s;
-const __m256i *W13_256 = (__m256i *)W13s;
-const __m256i *W23_256 = (__m256i *)W23s;
-const __m256i *W15_256 = (__m256i *)W15s;
-const __m256i *W25_256 = (__m256i *)W25s;
-const __m256i *W35_256 = (__m256i *)W35s;
-const __m256i *W45_256 = (__m256i *)W45s;
-#endif
-
-#elif defined(__arm__)
-int16x8_t *W0  = (int16x8_t *)W0s;
-int16x8_t *W13 = (int16x8_t *)W13s;
-int16x8_t *W23 = (int16x8_t *)W23s;
-int16x8_t *W15 = (int16x8_t *)W15s;
-int16x8_t *W25 = (int16x8_t *)W25s;
-int16x8_t *W35 = (int16x8_t *)W35s;
-int16x8_t *W45 = (int16x8_t *)W45s;
-#endif
-const static int16_t dft_norm_table[16] = {9459,  //12
-					   6689,//24
-					   5461,//36
-					   4729,//482
-					   4230,//60
-					   23170,//72
-					   3344,//96
-					   3153,//108
-					   2991,//120
-					   18918,//sqrt(3),//144
-					   18918,//sqrt(3),//180
-					   16384,//2, //192
-					   18918,//sqrt(3), // 216
-					   16384,//2, //240
-					   18918,//sqrt(3), // 288
-					   14654
-}; //sqrt(5) //300
-
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly2(__m128i *x0, __m128i *x1,__m128i *y0, __m128i *y1,__m128i *tw)__attribute__((always_inline));
-
-static inline void bfly2(__m128i *x0, __m128i *x1,__m128i *y0, __m128i *y1,__m128i *tw)
-{
-
-  __m128i x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-  __m128i bfly2_tmp1,bfly2_tmp2;
-
-  cmult(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmult(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = _mm_srai_epi32(_mm_add_epi32(x0r_2,x1r_2),15);
-  dy1r = _mm_srai_epi32(_mm_sub_epi32(x0r_2,x1r_2),15);
-  dy0i = _mm_srai_epi32(_mm_add_epi32(x0i_2,x1i_2),15);
-  //  printf("y0i %d\n",((int16_t *)y0i)[0]);
-  dy1i = _mm_srai_epi32(_mm_sub_epi32(x0i_2,x1i_2),15);
-
-  bfly2_tmp1 = _mm_unpacklo_epi32(dy0r,dy0i);
-  bfly2_tmp2 = _mm_unpackhi_epi32(dy0r,dy0i);
-  *y0 = _mm_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-
-  bfly2_tmp1 = _mm_unpacklo_epi32(dy1r,dy1i);
-  bfly2_tmp2 = _mm_unpackhi_epi32(dy1r,dy1i);
-  *y1 = _mm_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-}
-
-#ifdef __AVX2__
-
-static inline void bfly2_256(__m256i *x0, __m256i *x1,__m256i *y0, __m256i *y1,__m256i *tw)__attribute__((always_inline));
-
-static inline void bfly2_256(__m256i *x0, __m256i *x1,__m256i *y0, __m256i *y1,__m256i *tw)
-{
-
-  __m256i x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-  __m256i bfly2_tmp1,bfly2_tmp2;
-
-  cmult_256(*(x0),*(W0_256),&x0r_2,&x0i_2);
-  cmult_256(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = _mm256_srai_epi32(_mm256_add_epi32(x0r_2,x1r_2),15);
-  dy1r = _mm256_srai_epi32(_mm256_sub_epi32(x0r_2,x1r_2),15);
-  dy0i = _mm256_srai_epi32(_mm256_add_epi32(x0i_2,x1i_2),15);
-  //  printf("y0i %d\n",((int16_t *)y0i)[0]);
-  dy1i = _mm256_srai_epi32(_mm256_sub_epi32(x0i_2,x1i_2),15);
-
-  bfly2_tmp1 = _mm256_unpacklo_epi32(dy0r,dy0i);
-  bfly2_tmp2 = _mm256_unpackhi_epi32(dy0r,dy0i);
-  *y0 = _mm256_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-
-  bfly2_tmp1 = _mm256_unpacklo_epi32(dy1r,dy1i);
-  bfly2_tmp2 = _mm256_unpackhi_epi32(dy1r,dy1i);
-  *y1 = _mm256_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-}
-
-#endif
-
-#elif defined(__arm__)
-
-static inline void bfly2(int16x8_t *x0, int16x8_t *x1,int16x8_t *y0, int16x8_t *y1,int16x8_t *tw)__attribute__((always_inline));
-
-static inline void bfly2(int16x8_t *x0, int16x8_t *x1,int16x8_t *y0, int16x8_t *y1,int16x8_t *tw)
-{
-
-  int32x4_t x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-
-  cmult(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmult(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = vqaddq_s32(x0r_2,x1r_2);
-  dy1r = vqsubq_s32(x0r_2,x1r_2);
-  dy0i = vqaddq_s32(x0i_2,x1i_2);
-  dy1i = vqsubq_s32(x0i_2,x1i_2);
-
-  *y0 = cpack(dy0r,dy0i);
-  *y1 = cpack(dy1r,dy1i);
-}
-
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly2_tw1(__m128i *x0, __m128i *x1, __m128i *y0, __m128i *y1)__attribute__((always_inline));
-
-static inline void bfly2_tw1(__m128i *x0, __m128i *x1, __m128i *y0, __m128i *y1)
-{
-
-  *y0  = _mm_adds_epi16(*x0,*x1);
-  *y1  = _mm_subs_epi16(*x0,*x1);
-
-}
-
-#elif defined(__arm__)
-
-static inline void bfly2_tw1(int16x8_t *x0, int16x8_t *x1, int16x8_t *y0, int16x8_t *y1)__attribute__((always_inline));
-
-static inline void bfly2_tw1(int16x8_t *x0, int16x8_t *x1, int16x8_t *y0, int16x8_t *y1)
-{
-
-  *y0  = vqaddq_s16(*x0,*x1);
-  *y1  = vqsubq_s16(*x0,*x1);
-
-}
-#endif
- 
-#if defined(__x86_64__) || defined(__i386__)
-
-
-
-static inline void bfly2_16(__m128i *x0, __m128i *x1, __m128i *y0, __m128i *y1, __m128i *tw, __m128i *twb)__attribute__((always_inline));
-
-static inline void bfly2_16(__m128i *x0, __m128i *x1, __m128i *y0, __m128i *y1, __m128i *tw, __m128i *twb)
-{
-
-  //  register __m128i x1t;
-  __m128i x1t;
-
-  x1t = packed_cmult2(*(x1),*(tw),*(twb));
-  /*
-  print_shorts("x0",(int16_t*)x0);
-  print_shorts("x1",(int16_t*)x1);
-  print_shorts("tw",(int16_t*)tw);
-  print_shorts("twb",(int16_t*)twb);
-  print_shorts("x1t",(int16_t*)&x1t);*/
-  *y0  = _mm_adds_epi16(*x0,x1t);
-  *y1  = _mm_subs_epi16(*x0,x1t);
-  /*  print_shorts("y0",(int16_t*)y0);
-      print_shorts("y1",(int16_t*)y1);*/
-}
-
-#ifdef __AVX2__
-
-static inline void bfly2_16_256(__m256i *x0, __m256i *x1, __m256i *y0, __m256i *y1, __m256i *tw, __m256i *twb)__attribute__((always_inline));
-
-static inline void bfly2_16_256(__m256i *x0, __m256i *x1, __m256i *y0, __m256i *y1, __m256i *tw, __m256i *twb)
-{
-
-  //  register __m256i x1t;
-  __m256i x1t;
-
-  x1t = packed_cmult2_256(*(x1),*(tw),*(twb));
-  /*
-  print_shorts256("x0",(int16_t*)x0);
-  print_shorts256("x1",(int16_t*)x1);
-  print_shorts256("tw",(int16_t*)tw);
-  print_shorts256("twb",(int16_t*)twb);
-  print_shorts256("x1t",(int16_t*)&x1t);*/
-  *y0  = _mm256_adds_epi16(*x0,x1t);
-  *y1  = _mm256_subs_epi16(*x0,x1t);
-  
-  /*print_shorts256("y0",(int16_t*)y0);
-    print_shorts256("y1",(int16_t*)y1);*/
-}
-#endif
-
-
-#elif defined(__arm__)
-
-static inline void bfly2_16(int16x8_t *x0, int16x8_t *x1, int16x8_t *y0, int16x8_t *y1, int16x8_t *tw, int16x8_t *twb)__attribute__((always_inline));
-
-static inline void bfly2_16(int16x8_t *x0, int16x8_t *x1, int16x8_t *y0, int16x8_t *y1, int16x8_t *tw, int16x8_t *twb)
-{
-
-  *y0  = vqaddq_s16(*x0,*x1);
-  *y1  = vqsubq_s16(*x0,*x1);
-
-}
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void ibfly2(__m128i *x0, __m128i *x1,__m128i *y0, __m128i *y1,__m128i *tw)__attribute__((always_inline));
-
-static inline void ibfly2(__m128i *x0, __m128i *x1,__m128i *y0, __m128i *y1,__m128i *tw)
-{
-
-  __m128i x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-  __m128i bfly2_tmp1,bfly2_tmp2;
-
-  cmultc(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmultc(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = _mm_srai_epi32(_mm_add_epi32(x0r_2,x1r_2),15);
-  dy1r = _mm_srai_epi32(_mm_sub_epi32(x0r_2,x1r_2),15);
-  dy0i = _mm_srai_epi32(_mm_add_epi32(x0i_2,x1i_2),15);
-  //  printf("y0i %d\n",((int16_t *)y0i)[0]);
-  dy1i = _mm_srai_epi32(_mm_sub_epi32(x0i_2,x1i_2),15);
-
-  bfly2_tmp1 = _mm_unpacklo_epi32(dy0r,dy0i);
-  bfly2_tmp2 = _mm_unpackhi_epi32(dy0r,dy0i);
-  *y0 = _mm_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-
-  bfly2_tmp1 = _mm_unpacklo_epi32(dy1r,dy1i);
-  bfly2_tmp2 = _mm_unpackhi_epi32(dy1r,dy1i);
-  *y1 = _mm_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-}
-
-#ifdef __AVX2__
-static inline void ibfly2_256(__m256i *x0, __m256i *x1,__m256i *y0, __m256i *y1,__m256i *tw)__attribute__((always_inline));
-
-static inline void ibfly2_256(__m256i *x0, __m256i *x1,__m256i *y0, __m256i *y1,__m256i *tw)
-{
-
-  __m256i x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-  __m256i bfly2_tmp1,bfly2_tmp2;
-
-  cmultc_256(*(x0),*(W0_256),&x0r_2,&x0i_2);
-  cmultc_256(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = _mm256_srai_epi32(_mm256_add_epi32(x0r_2,x1r_2),15);
-  dy1r = _mm256_srai_epi32(_mm256_sub_epi32(x0r_2,x1r_2),15);
-  dy0i = _mm256_srai_epi32(_mm256_add_epi32(x0i_2,x1i_2),15);
-  //  printf("y0i %d\n",((int16_t *)y0i)[0]);
-  dy1i = _mm256_srai_epi32(_mm256_sub_epi32(x0i_2,x1i_2),15);
-
-  bfly2_tmp1 = _mm256_unpacklo_epi32(dy0r,dy0i);
-  bfly2_tmp2 = _mm256_unpackhi_epi32(dy0r,dy0i);
-  *y0 = _mm256_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-
-  bfly2_tmp1 = _mm256_unpacklo_epi32(dy1r,dy1i);
-  bfly2_tmp2 = _mm256_unpackhi_epi32(dy1r,dy1i);
-  *y1 = _mm256_packs_epi32(bfly2_tmp1,bfly2_tmp2);
-}
-#endif
-
-#elif defined(__arm__)
-static inline void ibfly2(int16x8_t *x0, int16x8_t *x1,int16x8_t *y0, int16x8_t *y1,int16x8_t *tw)
-{
-
-  int32x4_t x0r_2,x0i_2,x1r_2,x1i_2,dy0r,dy1r,dy0i,dy1i;
-
-  cmultc(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmultc(*(x1),*(tw),&x1r_2,&x1i_2);
-
-  dy0r = vqaddq_s32(x0r_2,x1r_2);
-  dy1r = vqsubq_s32(x0r_2,x1r_2);
-  dy0i = vqaddq_s32(x0i_2,x1i_2);
-  dy1i = vqsubq_s32(x0i_2,x1i_2);
-
-  *y0 = cpack(dy0r,dy0i);
-  *y1 = cpack(dy1r,dy1i);
-
-}
-
-#endif
-
-
-
-
-// This is the radix-3 butterfly (fft)
-
-#if defined(__x86_64__) || defined(__i386__)
-
-static inline void bfly3(__m128i *x0,__m128i *x1,__m128i *x2,
-                         __m128i *y0,__m128i *y1,__m128i *y2,
-                         __m128i *tw1,__m128i *tw2) __attribute__((always_inline));
-
-static inline void bfly3(__m128i *x0,__m128i *x1,__m128i *x2,
-                         __m128i *y0,__m128i *y1,__m128i *y2,
-                         __m128i *tw1,__m128i *tw2)
-{
-
-  __m128i tmpre,tmpim,x1_2,x2_2;
-
-  packed_cmult(*(x1),*(tw1),&x1_2);
-  packed_cmult(*(x2),*(tw2),&x2_2);
-  *(y0)  = _mm_adds_epi16(*(x0),_mm_adds_epi16(x1_2,x2_2));
-  cmult(x1_2,*(W13),&tmpre,&tmpim);
-  cmac(x2_2,*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = _mm_adds_epi16(*(x0),*(y1));
-  cmult(x1_2,*(W23),&tmpre,&tmpim);
-  cmac(x2_2,*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = _mm_adds_epi16(*(x0),*(y2));
-}
-
-#ifdef __AVX2__
-
-static inline void bfly3_256(__m256i *x0,__m256i *x1,__m256i *x2,
-			     __m256i *y0,__m256i *y1,__m256i *y2,
-			     __m256i *tw1,__m256i *tw2) __attribute__((always_inline));
-
-static inline void bfly3_256(__m256i *x0,__m256i *x1,__m256i *x2,
-			     __m256i *y0,__m256i *y1,__m256i *y2,
-			     __m256i *tw1,__m256i *tw2)
-{ 
-
-  __m256i tmpre,tmpim,x1_2,x2_2;
-
-  packed_cmult_256(*(x1),*(tw1),&x1_2);
-  packed_cmult_256(*(x2),*(tw2),&x2_2);
-  *(y0)  = _mm256_adds_epi16(*(x0),_mm256_adds_epi16(x1_2,x2_2));
-  cmult_256(x1_2,*(W13_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W23_256),&tmpre,&tmpim);
-  *(y1) = cpack_256(tmpre,tmpim);
-  *(y1) = _mm256_adds_epi16(*(x0),*(y1));
-  cmult_256(x1_2,*(W23_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W13_256),&tmpre,&tmpim);
-  *(y2) = cpack_256(tmpre,tmpim);
-  *(y2) = _mm256_adds_epi16(*(x0),*(y2));
-}
-#endif
-
-#elif defined(__arm__)
-static inline void bfly3(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-                         int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,
-                         int16x8_t *tw1,int16x8_t *tw2) __attribute__((always_inline));
-
-static inline void bfly3(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-                         int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,
-                         int16x8_t *tw1,int16x8_t *tw2)
-{
-
-  int32x4_t tmpre,tmpim;
-  int16x8_t x1_2,x2_2;
-
-  packed_cmult(*(x1),*(tw1),&x1_2);
-  packed_cmult(*(x2),*(tw2),&x2_2);
-  *(y0)  = vqaddq_s16(*(x0),vqaddq_s16(x1_2,x2_2));
-  cmult(x1_2,*(W13),&tmpre,&tmpim);
-  cmac(x2_2,*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = vqaddq_s16(*(x0),*(y1));
-  cmult(x1_2,*(W23),&tmpre,&tmpim);
-  cmac(x2_2,*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = vqaddq_s16(*(x0),*(y2));
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void ibfly3(__m128i *x0,__m128i *x1,__m128i *x2,
-			  __m128i *y0,__m128i *y1,__m128i *y2,
-			  __m128i *tw1,__m128i *tw2) __attribute__((always_inline));
-
-static inline void ibfly3(__m128i *x0,__m128i *x1,__m128i *x2,
-			  __m128i *y0,__m128i *y1,__m128i *y2,
-			  __m128i *tw1,__m128i *tw2)
-{
-
-  __m128i tmpre,tmpim,x1_2,x2_2;
-
-  packed_cmultc(*(x1),*(tw1),&x1_2);
-  packed_cmultc(*(x2),*(tw2),&x2_2);
-  *(y0)  = _mm_adds_epi16(*(x0),_mm_adds_epi16(x1_2,x2_2));
-  cmultc(x1_2,*(W13),&tmpre,&tmpim);
-  cmacc(x2_2,*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = _mm_adds_epi16(*(x0),*(y1));
-  cmultc(x1_2,*(W23),&tmpre,&tmpim);
-  cmacc(x2_2,*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = _mm_adds_epi16(*(x0),*(y2));
-}
-
-#ifdef __AVX2__
-
-static inline void ibfly3_256(__m256i *x0,__m256i *x1,__m256i *x2,
-			      __m256i *y0,__m256i *y1,__m256i *y2,
-			      __m256i *tw1,__m256i *tw2) __attribute__((always_inline));
-
-static inline void ibfly3_256(__m256i *x0,__m256i *x1,__m256i *x2,
-			      __m256i *y0,__m256i *y1,__m256i *y2,
-			      __m256i *tw1,__m256i *tw2)
-{ 
-
-  __m256i tmpre,tmpim,x1_2,x2_2;
-
-  packed_cmultc_256(*(x1),*(tw1),&x1_2);
-  packed_cmultc_256(*(x2),*(tw2),&x2_2);
-  *(y0)  = _mm256_adds_epi16(*(x0),_mm256_adds_epi16(x1_2,x2_2));
-  cmultc_256(x1_2,*(W13_256),&tmpre,&tmpim);
-  cmacc_256(x2_2,*(W23_256),&tmpre,&tmpim);
-  *(y1) = cpack_256(tmpre,tmpim);
-  *(y1) = _mm256_adds_epi16(*(x0),*(y1));
-  cmultc_256(x1_2,*(W23_256),&tmpre,&tmpim);
-  cmacc_256(x2_2,*(W13_256),&tmpre,&tmpim);
-  *(y2) = cpack_256(tmpre,tmpim);
-  *(y2) = _mm256_adds_epi16(*(x0),*(y2));
-}
-#endif
-
-#elif defined(__arm__)
-static inline void ibfly3(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-			  int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,
-			  int16x8_t *tw1,int16x8_t *tw2) __attribute__((always_inline));
-
-static inline void ibfly3(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-			  int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,
-			  int16x8_t *tw1,int16x8_t *tw2)
-{
-
-  int32x4_t tmpre,tmpim;
-  int16x8_t x1_2,x2_2;
-
-  packed_cmultc(*(x1),*(tw1),&x1_2);
-  packed_cmultc(*(x2),*(tw2),&x2_2);
-  *(y0)  = vqaddq_s16(*(x0),vqaddq_s16(x1_2,x2_2));
-  cmultc(x1_2,*(W13),&tmpre,&tmpim);
-  cmacc(x2_2,*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = vqaddq_s16(*(x0),*(y1));
-  cmultc(x1_2,*(W23),&tmpre,&tmpim);
-  cmacc(x2_2,*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = vqaddq_s16(*(x0),*(y2));
-}
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly3_tw1(__m128i *x0,__m128i *x1,__m128i *x2,
-                             __m128i *y0,__m128i *y1,__m128i *y2) __attribute__((always_inline));
-
-static inline void bfly3_tw1(__m128i *x0,__m128i *x1,__m128i *x2,
-                             __m128i *y0,__m128i *y1,__m128i *y2)
-{
-
-  __m128i tmpre,tmpim;
-
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(*(x1),*(x2)));
-  cmult(*(x1),*(W13),&tmpre,&tmpim);
-  cmac(*(x2),*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = _mm_adds_epi16(*(x0),*(y1));
-  cmult(*(x1),*(W23),&tmpre,&tmpim);
-  cmac(*(x2),*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = _mm_adds_epi16(*(x0),*(y2));
-}
-
-#ifdef __AVX2__
-
-static inline void bfly3_tw1_256(__m256i *x0,__m256i *x1,__m256i *x2,
-				 __m256i *y0,__m256i *y1,__m256i *y2) __attribute__((always_inline));
-
-static inline void bfly3_tw1_256(__m256i *x0,__m256i *x1,__m256i *x2,
-				 __m256i *y0,__m256i *y1,__m256i *y2)
-{
-
-  __m256i tmpre,tmpim;
-
-  *(y0) = _mm256_adds_epi16(*(x0),_mm256_adds_epi16(*(x1),*(x2)));
-  cmult_256(*(x1),*(W13_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W23_256),&tmpre,&tmpim);
-  *(y1) = cpack_256(tmpre,tmpim);
-  *(y1) = _mm256_adds_epi16(*(x0),*(y1));
-  cmult_256(*(x1),*(W23_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W13_256),&tmpre,&tmpim);
-  *(y2) = cpack_256(tmpre,tmpim);
-  *(y2) = _mm256_adds_epi16(*(x0),*(y2));
-}
-#endif
-
-#elif defined(__arm__)
-static inline void bfly3_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-                             int16x8_t *y0,int16x8_t *y1,int16x8_t *y2) __attribute__((always_inline));
-
-static inline void bfly3_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,
-                             int16x8_t *y0,int16x8_t *y1,int16x8_t *y2)
-{
-
-  int32x4_t tmpre,tmpim;
-
-  *(y0) = vqaddq_s16(*(x0),vqaddq_s16(*(x1),*(x2)));
-  cmult(*(x1),*(W13),&tmpre,&tmpim);
-  cmac(*(x2),*(W23),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = vqaddq_s16(*(x0),*(y1));
-  cmult(*(x1),*(W23),&tmpre,&tmpim);
-  cmac(*(x2),*(W13),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = vqaddq_s16(*(x0),*(y2));
-
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly4(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                         __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                         __m128i *tw1,__m128i *tw2,__m128i *tw3)__attribute__((always_inline));
-
-static inline void bfly4(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                         __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                         __m128i *tw1,__m128i *tw2,__m128i *tw3)
-{
-
-  __m128i x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-  //  cmult(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmult(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmult(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmult(*(x3),*(tw3),&x3r_2,&x3i_2);
-  //  dy0r = _mm_add_epi32(x0r_2,_mm_add_epi32(x1r_2,_mm_add_epi32(x2r_2,x3r_2)));
-  //  dy0i = _mm_add_epi32(x0i_2,_mm_add_epi32(x1i_2,_mm_add_epi32(x2i_2,x3i_2)));
-  //  *(y0)  = cpack(dy0r,dy0i);
-  dy0r = _mm_add_epi32(x1r_2,_mm_add_epi32(x2r_2,x3r_2));
-  dy0i = _mm_add_epi32(x1i_2,_mm_add_epi32(x2i_2,x3i_2));
-  *(y0)  = _mm_add_epi16(*(x0),cpack(dy0r,dy0i));
-  //  dy1r = _mm_add_epi32(x0r_2,_mm_sub_epi32(x1i_2,_mm_add_epi32(x2r_2,x3i_2)));
-  //  dy1i = _mm_sub_epi32(x0i_2,_mm_add_epi32(x1r_2,_mm_sub_epi32(x2i_2,x3r_2)));
-  //  *(y1)  = cpack(dy1r,dy1i);
-  dy1r = _mm_sub_epi32(x1i_2,_mm_add_epi32(x2r_2,x3i_2));
-  dy1i = _mm_sub_epi32(_mm_sub_epi32(x3r_2,x2i_2),x1r_2);
-  *(y1)  = _mm_add_epi16(*(x0),cpack(dy1r,dy1i));
-  //  dy2r = _mm_sub_epi32(x0r_2,_mm_sub_epi32(x1r_2,_mm_sub_epi32(x2r_2,x3r_2)));
-  //  dy2i = _mm_sub_epi32(x0i_2,_mm_sub_epi32(x1i_2,_mm_sub_epi32(x2i_2,x3i_2)));
-  //  *(y2)  = cpack(dy2r,dy2i);
-  dy2r = _mm_sub_epi32(_mm_sub_epi32(x2r_2,x3r_2),x1r_2);
-  dy2i = _mm_sub_epi32(_mm_sub_epi32(x2i_2,x3i_2),x1i_2);
-  *(y2)  = _mm_add_epi16(*(x0),cpack(dy2r,dy2i));
-  //  dy3r = _mm_sub_epi32(x0r_2,_mm_add_epi32(x1i_2,_mm_sub_epi32(x2r_2,x3i_2)));
-  //  dy3i = _mm_add_epi32(x0i_2,_mm_sub_epi32(x1r_2,_mm_add_epi32(x2i_2,x3r_2)));
-  //  *(y3) = cpack(dy3r,dy3i);
-  dy3r = _mm_sub_epi32(_mm_sub_epi32(x3i_2,x2r_2),x1i_2);
-  dy3i = _mm_sub_epi32(x1r_2,_mm_add_epi32(x2i_2,x3r_2));
-  *(y3) = _mm_add_epi16(*(x0),cpack(dy3r,dy3i));
-}
-
-#ifdef __AVX2__
-static inline void bfly4_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-			     __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-			     __m256i *tw1,__m256i *tw2,__m256i *tw3)__attribute__((always_inline));
-
-static inline void bfly4_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-			     __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-			     __m256i *tw1,__m256i *tw2,__m256i *tw3)
-{
-
-  __m256i x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-  //  cmult(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmult_256(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmult_256(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmult_256(*(x3),*(tw3),&x3r_2,&x3i_2);
-  //  dy0r = _mm_add_epi32(x0r_2,_mm_add_epi32(x1r_2,_mm_add_epi32(x2r_2,x3r_2)));
-  //  dy0i = _mm_add_epi32(x0i_2,_mm_add_epi32(x1i_2,_mm_add_epi32(x2i_2,x3i_2)));
-  //  *(y0)  = cpack(dy0r,dy0i);
-  dy0r = _mm256_add_epi32(x1r_2,_mm256_add_epi32(x2r_2,x3r_2));
-  dy0i = _mm256_add_epi32(x1i_2,_mm256_add_epi32(x2i_2,x3i_2));
-  *(y0)  = _mm256_add_epi16(*(x0),cpack_256(dy0r,dy0i));
-  //  dy1r = _mm_add_epi32(x0r_2,_mm_sub_epi32(x1i_2,_mm_add_epi32(x2r_2,x3i_2)));
-  //  dy1i = _mm_sub_epi32(x0i_2,_mm_add_epi32(x1r_2,_mm_sub_epi32(x2i_2,x3r_2)));
-  //  *(y1)  = cpack(dy1r,dy1i);
-  dy1r = _mm256_sub_epi32(x1i_2,_mm256_add_epi32(x2r_2,x3i_2));
-  dy1i = _mm256_sub_epi32(_mm256_sub_epi32(x3r_2,x2i_2),x1r_2);
-  *(y1)  = _mm256_add_epi16(*(x0),cpack_256(dy1r,dy1i));
-  //  dy2r = _mm_sub_epi32(x0r_2,_mm_sub_epi32(x1r_2,_mm_sub_epi32(x2r_2,x3r_2)));
-  //  dy2i = _mm_sub_epi32(x0i_2,_mm_sub_epi32(x1i_2,_mm_sub_epi32(x2i_2,x3i_2)));
-  //  *(y2)  = cpack(dy2r,dy2i);
-  dy2r = _mm256_sub_epi32(_mm256_sub_epi32(x2r_2,x3r_2),x1r_2);
-  dy2i = _mm256_sub_epi32(_mm256_sub_epi32(x2i_2,x3i_2),x1i_2);
-  *(y2)  = _mm256_add_epi16(*(x0),cpack_256(dy2r,dy2i));
-  //  dy3r = _mm_sub_epi32(x0r_2,_mm_add_epi32(x1i_2,_mm_sub_epi32(x2r_2,x3i_2)));
-  //  dy3i = _mm_add_epi32(x0i_2,_mm_sub_epi32(x1r_2,_mm_add_epi32(x2i_2,x3r_2)));
-  //  *(y3) = cpack(dy3r,dy3i);
-  dy3r = _mm256_sub_epi32(_mm256_sub_epi32(x3i_2,x2r_2),x1i_2);
-  dy3i = _mm256_sub_epi32(x1r_2,_mm256_add_epi32(x2i_2,x3r_2));
-  *(y3) = _mm256_add_epi16(*(x0),cpack_256(dy3r,dy3i));
-}
-#endif
-#elif defined(__arm__)
-static inline void bfly4(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                         int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                         int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3)__attribute__((always_inline));
-
-static inline void bfly4(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                         int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                         int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3)
-{
-
-  int32x4_t x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-  //  cmult(*(x0),*(W0),&x0r_2,&x0i_2);
-  cmult(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmult(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmult(*(x3),*(tw3),&x3r_2,&x3i_2);
-  //  dy0r = _mm_add_epi32(x0r_2,_mm_add_epi32(x1r_2,_mm_add_epi32(x2r_2,x3r_2)));
-  //  dy0i = _mm_add_epi32(x0i_2,_mm_add_epi32(x1i_2,_mm_add_epi32(x2i_2,x3i_2)));
-  //  *(y0)  = cpack(dy0r,dy0i);
-  dy0r = vqaddq_s32(x1r_2,vqaddq_s32(x2r_2,x3r_2));
-  dy0i = vqaddq_s32(x1i_2,vqaddq_s32(x2i_2,x3i_2));
-  *(y0)  = vqaddq_s16(*(x0),cpack(dy0r,dy0i));
-  //  dy1r = _mm_add_epi32(x0r_2,_mm_sub_epi32(x1i_2,_mm_add_epi32(x2r_2,x3i_2)));
-  //  dy1i = _mm_sub_epi32(x0i_2,_mm_add_epi32(x1r_2,_mm_sub_epi32(x2i_2,x3r_2)));
-  //  *(y1)  = cpack(dy1r,dy1i);
-  dy1r = vqsubq_s32(x1i_2,vqaddq_s32(x2r_2,x3i_2));
-  dy1i = vqsubq_s32(vqsubq_s32(x3r_2,x2i_2),x1r_2);
-  *(y1)  = vqaddq_s16(*(x0),cpack(dy1r,dy1i));
-  //  dy2r = _mm_sub_epi32(x0r_2,_mm_sub_epi32(x1r_2,_mm_sub_epi32(x2r_2,x3r_2)));
-  //  dy2i = _mm_sub_epi32(x0i_2,_mm_sub_epi32(x1i_2,_mm_sub_epi32(x2i_2,x3i_2)));
-  //  *(y2)  = cpack(dy2r,dy2i);
-  dy2r = vqsubq_s32(vqsubq_s32(x2r_2,x3r_2),x1r_2);
-  dy2i = vqsubq_s32(vqsubq_s32(x2i_2,x3i_2),x1i_2);
-  *(y2)  = vqaddq_s16(*(x0),cpack(dy2r,dy2i));
-  //  dy3r = _mm_sub_epi32(x0r_2,_mm_add_epi32(x1i_2,_mm_sub_epi32(x2r_2,x3i_2)));
-  //  dy3i = _mm_add_epi32(x0i_2,_mm_sub_epi32(x1r_2,_mm_add_epi32(x2i_2,x3r_2)));
-  //  *(y3) = cpack(dy3r,dy3i);
-  dy3r = vqsubq_s32(vqsubq_s32(x3i_2,x2r_2),x1i_2);
-  dy3i = vqsubq_s32(x1r_2,vqaddq_s32(x2i_2,x3r_2));
-  *(y3) = vqaddq_s16(*(x0),cpack(dy3r,dy3i));
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void ibfly4(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                          __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                          __m128i *tw1,__m128i *tw2,__m128i *tw3)__attribute__((always_inline));
-
-static inline void ibfly4(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                          __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                          __m128i *tw1,__m128i *tw2,__m128i *tw3)
-{
-
-  __m128i x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-
-  cmultc(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmultc(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmultc(*(x3),*(tw3),&x3r_2,&x3i_2);
-
-  dy0r = _mm_add_epi32(x1r_2,_mm_add_epi32(x2r_2,x3r_2));
-  dy0i = _mm_add_epi32(x1i_2,_mm_add_epi32(x2i_2,x3i_2));
-  *(y0)  = _mm_add_epi16(*(x0),cpack(dy0r,dy0i));
-  dy3r = _mm_sub_epi32(x1i_2,_mm_add_epi32(x2r_2,x3i_2));
-  dy3i = _mm_sub_epi32(_mm_sub_epi32(x3r_2,x2i_2),x1r_2);
-  *(y3)  = _mm_add_epi16(*(x0),cpack(dy3r,dy3i));
-  dy2r = _mm_sub_epi32(_mm_sub_epi32(x2r_2,x3r_2),x1r_2);
-  dy2i = _mm_sub_epi32(_mm_sub_epi32(x2i_2,x3i_2),x1i_2);
-  *(y2)  = _mm_add_epi16(*(x0),cpack(dy2r,dy2i));
-  dy1r = _mm_sub_epi32(_mm_sub_epi32(x3i_2,x2r_2),x1i_2);
-  dy1i = _mm_sub_epi32(x1r_2,_mm_add_epi32(x2i_2,x3r_2));
-  *(y1) = _mm_add_epi16(*(x0),cpack(dy1r,dy1i));
-}
-
-#ifdef __AVX2__
-
-static inline void ibfly4_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-			      __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-			      __m256i *tw1,__m256i *tw2,__m256i *tw3)__attribute__((always_inline));
-
-static inline void ibfly4_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-			      __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-			      __m256i *tw1,__m256i *tw2,__m256i *tw3)
-{
-
-  __m256i x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-
-  cmultc_256(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmultc_256(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmultc_256(*(x3),*(tw3),&x3r_2,&x3i_2);
-
-  dy0r = _mm256_add_epi32(x1r_2,_mm256_add_epi32(x2r_2,x3r_2));
-  dy0i = _mm256_add_epi32(x1i_2,_mm256_add_epi32(x2i_2,x3i_2));
-  *(y0)  = _mm256_add_epi16(*(x0),cpack_256(dy0r,dy0i));
-  dy3r = _mm256_sub_epi32(x1i_2,_mm256_add_epi32(x2r_2,x3i_2));
-  dy3i = _mm256_sub_epi32(_mm256_sub_epi32(x3r_2,x2i_2),x1r_2);
-  *(y3)  = _mm256_add_epi16(*(x0),cpack_256(dy3r,dy3i));
-  dy2r = _mm256_sub_epi32(_mm256_sub_epi32(x2r_2,x3r_2),x1r_2);
-  dy2i = _mm256_sub_epi32(_mm256_sub_epi32(x2i_2,x3i_2),x1i_2);
-  *(y2)  = _mm256_add_epi16(*(x0),cpack_256(dy2r,dy2i));
-  dy1r = _mm256_sub_epi32(_mm256_sub_epi32(x3i_2,x2r_2),x1i_2);
-  dy1i = _mm256_sub_epi32(x1r_2,_mm256_add_epi32(x2i_2,x3r_2));
-  *(y1) = _mm256_add_epi16(*(x0),cpack_256(dy1r,dy1i));
-}
-
-#endif
-#elif defined(__arm__)
-
-static inline void ibfly4(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                          int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                          int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3)__attribute__((always_inline));
-
-static inline void ibfly4(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                          int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                          int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3)
-{
-
-  int32x4_t x1r_2,x1i_2,x2r_2,x2i_2,x3r_2,x3i_2,dy0r,dy0i,dy1r,dy1i,dy2r,dy2i,dy3r,dy3i;
-
-
-  cmultc(*(x1),*(tw1),&x1r_2,&x1i_2);
-  cmultc(*(x2),*(tw2),&x2r_2,&x2i_2);
-  cmultc(*(x3),*(tw3),&x3r_2,&x3i_2);
-
-  dy0r  = vqaddq_s32(x1r_2,vqaddq_s32(x2r_2,x3r_2));
-  dy0i  = vqaddq_s32(x1i_2,vqaddq_s32(x2i_2,x3i_2));
-  *(y0) = vqaddq_s16(*(x0),cpack(dy0r,dy0i));
-  dy3r  = vqsubq_s32(x1i_2,vqaddq_s32(x2r_2,x3i_2));
-  dy3i  = vqsubq_s32(vqsubq_s32(x3r_2,x2i_2),x1r_2);
-  *(y3) = vqaddq_s16(*(x0),cpack(dy3r,dy3i));
-  dy2r  = vqsubq_s32(vqsubq_s32(x2r_2,x3r_2),x1r_2);
-  dy2i  = vqsubq_s32(vqsubq_s32(x2i_2,x3i_2),x1i_2);
-  *(y2) = vqaddq_s16(*(x0),cpack(dy2r,dy2i));
-  dy1r  = vqsubq_s32(vqsubq_s32(x3i_2,x2r_2),x1i_2);
-  dy1i  = vqsubq_s32(x1r_2,vqaddq_s32(x2i_2,x3r_2));
-  *(y1) = vqaddq_s16(*(x0),cpack(dy1r,dy1i));
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-
-static inline void bfly4_tw1(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                             __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3)__attribute__((always_inline));
-
-static inline void bfly4_tw1(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                             __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3)
-{
-  register __m128i x1_flip,x3_flip,x02t,x13t;
-  register __m128i complex_shuffle = _mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  x02t    = _mm_adds_epi16(*(x0),*(x2));
-  x13t    = _mm_adds_epi16(*(x1),*(x3));
-  *(y0)   = _mm_adds_epi16(x02t,x13t);
-  *(y2)   = _mm_subs_epi16(x02t,x13t);
-  x1_flip = _mm_sign_epi16(*(x1),*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm_sign_epi16(*(x3),*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm_subs_epi16(*(x0),*(x2));
-  x13t    = _mm_subs_epi16(x1_flip,x3_flip);
-  *(y1)   = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  /*
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(*(x1),_mm_adds_epi16(*(x2),*(x3))));
-  x1_flip = _mm_sign_epi16(*(x1),*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(*(x3),*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  *(y1)   = _mm_adds_epi16(*(x0),_mm_subs_epi16(x1_flip,_mm_adds_epi16(*(x2),x3_flip)));
-  *(y2)   = _mm_subs_epi16(*(x0),_mm_subs_epi16(*(x1),_mm_subs_epi16(*(x2),*(x3))));
-  *(y3)   = _mm_subs_epi16(*(x0),_mm_adds_epi16(x1_flip,_mm_subs_epi16(*(x2),x3_flip)));
-  */
-}
-
-#ifdef __AVX2__
-
-static inline void bfly4_tw1_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				 __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3)__attribute__((always_inline));
-
-static inline void bfly4_tw1_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				 __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3)
-{
-  register __m256i x1_flip,x3_flip,x02t,x13t;
-  register __m256i complex_shuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  x02t    = _mm256_adds_epi16(*(x0),*(x2));
-  x13t    = _mm256_adds_epi16(*(x1),*(x3));
-  *(y0)   = _mm256_adds_epi16(x02t,x13t);
-  *(y2)   = _mm256_subs_epi16(x02t,x13t);
-  x1_flip = _mm256_sign_epi16(*(x1),*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(*(x3),*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm256_subs_epi16(*(x0),*(x2));
-  x13t    = _mm256_subs_epi16(x1_flip,x3_flip);
-  *(y1)   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-}
-#endif
-
-#elif defined(__arm__)
-
-static inline void bfly4_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                             int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3)__attribute__((always_inline));
-
-static inline void bfly4_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                             int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3)
-{
-
-  register int16x8_t x1_flip,x3_flip;
-
-  *(y0) = vqaddq_s16(*(x0),vqaddq_s16(*(x1),vqaddq_s16(*(x2),*(x3))));
-  x1_flip = vrev32q_s16(vmulq_s16(*(x1),*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(*(x3),*(int16x8_t*)conjugatedft));
-  *(y1)   = vqaddq_s16(*(x0),vqsubq_s16(x1_flip,vqaddq_s16(*(x2),x3_flip)));
-  *(y2)   = vqsubq_s16(*(x0),vqsubq_s16(*(x1),vqsubq_s16(*(x2),*(x3))));
-  *(y3)   = vqsubq_s16(*(x0),vqaddq_s16(x1_flip,vqsubq_s16(*(x2),x3_flip)));
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-
-static inline void ibfly4_tw1(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                              __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3)__attribute__((always_inline));
-
-static inline void ibfly4_tw1(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                              __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3)
-{
-
-  register __m128i x1_flip,x3_flip;
-
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(*(x1),_mm_adds_epi16(*(x2),*(x3))));
-
-  x1_flip = _mm_sign_epi16(*(x1),*(__m128i*)conjugatedft);
-  //  x1_flip = _mm_shufflelo_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x1_flip = _mm_shufflehi_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(*(x3),*(__m128i*)conjugatedft);
-  //  x3_flip = _mm_shufflelo_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x3_flip = _mm_shufflehi_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  *(y1)   = _mm_subs_epi16(*(x0),_mm_adds_epi16(x1_flip,_mm_subs_epi16(*(x2),x3_flip)));
-  *(y2)   = _mm_subs_epi16(*(x0),_mm_subs_epi16(*(x1),_mm_subs_epi16(*(x2),*(x3))));
-  *(y3)   = _mm_adds_epi16(*(x0),_mm_subs_epi16(x1_flip,_mm_adds_epi16(*(x2),x3_flip)));
-}
-
-
-#elif defined(__arm__)
-static inline void ibfly4_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-			      int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3)__attribute__((always_inline));
-
-static inline void ibfly4_tw1(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-			      int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3)
-{
-
-  register int16x8_t x1_flip,x3_flip;
-
-  *(y0) = vqaddq_s16(*(x0),vqaddq_s16(*(x1),vqaddq_s16(*(x2),*(x3))));
-  x1_flip = vrev32q_s16(vmulq_s16(*(x1),*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(*(x3),*(int16x8_t*)conjugatedft));
-  *(y1)   = vqsubq_s16(*(x0),vqaddq_s16(x1_flip,vqsubq_s16(*(x2),x3_flip)));
-  *(y2)   = vqsubq_s16(*(x0),vqsubq_s16(*(x1),vqsubq_s16(*(x2),*(x3))));
-  *(y3)   = vqaddq_s16(*(x0),vqsubq_s16(x1_flip,vqaddq_s16(*(x2),x3_flip)));
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly4_16(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                            __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                            __m128i *tw1,__m128i *tw2,__m128i *tw3,
-                            __m128i *tw1b,__m128i *tw2b,__m128i *tw3b)__attribute__((always_inline));
-
-static inline void bfly4_16(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                            __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                            __m128i *tw1,__m128i *tw2,__m128i *tw3,
-                            __m128i *tw1b,__m128i *tw2b,__m128i *tw3b)
-{
-
-  register __m128i x1t,x2t,x3t,x02t,x13t;
-  register __m128i x1_flip,x3_flip;
-
-  x1t = packed_cmult2(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2(*(x3),*(tw3),*(tw3b));
-
-
-  //  bfly4_tw1(x0,&x1t,&x2t,&x3t,y0,y1,y2,y3);
-  x02t  = _mm_adds_epi16(*(x0),x2t);
-  x13t  = _mm_adds_epi16(x1t,x3t);
-  /*
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(x1t,_mm_adds_epi16(x2t,x3t)));
-  *(y2)   = _mm_subs_epi16(*(x0),_mm_subs_epi16(x1t,_mm_subs_epi16(x2t,x3t)));
-  */
-  *(y0)   = _mm_adds_epi16(x02t,x13t);
-  *(y2)   = _mm_subs_epi16(x02t,x13t);
-
-  x1_flip = _mm_sign_epi16(x1t,*(__m128i*)conjugatedft);
-  //  x1_flip = _mm_shufflelo_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x1_flip = _mm_shufflehi_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(x3t,*(__m128i*)conjugatedft);
-  //  x3_flip = _mm_shufflelo_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x3_flip = _mm_shufflehi_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x02t  = _mm_subs_epi16(*(x0),x2t);
-  x13t  = _mm_subs_epi16(x1_flip,x3_flip);
-  /*
-  *(y1)   = _mm_adds_epi16(*(x0),_mm_subs_epi16(x1_flip,_mm_adds_epi16(x2t,x3_flip)));  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm_subs_epi16(*(x0),_mm_adds_epi16(x1_flip,_mm_subs_epi16(x2t,x3_flip)));  // x0 - x1f - x2 + x3f
-  */
-  *(y1)   = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-}
-
-#ifdef __AVX2__
-static inline void bfly4_16_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				__m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-				__m256i *tw1,__m256i *tw2,__m256i *tw3,
-				__m256i *tw1b,__m256i *tw2b,__m256i *tw3b)__attribute__((always_inline));
-
-static inline void bfly4_16_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				__m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-				__m256i *tw1,__m256i *tw2,__m256i *tw3,
-				__m256i *tw1b,__m256i *tw2b,__m256i *tw3b)
-{
-
-  register __m256i x1t,x2t,x3t,x02t,x13t;
-  register __m256i x1_flip,x3_flip;
-  register __m256i complex_shuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  // each input xi is assumed to be to consecutive vectors xi0 xi1 on which to perform the 8 butterflies
-  // [xi00 xi01 xi02 xi03 xi10 xi20 xi30 xi40]
-  // each output yi is the same
-
-  x1t = packed_cmult2_256(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2_256(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2_256(*(x3),*(tw3),*(tw3b));
-
-  x02t  = _mm256_adds_epi16(*(x0),x2t);
-  x13t  = _mm256_adds_epi16(x1t,x3t);
-  *(y0)   = _mm256_adds_epi16(x02t,x13t);
-  *(y2)   = _mm256_subs_epi16(x02t,x13t);
-
-  x1_flip = _mm256_sign_epi16(x1t,*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(x3t,*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t  = _mm256_subs_epi16(*(x0),x2t);
-  x13t  = _mm256_subs_epi16(x1_flip,x3_flip);
-  *(y1)   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-}
-
-#endif
-
-#elif defined(__arm__)
-
-static inline void bfly4_16(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                            int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                            int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,
-                            int16x8_t *tw1b,int16x8_t *tw2b,int16x8_t *tw3b)__attribute__((always_inline));
-
-static inline void bfly4_16(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-                            int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-                            int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,
-                            int16x8_t *tw1b,int16x8_t *tw2b,int16x8_t *tw3b)
-{
-
-  register int16x8_t x1t,x2t,x3t,x02t,x13t;
-  register int16x8_t x1_flip,x3_flip;
-
-  x1t = packed_cmult2(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2(*(x3),*(tw3),*(tw3b));
-
-
-
-  x02t  = vqaddq_s16(*(x0),x2t);
-  x13t  = vqaddq_s16(x1t,x3t);
-  *(y0)   = vqaddq_s16(x02t,x13t);
-  *(y2)   = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(x1t,*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(x3t,*(int16x8_t*)conjugatedft));
-  x02t  = vqsubq_s16(*(x0),x2t);
-  x13t  = vqsubq_s16(x1_flip,x3_flip);
-  *(y1)   = vqaddq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y3)   = vqsubq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-}
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void ibfly4_16(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                             __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                             __m128i *tw1,__m128i *tw2,__m128i *tw3,
-                             __m128i *tw1b,__m128i *tw2b,__m128i *tw3b)__attribute__((always_inline));
-
-static inline void ibfly4_16(__m128i *x0,__m128i *x1,__m128i *x2,__m128i *x3,
-                             __m128i *y0,__m128i *y1,__m128i *y2,__m128i *y3,
-                             __m128i *tw1,__m128i *tw2,__m128i *tw3,
-                             __m128i *tw1b,__m128i *tw2b,__m128i *tw3b)
-{
-
-  register __m128i x1t,x2t,x3t,x02t,x13t;
-  register __m128i x1_flip,x3_flip;
-
-  x1t = packed_cmult2(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2(*(x3),*(tw3),*(tw3b));
-
-
-  //  bfly4_tw1(x0,&x1t,&x2t,&x3t,y0,y1,y2,y3);
-  x02t  = _mm_adds_epi16(*(x0),x2t);
-  x13t  = _mm_adds_epi16(x1t,x3t);
-  /*
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(x1t,_mm_adds_epi16(x2t,x3t)));
-  *(y2)   = _mm_subs_epi16(*(x0),_mm_subs_epi16(x1t,_mm_subs_epi16(x2t,x3t)));
-  */
-  *(y0)   = _mm_adds_epi16(x02t,x13t);
-  *(y2)   = _mm_subs_epi16(x02t,x13t);
-
-  x1_flip = _mm_sign_epi16(x1t,*(__m128i*)conjugatedft);
-  //  x1_flip = _mm_shufflelo_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x1_flip = _mm_shufflehi_epi16(x1_flip,_MM_SHUFFLE(2,3,0,1));
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(x3t,*(__m128i*)conjugatedft);
-  //  x3_flip = _mm_shufflelo_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  //  x3_flip = _mm_shufflehi_epi16(x3_flip,_MM_SHUFFLE(2,3,0,1));
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x02t  = _mm_subs_epi16(*(x0),x2t);
-  x13t  = _mm_subs_epi16(x1_flip,x3_flip);
-  /*
-  *(y1)   = _mm_adds_epi16(*(x0),_mm_subs_epi16(x1_flip,_mm_adds_epi16(x2t,x3_flip)));  // x0 + x1f - x2 - x3f
-  *(y3)   = _mm_subs_epi16(*(x0),_mm_adds_epi16(x1_flip,_mm_subs_epi16(x2t,x3_flip)));  // x0 - x1f - x2 + x3f
-  */
-  *(y3)   = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y1)   = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-}
-
-#ifdef __AVX2__
-static inline void ibfly4_16_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				 __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-				 __m256i *tw1,__m256i *tw2,__m256i *tw3,
-				 __m256i *tw1b,__m256i *tw2b,__m256i *tw3b)__attribute__((always_inline));
-
-static inline void ibfly4_16_256(__m256i *x0,__m256i *x1,__m256i *x2,__m256i *x3,
-				 __m256i *y0,__m256i *y1,__m256i *y2,__m256i *y3,
-				 __m256i *tw1,__m256i *tw2,__m256i *tw3,
-				 __m256i *tw1b,__m256i *tw2b,__m256i *tw3b)
-{
-
-  register __m256i x1t,x2t,x3t,x02t,x13t;
-  register __m256i x1_flip,x3_flip;
-  register __m256i complex_shuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  // each input xi is assumed to be to consecutive vectors xi0 xi1 on which to perform the 8 butterflies
-  // [xi00 xi01 xi02 xi03 xi10 xi20 xi30 xi40]
-  // each output yi is the same
-
-  x1t = packed_cmult2_256(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2_256(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2_256(*(x3),*(tw3),*(tw3b));
-
-  x02t  = _mm256_adds_epi16(*(x0),x2t);
-  x13t  = _mm256_adds_epi16(x1t,x3t);
-  *(y0)   = _mm256_adds_epi16(x02t,x13t);
-  *(y2)   = _mm256_subs_epi16(x02t,x13t);
-
-  x1_flip = _mm256_sign_epi16(x1t,*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(x3t,*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t  = _mm256_subs_epi16(*(x0),x2t);
-  x13t  = _mm256_subs_epi16(x1_flip,x3_flip);
-  *(y3)   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  *(y1)   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-}
-#endif
-
-#elif defined(__arm__)
-static inline void ibfly4_16(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-			     int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-			     int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,
-			     int16x8_t *tw1b,int16x8_t *tw2b,int16x8_t *tw3b)__attribute__((always_inline));
-
-static inline void ibfly4_16(int16x8_t *x0,int16x8_t *x1,int16x8_t *x2,int16x8_t *x3,
-			     int16x8_t *y0,int16x8_t *y1,int16x8_t *y2,int16x8_t *y3,
-			     int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,
-			     int16x8_t *tw1b,int16x8_t *tw2b,int16x8_t *tw3b)
-{
-
-  register int16x8_t x1t,x2t,x3t,x02t,x13t;
-  register int16x8_t x1_flip,x3_flip;
-
-  x1t = packed_cmult2(*(x1),*(tw1),*(tw1b));
-  x2t = packed_cmult2(*(x2),*(tw2),*(tw2b));
-  x3t = packed_cmult2(*(x3),*(tw3),*(tw3b));
-
-  x02t    = vqaddq_s16(*(x0),x2t);
-  x13t    = vqaddq_s16(x1t,x3t);
-  *(y0)   = vqaddq_s16(x02t,x13t);
-  *(y2)   = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(x1t,*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(x3t,*(int16x8_t*)conjugatedft));
-  x02t    = vqsubq_s16(*(x0),x2t);
-  x13t    = vqsubq_s16(x1_flip,x3_flip);
-  *(y3)   = vqaddq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-  *(y1)   = vqsubq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly5(__m128i *x0, __m128i *x1, __m128i *x2, __m128i *x3,__m128i *x4,
-                         __m128i *y0, __m128i *y1, __m128i *y2, __m128i *y3,__m128i *y4,
-                         __m128i *tw1,__m128i *tw2,__m128i *tw3,__m128i *tw4)__attribute__((always_inline));
-
-static inline void bfly5(__m128i *x0, __m128i *x1, __m128i *x2, __m128i *x3,__m128i *x4,
-                         __m128i *y0, __m128i *y1, __m128i *y2, __m128i *y3,__m128i *y4,
-                         __m128i *tw1,__m128i *tw2,__m128i *tw3,__m128i *tw4)
-{
-
-
-
-  __m128i x1_2,x2_2,x3_2,x4_2,tmpre,tmpim;
-
-  packed_cmult(*(x1),*(tw1),&x1_2);
-  packed_cmult(*(x2),*(tw2),&x2_2);
-  packed_cmult(*(x3),*(tw3),&x3_2);
-  packed_cmult(*(x4),*(tw4),&x4_2);
-
-  *(y0)  = _mm_adds_epi16(*(x0),_mm_adds_epi16(x1_2,_mm_adds_epi16(x2_2,_mm_adds_epi16(x3_2,x4_2))));
-  cmult(x1_2,*(W15),&tmpre,&tmpim);
-  cmac(x2_2,*(W25),&tmpre,&tmpim);
-  cmac(x3_2,*(W35),&tmpre,&tmpim);
-  cmac(x4_2,*(W45),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = _mm_adds_epi16(*(x0),*(y1));
-
-  cmult(x1_2,*(W25),&tmpre,&tmpim);
-  cmac(x2_2,*(W45),&tmpre,&tmpim);
-  cmac(x3_2,*(W15),&tmpre,&tmpim);
-  cmac(x4_2,*(W35),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = _mm_adds_epi16(*(x0),*(y2));
-
-  cmult(x1_2,*(W35),&tmpre,&tmpim);
-  cmac(x2_2,*(W15),&tmpre,&tmpim);
-  cmac(x3_2,*(W45),&tmpre,&tmpim);
-  cmac(x4_2,*(W25),&tmpre,&tmpim);
-  *(y3) = cpack(tmpre,tmpim);
-  *(y3) = _mm_adds_epi16(*(x0),*(y3));
-
-  cmult(x1_2,*(W45),&tmpre,&tmpim);
-  cmac(x2_2,*(W35),&tmpre,&tmpim);
-  cmac(x3_2,*(W25),&tmpre,&tmpim);
-  cmac(x4_2,*(W15),&tmpre,&tmpim);
-  *(y4) = cpack(tmpre,tmpim);
-  *(y4) = _mm_adds_epi16(*(x0),*(y4));
-
-
-}
-
-#ifdef __AVX2__
-
-static inline void bfly5_256(__m256i *x0, __m256i *x1, __m256i *x2, __m256i *x3,__m256i *x4,
-			     __m256i *y0, __m256i *y1, __m256i *y2, __m256i *y3,__m256i *y4,
-			     __m256i *tw1,__m256i *tw2,__m256i *tw3,__m256i *tw4)__attribute__((always_inline));
-
-static inline void bfly5_256(__m256i *x0, __m256i *x1, __m256i *x2, __m256i *x3,__m256i *x4,
-			     __m256i *y0, __m256i *y1, __m256i *y2, __m256i *y3,__m256i *y4,
-			     __m256i *tw1,__m256i *tw2,__m256i *tw3,__m256i *tw4)
-{
-
-
-
-  __m256i x1_2,x2_2,x3_2,x4_2,tmpre,tmpim;
-
-  packed_cmult_256(*(x1),*(tw1),&x1_2);
-  packed_cmult_256(*(x2),*(tw2),&x2_2);
-  packed_cmult_256(*(x3),*(tw3),&x3_2);
-  packed_cmult_256(*(x4),*(tw4),&x4_2);
-
-  *(y0)  = _mm256_adds_epi16(*(x0),_mm256_adds_epi16(x1_2,_mm256_adds_epi16(x2_2,_mm256_adds_epi16(x3_2,x4_2))));
-  cmult_256(x1_2,*(W15_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W25_256),&tmpre,&tmpim);
-  cmac_256(x3_2,*(W35_256),&tmpre,&tmpim);
-  cmac_256(x4_2,*(W45_256),&tmpre,&tmpim);
-  *(y1) = cpack_256(tmpre,tmpim);
-  *(y1) = _mm256_adds_epi16(*(x0),*(y1));
-
-  cmult_256(x1_2,*(W25_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W45_256),&tmpre,&tmpim);
-  cmac_256(x3_2,*(W15_256),&tmpre,&tmpim);
-  cmac_256(x4_2,*(W35_256),&tmpre,&tmpim);
-  *(y2) = cpack_256(tmpre,tmpim);
-  *(y2) = _mm256_adds_epi16(*(x0),*(y2));
-
-  cmult_256(x1_2,*(W35_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W15_256),&tmpre,&tmpim);
-  cmac_256(x3_2,*(W45_256),&tmpre,&tmpim);
-  cmac_256(x4_2,*(W25_256),&tmpre,&tmpim);
-  *(y3) = cpack_256(tmpre,tmpim);
-  *(y3) = _mm256_adds_epi16(*(x0),*(y3));
-
-  cmult_256(x1_2,*(W45_256),&tmpre,&tmpim);
-  cmac_256(x2_2,*(W35_256),&tmpre,&tmpim);
-  cmac_256(x3_2,*(W25_256),&tmpre,&tmpim);
-  cmac_256(x4_2,*(W15_256),&tmpre,&tmpim);
-  *(y4) = cpack_256(tmpre,tmpim);
-  *(y4) = _mm256_adds_epi16(*(x0),*(y4));
-
-
-}
-#endif
-
-#elif defined(__arm__)
-static inline void bfly5(int16x8_t *x0, int16x8_t *x1, int16x8_t *x2, int16x8_t *x3,int16x8_t *x4,
-                         int16x8_t *y0, int16x8_t *y1, int16x8_t *y2, int16x8_t *y3,int16x8_t *y4,
-                         int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,int16x8_t *tw4)__attribute__((always_inline));
-
-static inline void bfly5(int16x8_t *x0, int16x8_t *x1, int16x8_t *x2, int16x8_t *x3,int16x8_t *x4,
-                         int16x8_t *y0, int16x8_t *y1, int16x8_t *y2, int16x8_t *y3,int16x8_t *y4,
-                         int16x8_t *tw1,int16x8_t *tw2,int16x8_t *tw3,int16x8_t *tw4)
-{
-
-
-
-  int16x8_t x1_2,x2_2,x3_2,x4_2;
-  int32x4_t tmpre,tmpim;
-
-  packed_cmult(*(x1),*(tw1),&x1_2);
-  packed_cmult(*(x2),*(tw2),&x2_2);
-  packed_cmult(*(x3),*(tw3),&x3_2);
-  packed_cmult(*(x4),*(tw4),&x4_2);
-
-  *(y0)  = vqaddq_s16(*(x0),vqaddq_s16(x1_2,vqaddq_s16(x2_2,vqaddq_s16(x3_2,x4_2))));
-  cmult(x1_2,*(W15),&tmpre,&tmpim);
-  cmac(x2_2,*(W25),&tmpre,&tmpim);
-  cmac(x3_2,*(W35),&tmpre,&tmpim);
-  cmac(x4_2,*(W45),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = vqaddq_s16(*(x0),*(y1));
-
-  cmult(x1_2,*(W25),&tmpre,&tmpim);
-  cmac(x2_2,*(W45),&tmpre,&tmpim);
-  cmac(x3_2,*(W15),&tmpre,&tmpim);
-  cmac(x4_2,*(W35),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = vqaddq_s16(*(x0),*(y2));
-
-  cmult(x1_2,*(W35),&tmpre,&tmpim);
-  cmac(x2_2,*(W15),&tmpre,&tmpim);
-  cmac(x3_2,*(W45),&tmpre,&tmpim);
-  cmac(x4_2,*(W25),&tmpre,&tmpim);
-  *(y3) = cpack(tmpre,tmpim);
-  *(y3) = vqaddq_s16(*(x0),*(y3));
-
-  cmult(x1_2,*(W45),&tmpre,&tmpim);
-  cmac(x2_2,*(W35),&tmpre,&tmpim);
-  cmac(x3_2,*(W25),&tmpre,&tmpim);
-  cmac(x4_2,*(W15),&tmpre,&tmpim);
-  *(y4) = cpack(tmpre,tmpim);
-  *(y4) = vqaddq_s16(*(x0),*(y4));
-
-
-}
-
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void bfly5_tw1(__m128i *x0, __m128i *x1, __m128i *x2, __m128i *x3,__m128i *x4,
-                             __m128i *y0, __m128i *y1, __m128i *y2, __m128i *y3,__m128i *y4) __attribute__((always_inline));
-
-static inline void bfly5_tw1(__m128i *x0, __m128i *x1, __m128i *x2, __m128i *x3,__m128i *x4,
-                             __m128i *y0, __m128i *y1, __m128i *y2, __m128i *y3,__m128i *y4)
-{
-
-  __m128i tmpre,tmpim;
-
-  *(y0) = _mm_adds_epi16(*(x0),_mm_adds_epi16(*(x1),_mm_adds_epi16(*(x2),_mm_adds_epi16(*(x3),*(x4)))));
-  cmult(*(x1),*(W15),&tmpre,&tmpim);
-  cmac(*(x2),*(W25),&tmpre,&tmpim);
-  cmac(*(x3),*(W35),&tmpre,&tmpim);
-  cmac(*(x4),*(W45),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = _mm_adds_epi16(*(x0),*(y1));
-  cmult(*(x1),*(W25),&tmpre,&tmpim);
-  cmac(*(x2),*(W45),&tmpre,&tmpim);
-  cmac(*(x3),*(W15),&tmpre,&tmpim);
-  cmac(*(x4),*(W35),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = _mm_adds_epi16(*(x0),*(y2));
-  cmult(*(x1),*(W35),&tmpre,&tmpim);
-  cmac(*(x2),*(W15),&tmpre,&tmpim);
-  cmac(*(x3),*(W45),&tmpre,&tmpim);
-  cmac(*(x4),*(W25),&tmpre,&tmpim);
-  *(y3) = cpack(tmpre,tmpim);
-  *(y3) = _mm_adds_epi16(*(x0),*(y3));
-  cmult(*(x1),*(W45),&tmpre,&tmpim);
-  cmac(*(x2),*(W35),&tmpre,&tmpim);
-  cmac(*(x3),*(W25),&tmpre,&tmpim);
-  cmac(*(x4),*(W15),&tmpre,&tmpim);
-  *(y4) = cpack(tmpre,tmpim);
-  *(y4) = _mm_adds_epi16(*(x0),*(y4));
-}
-
-#ifdef __AVX2__
-static inline void bfly5_tw1_256(__m256i *x0, __m256i *x1, __m256i *x2, __m256i *x3,__m256i *x4,
-				 __m256i *y0, __m256i *y1, __m256i *y2, __m256i *y3,__m256i *y4) __attribute__((always_inline));
-
-static inline void bfly5_tw1_256(__m256i *x0, __m256i *x1, __m256i *x2, __m256i *x3,__m256i *x4,
-				 __m256i *y0, __m256i *y1, __m256i *y2, __m256i *y3,__m256i *y4)
-{
-
-  __m256i tmpre,tmpim;
-
-  *(y0) = _mm256_adds_epi16(*(x0),_mm256_adds_epi16(*(x1),_mm256_adds_epi16(*(x2),_mm256_adds_epi16(*(x3),*(x4)))));
-  cmult_256(*(x1),*(W15_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W25_256),&tmpre,&tmpim);
-  cmac_256(*(x3),*(W35_256),&tmpre,&tmpim);
-  cmac_256(*(x4),*(W45_256),&tmpre,&tmpim);
-  *(y1) = cpack_256(tmpre,tmpim);
-  *(y1) = _mm256_adds_epi16(*(x0),*(y1));
-  cmult_256(*(x1),*(W25_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W45_256),&tmpre,&tmpim);
-  cmac_256(*(x3),*(W15_256),&tmpre,&tmpim);
-  cmac_256(*(x4),*(W35_256),&tmpre,&tmpim);
-  *(y2) = cpack_256(tmpre,tmpim);
-  *(y2) = _mm256_adds_epi16(*(x0),*(y2));
-  cmult_256(*(x1),*(W35_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W15_256),&tmpre,&tmpim);
-  cmac_256(*(x3),*(W45_256),&tmpre,&tmpim);
-  cmac_256(*(x4),*(W25_256),&tmpre,&tmpim);
-  *(y3) = cpack_256(tmpre,tmpim);
-  *(y3) = _mm256_adds_epi16(*(x0),*(y3));
-  cmult_256(*(x1),*(W45_256),&tmpre,&tmpim);
-  cmac_256(*(x2),*(W35_256),&tmpre,&tmpim);
-  cmac_256(*(x3),*(W25_256),&tmpre,&tmpim);
-  cmac_256(*(x4),*(W15_256),&tmpre,&tmpim);
-  *(y4) = cpack_256(tmpre,tmpim);
-  *(y4) = _mm256_adds_epi16(*(x0),*(y4));
-}
-#endif
-#elif defined(__arm__)
-static inline void bfly5_tw1(int16x8_t *x0, int16x8_t *x1, int16x8_t *x2, int16x8_t *x3,int16x8_t *x4,
-                             int16x8_t *y0, int16x8_t *y1, int16x8_t *y2, int16x8_t *y3,int16x8_t *y4) __attribute__((always_inline));
-
-static inline void bfly5_tw1(int16x8_t *x0, int16x8_t *x1, int16x8_t *x2, int16x8_t *x3,int16x8_t *x4,
-                             int16x8_t *y0, int16x8_t *y1, int16x8_t *y2, int16x8_t *y3,int16x8_t *y4)
-{
-
-  int32x4_t tmpre,tmpim;
-
-  *(y0) = vqaddq_s16(*(x0),vqaddq_s16(*(x1),vqaddq_s16(*(x2),vqaddq_s16(*(x3),*(x4)))));
-  cmult(*(x1),*(W15),&tmpre,&tmpim);
-  cmac(*(x2),*(W25),&tmpre,&tmpim);
-  cmac(*(x3),*(W35),&tmpre,&tmpim);
-  cmac(*(x4),*(W45),&tmpre,&tmpim);
-  *(y1) = cpack(tmpre,tmpim);
-  *(y1) = vqaddq_s16(*(x0),*(y1));
-  cmult(*(x1),*(W25),&tmpre,&tmpim);
-  cmac(*(x2),*(W45),&tmpre,&tmpim);
-  cmac(*(x3),*(W15),&tmpre,&tmpim);
-  cmac(*(x4),*(W35),&tmpre,&tmpim);
-  *(y2) = cpack(tmpre,tmpim);
-  *(y2) = vqaddq_s16(*(x0),*(y2));
-  cmult(*(x1),*(W35),&tmpre,&tmpim);
-  cmac(*(x2),*(W15),&tmpre,&tmpim);
-  cmac(*(x3),*(W45),&tmpre,&tmpim);
-  cmac(*(x4),*(W25),&tmpre,&tmpim);
-  *(y3) = cpack(tmpre,tmpim);
-  *(y3) = vqaddq_s16(*(x0),*(y3));
-  cmult(*(x1),*(W45),&tmpre,&tmpim);
-  cmac(*(x2),*(W35),&tmpre,&tmpim);
-  cmac(*(x3),*(W25),&tmpre,&tmpim);
-  cmac(*(x4),*(W15),&tmpre,&tmpim);
-  *(y4) = cpack(tmpre,tmpim);
-  *(y4) = vqaddq_s16(*(x0),*(y4));
-}
-
-#endif
-// performs 4x4 transpose of input x (complex interleaved) using 128bit SIMD intrinsics
-// i.e. x = [x0r x0i x1r x1i ... x15r x15i], y = [x0r x0i x4r x4i x8r x8i x12r x12i x1r x1i x5r x5i x9r x9i x13r x13i x2r x2i ... x15r x15i]
-
-#if defined(__x86_64__) || defined(__i386__)
-static inline void transpose16(__m128i *x,__m128i *y) __attribute__((always_inline));
-static inline void transpose16(__m128i *x,__m128i *y)
-{
-  register __m128i ytmp0,ytmp1,ytmp2,ytmp3;
-
-  ytmp0 = _mm_unpacklo_epi32(x[0],x[1]);
-  ytmp1 = _mm_unpackhi_epi32(x[0],x[1]);
-  ytmp2 = _mm_unpacklo_epi32(x[2],x[3]);
-  ytmp3 = _mm_unpackhi_epi32(x[2],x[3]);
-  y[0]    = _mm_unpacklo_epi64(ytmp0,ytmp2);
-  y[1]    = _mm_unpackhi_epi64(ytmp0,ytmp2);
-  y[2]    = _mm_unpacklo_epi64(ytmp1,ytmp3);
-  y[3]    = _mm_unpackhi_epi64(ytmp1,ytmp3);
-}
-
-#elif defined(__arm__)
-static inline void transpose16(int16x8_t *x,int16x8_t *y) __attribute__((always_inline));
-static inline void transpose16(int16x8_t *x,int16x8_t *y)
-{
-  register uint32x4x2_t ytmp0,ytmp1;
-
-  ytmp0 = vtrnq_u32((uint32x4_t)(x[0]),(uint32x4_t)(x[1]));
-  ytmp1 = vtrnq_u32((uint32x4_t)(x[2]),(uint32x4_t)(x[3]));
-
-  y[0]  = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[0]),vget_low_s16((int16x8_t)ytmp1.val[0]));
-  y[1]  = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[0]),vget_high_s16((int16x8_t)ytmp1.val[0]));
-  y[2]  = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[1]),vget_low_s16((int16x8_t)ytmp1.val[1]));
-  y[3]  = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[1]),vget_high_s16((int16x8_t)ytmp1.val[1]));
-}
-
-# endif
-// same as above but output is offset by off
-#if defined(__x86_64__) || defined(__i386__)
-static inline void transpose16_ooff(__m128i *x,__m128i *y,int off) __attribute__((always_inline));
-
-static inline void transpose16_ooff(__m128i *x,__m128i *y,int off)
-{
-  register __m128i ytmp0,ytmp1,ytmp2,ytmp3;
-  __m128i *y2=y;
-
-  ytmp0 = _mm_unpacklo_epi32(x[0],x[1]); // x00 x10 x01 x11
-  ytmp1 = _mm_unpackhi_epi32(x[0],x[1]); // x02 x12 x03 x13
-  ytmp2 = _mm_unpacklo_epi32(x[2],x[3]); // x20 x30 x21 x31
-  ytmp3 = _mm_unpackhi_epi32(x[2],x[3]); // x22 x32 x23 x33
-  *y2     = _mm_unpacklo_epi64(ytmp0,ytmp2); // x00 x10 x20 x30 
-  y2+=off;
-  *y2     = _mm_unpackhi_epi64(ytmp0,ytmp2); // x01 x11 x21 x31
-  y2+=off;
-  *y2     = _mm_unpacklo_epi64(ytmp1,ytmp3); // x02 x12 x22 x32
-  y2+=off;
-  *y2     = _mm_unpackhi_epi64(ytmp1,ytmp3); // x03 x13 x23 x33
-}
-
-#ifdef __AVX2__
-
-static inline void transpose16_ooff_simd256(__m256i *x,__m256i *y,int off) __attribute__((always_inline));
-static inline void transpose16_ooff_simd256(__m256i *x,__m256i *y,int off)
-{
-  register __m256i ytmp0,ytmp1,ytmp2,ytmp3,ytmp4,ytmp5,ytmp6,ytmp7;
-  __m256i *y2=y;
-  __m256i const perm_mask = _mm256_set_epi32(7, 3, 5, 1, 6, 2, 4, 0);
-
-  ytmp0 = _mm256_permutevar8x32_epi32(x[0],perm_mask);  // x00 x10 x01 x11 x02 x12 x03 x13
-  ytmp1 = _mm256_permutevar8x32_epi32(x[1],perm_mask);  // x20 x30 x21 x31 x22 x32 x23 x33
-  ytmp2 = _mm256_permutevar8x32_epi32(x[2],perm_mask);  // x40 x50 x41 x51 x42 x52 x43 x53
-  ytmp3 = _mm256_permutevar8x32_epi32(x[3],perm_mask);  // x60 x70 x61 x71 x62 x72 x63 x73
-  ytmp4 = _mm256_unpacklo_epi64(ytmp0,ytmp1);           // x00 x10 x20 x30 x01 x11 x21 x31
-  ytmp5 = _mm256_unpackhi_epi64(ytmp0,ytmp1);           // x02 x12 x22 x32 x03 x13 x23 x33
-  ytmp6 = _mm256_unpacklo_epi64(ytmp2,ytmp3);           // x40 x50 x60 x70 x41 x51 x61 x71
-  ytmp7 = _mm256_unpackhi_epi64(ytmp2,ytmp3);           // x42 x52 x62 x72 x43 x53 x63 x73
-
-  *y2    = _mm256_insertf128_si256(ytmp4,_mm256_extracti128_si256(ytmp6,0),1);  //x00 x10 x20 x30 x40 x50 x60 x70
-  y2+=off;  
-  *y2    = _mm256_insertf128_si256(ytmp6,_mm256_extracti128_si256(ytmp4,1),0);  //x01 x11 x21 x31 x41 x51 x61 x71
-  y2+=off;  
-  *y2    = _mm256_insertf128_si256(ytmp5,_mm256_extracti128_si256(ytmp7,0),1);  //x00 x10 x20 x30 x40 x50 x60 x70
-  y2+=off;  
-  *y2    = _mm256_insertf128_si256(ytmp7,_mm256_extracti128_si256(ytmp5,1),0);  //x01 x11 x21 x31 x41 x51 x61 x71
-}
-#endif
-
-#elif defined(__arm__)
-static inline void transpose16_ooff(int16x8_t *x,int16x8_t *y,int off) __attribute__((always_inline));
-
-static inline void transpose16_ooff(int16x8_t *x,int16x8_t *y,int off)
-{
-  int16x8_t *y2=y;
-  register uint32x4x2_t ytmp0,ytmp1;
-
-  ytmp0 = vtrnq_u32((uint32x4_t)(x[0]),(uint32x4_t)(x[1]));
-  ytmp1 = vtrnq_u32((uint32x4_t)(x[2]),(uint32x4_t)(x[3]));
-
-  *y2   = (int16x8_t)vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[0]),vget_low_s16((int16x8_t)ytmp1.val[0])); y2+=off;
-  *y2   = (int16x8_t)vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[1]),vget_low_s16((int16x8_t)ytmp1.val[1])); y2+=off;
-  *y2   = (int16x8_t)vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[0]),vget_high_s16((int16x8_t)ytmp1.val[0])); y2+=off;
-  *y2   = (int16x8_t)vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[1]),vget_high_s16((int16x8_t)ytmp1.val[1]));
-
-
-}
-
-#endif
-
-#if defined(__x86_64__) || defined(__i386__)
-
-static inline void transpose4_ooff(__m64 *x,__m64 *y,int off)__attribute__((always_inline));
-static inline void transpose4_ooff(__m64 *x,__m64 *y,int off)
-{
-  y[0]   = _mm_unpacklo_pi32(x[0],x[1]);
-  y[off] = _mm_unpackhi_pi32(x[0],x[1]);
-
-  // x[0] = [x0 x1]
-  // x[1] = [x2 x3]
-  // y[0] = [x0 x2]
-  // y[off] = [x1 x3]
-}
-#ifdef __AVX2__
-static inline void transpose4_ooff_simd256(__m256i *x,__m256i *y,int off)__attribute__((always_inline));
-static inline void transpose4_ooff_simd256(__m256i *x,__m256i *y,int off)
-{
-  __m256i const perm_mask = _mm256_set_epi32(7, 5, 3, 1, 6, 4, 2, 0);
-  __m256i perm_tmp0,perm_tmp1;
-
-  // x[0] = [x0 x1 x2 x3 x4 x5 x6 x7]
-  // x[1] = [x8 x9 x10 x11 x12 x13 x14]
-  // y[0] = [x0 x2 x4 x6 x8 x10 x12 x14]
-  // y[off] = [x1 x3 x5 x7 x9 x11 x13 x15]
-  perm_tmp0 = _mm256_permutevar8x32_epi32(x[0],perm_mask);
-  perm_tmp1 = _mm256_permutevar8x32_epi32(x[1],perm_mask);
-  y[0]   = _mm256_insertf128_si256(perm_tmp0,_mm256_extracti128_si256(perm_tmp1,0),1);
-  y[off] = _mm256_insertf128_si256(perm_tmp1,_mm256_extracti128_si256(perm_tmp0,1),0);
-}
-#endif
-#elif (__arm__)
-
-static inline void transpose4_ooff(int16x4_t *x,int16x4_t *y,int off)__attribute__((always_inline));
-static inline void transpose4_ooff(int16x4_t *x,int16x4_t *y,int off)
-{
-  uint32x2x2_t ytmp = vtrn_u32((uint32x2_t)x[0],(uint32x2_t)x[1]);
-
-  y[0]   = (int16x4_t)ytmp.val[0];
-  y[off] = (int16x4_t)ytmp.val[1];
-}
-
-#endif
-
-// 16-point optimized DFT kernel
-
-const static int16_t tw16[24] __attribute__((aligned(32))) = { 32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,
-                                                  32767,0,23169,-23170,0     ,-32767,-23170,-23170,
-                                                  32767,0,12539,-30273,-23170,-23170,-30273,12539
-                                                };
-
-const static int16_t tw16a[24] __attribute__((aligned(32))) = {32767,0,30272,12540,23169 ,23170,12539 ,30273,
-                                                  32767,0,23169,23170,0     ,32767,-23170,23170,
-                                                  32767,0,12539,30273,-23170,23170,-30273,-12539
-                                                 };
-
-const static int16_t tw16b[24] __attribute__((aligned(32))) = { 0,32767,-12540,30272,-23170,23169 ,-30273,12539,
-                                                   0,32767,-23170,23169,-32767,0     ,-23170,-23170,
-                                                   0,32767,-30273,12539,-23170,-23170,12539 ,-30273
-                                                 };
-
-const static int16_t tw16c[24] __attribute__((aligned(32))) = { 0,32767,12540,30272,23170,23169 ,30273 ,12539,
-                                                   0,32767,23170,23169,32767,0     ,23170 ,-23170,
-                                                   0,32767,30273,12539,23170,-23170,-12539,-30273
-                                                 };
-
-#ifdef __AVX2__
-
-const static int16_t tw16rep[48] __attribute__((aligned(32))) = { 32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,
-						     32767,0,23169,-23170,0     ,-32767,-23170,-23170,32767,0,23169,-23170,0     ,-32767,-23170,-23170,
-						     32767,0,12539,-30273,-23170,-23170,-30273,12539,32767,0,12539,-30273,-23170,-23170,-30273,12539
-                                                   };
-
-const static int16_t tw16arep[48] __attribute__((aligned(32))) = {32767,0,30272,12540,23169 ,23170,12539 ,30273,32767,0,30272,12540,23169 ,23170,12539 ,30273,
-						     32767,0,23169,23170,0     ,32767,-23170,23170,32767,0,23169,23170,0     ,32767,-23170,23170,
-						     32767,0,12539,30273,-23170,23170,-30273,-12539,32767,0,12539,30273,-23170,23170,-30273,-12539
-                                                    }; 
-
-const static int16_t tw16brep[48] __attribute__((aligned(32))) = { 0,32767,-12540,30272,-23170,23169 ,-30273,12539,0,32767,-12540,30272,-23170,23169 ,-30273,12539,
-                                                      0,32767,-23170,23169,-32767,0     ,-23170,-23170,0,32767,-23170,23169,-32767,0     ,-23170,-23170,
-                                                      0,32767,-30273,12539,-23170,-23170,12539 ,-30273,0,32767,-30273,12539,-23170,-23170,12539 ,-30273
-                                                    };
-
-const static int16_t tw16crep[48] __attribute__((aligned(32))) = { 0,32767,12540,30272,23170,23169 ,30273 ,12539,0,32767,12540,30272,23170,23169 ,30273 ,12539,
-						      0,32767,23170,23169,32767,0     ,23170 ,-23170,0,32767,23170,23169,32767,0     ,23170 ,-23170,
-						      0,32767,30273,12539,23170,-23170,-12539,-30273,0,32767,30273,12539,23170,-23170,-12539,-30273
-                                                    };
-
-#endif /* __AVX2__ */
-
-
-
-static inline void dft16(int16_t *x,int16_t *y) __attribute__((always_inline));
-
-static inline void dft16(int16_t *x,int16_t *y)
-{
-
-#if defined(__x86_64__) || defined(__i386__)
-
-  __m128i *tw16a_128=(__m128i *)tw16a,*tw16b_128=(__m128i *)tw16b,*x128=(__m128i *)x,*y128=(__m128i *)y;
-
-
-
-  /*  This is the original version before unrolling
-
-  bfly4_tw1(x128,x128+1,x128+2,x128+3,
-      y128,y128+1,y128+2,y128+3);
-
-  transpose16(y128,ytmp);
-
-  bfly4_16(ytmp,ytmp+1,ytmp+2,ytmp+3,
-     y128,y128+1,y128+2,y128+3,
-     tw16_128,tw16_128+1,tw16_128+2);
-  */
-
-  register __m128i x1_flip,x3_flip,x02t,x13t;
-  register __m128i ytmp0,ytmp1,ytmp2,ytmp3,xtmp0,xtmp1,xtmp2,xtmp3;
-  register __m128i complex_shuffle = _mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-
-  x02t    = _mm_adds_epi16(x128[0],x128[2]);
-  x13t    = _mm_adds_epi16(x128[1],x128[3]);
-  xtmp0   = _mm_adds_epi16(x02t,x13t);
-  xtmp2   = _mm_subs_epi16(x02t,x13t);
-  x1_flip = _mm_sign_epi16(x128[1],*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm_sign_epi16(x128[3],*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm_subs_epi16(x128[0],x128[2]);
-  x13t    = _mm_subs_epi16(x1_flip,x3_flip);
-  xtmp1   = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp3   = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  ytmp0   = _mm_unpacklo_epi32(xtmp0,xtmp1);
-  ytmp1   = _mm_unpackhi_epi32(xtmp0,xtmp1);
-  ytmp2   = _mm_unpacklo_epi32(xtmp2,xtmp3);
-  ytmp3   = _mm_unpackhi_epi32(xtmp2,xtmp3);
-  xtmp0   = _mm_unpacklo_epi64(ytmp0,ytmp2);
-  xtmp1   = _mm_unpackhi_epi64(ytmp0,ytmp2);
-  xtmp2   = _mm_unpacklo_epi64(ytmp1,ytmp3);
-  xtmp3   = _mm_unpackhi_epi64(ytmp1,ytmp3);
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2(xtmp1,tw16a_128[0],tw16b_128[0]);
-  xtmp2 = packed_cmult2(xtmp2,tw16a_128[1],tw16b_128[1]);
-  xtmp3 = packed_cmult2(xtmp3,tw16a_128[2],tw16b_128[2]);
-
-  x02t    = _mm_adds_epi16(xtmp0,xtmp2);
-  x13t    = _mm_adds_epi16(xtmp1,xtmp3);
-  y128[0] = _mm_adds_epi16(x02t,x13t);
-  y128[2] = _mm_subs_epi16(x02t,x13t);
-  x1_flip = _mm_sign_epi16(xtmp1,*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(xtmp3,*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x02t    = _mm_subs_epi16(xtmp0,xtmp2);
-  x13t    = _mm_subs_epi16(x1_flip,x3_flip);
-  y128[1] = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  y128[3] = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-#elif defined(__arm__)
-
-  int16x8_t *tw16a_128=(int16x8_t *)tw16a,*tw16b_128=(int16x8_t *)tw16b,*x128=(int16x8_t *)x,*y128=(int16x8_t *)y;
-
-  /*  This is the original version before unrolling
-
-  bfly4_tw1(x128,x128+1,x128+2,x128+3,
-      y128,y128+1,y128+2,y128+3);
-
-  transpose16(y128,ytmp);
-
-  bfly4_16(ytmp,ytmp+1,ytmp+2,ytmp+3,
-     y128,y128+1,y128+2,y128+3,
-     tw16_128,tw16_128+1,tw16_128+2);
-  */
-
-  register int16x8_t x1_flip,x3_flip,x02t,x13t;
-  register int16x8_t xtmp0,xtmp1,xtmp2,xtmp3;
-  register uint32x4x2_t ytmp0,ytmp1;
-  register int16x8_t ytmp0b,ytmp1b,ytmp2b,ytmp3b;
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-  
-  x02t    = vqaddq_s16(x128[0],x128[2]);
-  x13t    = vqaddq_s16(x128[1],x128[3]);
-  xtmp0   = vqaddq_s16(x02t,x13t);
-  xtmp2   = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(x128[1],*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(x128[3],*(int16x8_t*)conjugatedft));
-  x02t    = vqsubq_s16(x128[0],x128[2]);
-  x13t    = vqsubq_s16(x1_flip,x3_flip);
-  xtmp1   = vqaddq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp3   = vqsubq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  ytmp0  = vtrnq_u32((uint32x4_t)(xtmp0),(uint32x4_t)(xtmp1));
-// y0[0] = [x00 x10 x02 x12], y0[1] = [x01 x11 x03 x13]
-  ytmp1  = vtrnq_u32((uint32x4_t)(xtmp2),(uint32x4_t)(xtmp3));
-// y1[0] = [x20 x30 x22 x32], y1[1] = [x21 x31 x23 x33]
-
-
-  ytmp0b = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[0]),vget_low_s16((int16x8_t)ytmp1.val[0]));
-// y0 = [x00 x10 x20 x30] 
-  ytmp1b = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[1]),vget_low_s16((int16x8_t)ytmp1.val[1]));
-// t1 = [x01 x11 x21 x31] 
-  ytmp2b = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[0]),vget_high_s16((int16x8_t)ytmp1.val[0]));
-// t2 = [x02 x12 x22 x32]
-  ytmp3b = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[1]),vget_high_s16((int16x8_t)ytmp1.val[1]));
-// t3 = [x03 x13 x23 x33]
-
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2(ytmp1b,tw16a_128[0],tw16b_128[0]);
-  xtmp2 = packed_cmult2(ytmp2b,tw16a_128[1],tw16b_128[1]);
-  xtmp3 = packed_cmult2(ytmp3b,tw16a_128[2],tw16b_128[2]);
-
-  x02t    = vqaddq_s16(ytmp0b,xtmp2);
-  x13t    = vqaddq_s16(xtmp1,xtmp3);
-  y128[0] = vqaddq_s16(x02t,x13t);
-  y128[2] = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(xtmp1,*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(xtmp3,*(int16x8_t*)conjugatedft));
-  x02t    = vqsubq_s16(ytmp0b,xtmp2);
-  x13t    = vqsubq_s16(x1_flip,x3_flip);
-  y128[1] = vqaddq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  y128[3] = vqsubq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-
-#endif
-}
-
-#if defined(__x86_64__) || defined(__i386__)
-#ifdef __AVX2__
-// Does two 16-point DFTS (x[0 .. 15] is 128 LSBs of input vector, x[16..31] is in 128 MSBs) 
-static inline void dft16_simd256(int16_t *x,int16_t *y) __attribute__((always_inline));
-static inline void dft16_simd256(int16_t *x,int16_t *y)
-{
-
-  __m256i *tw16a_256=(__m256i *)tw16arep,*tw16b_256=(__m256i *)tw16brep,*x256=(__m256i *)x,*y256=(__m256i *)y;
-
-  __m256i x1_flip,x3_flip,x02t,x13t;
-  __m256i ytmp0,ytmp1,ytmp2,ytmp3,xtmp0,xtmp1,xtmp2,xtmp3;
-  register __m256i complex_shuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-
-  x02t    = _mm256_adds_epi16(x256[0],x256[2]);
-  x13t    = _mm256_adds_epi16(x256[1],x256[3]);
-  xtmp0   = _mm256_adds_epi16(x02t,x13t);
-  xtmp2   = _mm256_subs_epi16(x02t,x13t);
-  x1_flip = _mm256_sign_epi16(x256[1],*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(x256[3],*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm256_subs_epi16(x256[0],x256[2]);
-  x13t    = _mm256_subs_epi16(x1_flip,x3_flip);
-  xtmp1   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp3   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  /*  print_shorts256("xtmp0",(int16_t*)&xtmp0);
-      print_shorts256("xtmp1",(int16_t*)&xtmp1);
-  print_shorts256("xtmp2",(int16_t*)&xtmp2);
-  print_shorts256("xtmp3",(int16_t*)&xtmp3);*/
-
-  ytmp0   = _mm256_unpacklo_epi32(xtmp0,xtmp1);  
-  ytmp1   = _mm256_unpackhi_epi32(xtmp0,xtmp1);
-  ytmp2   = _mm256_unpacklo_epi32(xtmp2,xtmp3);
-  ytmp3   = _mm256_unpackhi_epi32(xtmp2,xtmp3);
-  xtmp0   = _mm256_unpacklo_epi64(ytmp0,ytmp2);
-  xtmp1   = _mm256_unpackhi_epi64(ytmp0,ytmp2);
-  xtmp2   = _mm256_unpacklo_epi64(ytmp1,ytmp3);
-  xtmp3   = _mm256_unpackhi_epi64(ytmp1,ytmp3);
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2_256(xtmp1,tw16a_256[0],tw16b_256[0]);
-  xtmp2 = packed_cmult2_256(xtmp2,tw16a_256[1],tw16b_256[1]);
-  xtmp3 = packed_cmult2_256(xtmp3,tw16a_256[2],tw16b_256[2]);
-
-  /*  print_shorts256("xtmp0",(int16_t*)&xtmp0);
-  print_shorts256("xtmp1",(int16_t*)&xtmp1);
-  print_shorts256("xtmp2",(int16_t*)&xtmp2);
-  print_shorts256("xtmp3",(int16_t*)&xtmp3);*/
-
-  x02t    = _mm256_adds_epi16(xtmp0,xtmp2);
-  x13t    = _mm256_adds_epi16(xtmp1,xtmp3);
-  ytmp0   = _mm256_adds_epi16(x02t,x13t);
-  ytmp2   = _mm256_subs_epi16(x02t,x13t);
-  x1_flip = _mm256_sign_epi16(xtmp1,*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(xtmp3,*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm256_subs_epi16(xtmp0,xtmp2);
-  x13t    = _mm256_subs_epi16(x1_flip,x3_flip);
-  ytmp1   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  ytmp3   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
- 
-
-  // [y0  y1  y2  y3  y16 y17 y18 y19]
-  // [y4  y5  y6  y7  y20 y21 y22 y23]
-  // [y8  y9  y10 y11 y24 y25 y26 y27]
-  // [y12 y13 y14 y15 y28 y29 y30 y31]
-
-  y256[0] = _mm256_insertf128_si256(ytmp0,_mm256_extracti128_si256(ytmp1,0),1);
-  y256[1] = _mm256_insertf128_si256(ytmp2,_mm256_extracti128_si256(ytmp3,0),1);
-  y256[2] = _mm256_insertf128_si256(ytmp1,_mm256_extracti128_si256(ytmp0,1),0);
-  y256[3] = _mm256_insertf128_si256(ytmp3,_mm256_extracti128_si256(ytmp2,1),0);
-
-  // [y0  y1  y2  y3  y4  y5  y6  y7]
-  // [y8  y9  y10 y11 y12 y13 y14 y15]
-  // [y16 y17 y18 y19 y20 y21 y22 y23]
-  // [y24 y25 y26 y27 y28 y29 y30 y31]
-}
-
-#endif  
-#endif
-static inline void idft16(int16_t *x,int16_t *y) __attribute__((always_inline));
-
-static inline void idft16(int16_t *x,int16_t *y)
-{
-
-#if defined(__x86_64__) || defined(__i386__)
-  __m128i *tw16a_128=(__m128i *)tw16,*tw16b_128=(__m128i *)tw16c,*x128=(__m128i *)x,*y128=(__m128i *)y;
-
-  /*
-  bfly4_tw1(x128,x128+1,x128+2,x128+3,
-      y128,y128+1,y128+2,y128+3);
-
-  transpose16(y128,ytmp);
-
-  bfly4_16(ytmp,ytmp+1,ytmp+2,ytmp+3,
-     y128,y128+1,y128+2,y128+3,
-     tw16_128,tw16_128+1,tw16_128+2);
-  */
-
-  register __m128i x1_flip,x3_flip,x02t,x13t;
-  register __m128i ytmp0,ytmp1,ytmp2,ytmp3,xtmp0,xtmp1,xtmp2,xtmp3;
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-
-  x02t    = _mm_adds_epi16(x128[0],x128[2]);
-  x13t    = _mm_adds_epi16(x128[1],x128[3]);
-  xtmp0   = _mm_adds_epi16(x02t,x13t);
-  xtmp2   = _mm_subs_epi16(x02t,x13t);
-  x1_flip = _mm_sign_epi16(x128[1],*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(x128[3],*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x02t    = _mm_subs_epi16(x128[0],x128[2]);
-  x13t    = _mm_subs_epi16(x1_flip,x3_flip);
-  xtmp3   = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp1   = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  ytmp0   = _mm_unpacklo_epi32(xtmp0,xtmp1);
-  ytmp1   = _mm_unpackhi_epi32(xtmp0,xtmp1);
-  ytmp2   = _mm_unpacklo_epi32(xtmp2,xtmp3);
-  ytmp3   = _mm_unpackhi_epi32(xtmp2,xtmp3);
-  xtmp0   = _mm_unpacklo_epi64(ytmp0,ytmp2);
-  xtmp1   = _mm_unpackhi_epi64(ytmp0,ytmp2);
-  xtmp2   = _mm_unpacklo_epi64(ytmp1,ytmp3);
-  xtmp3   = _mm_unpackhi_epi64(ytmp1,ytmp3);
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2(xtmp1,tw16a_128[0],tw16b_128[0]);
-  xtmp2 = packed_cmult2(xtmp2,tw16a_128[1],tw16b_128[1]);
-  xtmp3 = packed_cmult2(xtmp3,tw16a_128[2],tw16b_128[2]);
-
-  x02t    = _mm_adds_epi16(xtmp0,xtmp2);
-  x13t    = _mm_adds_epi16(xtmp1,xtmp3);
-  y128[0] = _mm_adds_epi16(x02t,x13t);
-  y128[2] = _mm_subs_epi16(x02t,x13t);
-  x1_flip = _mm_sign_epi16(xtmp1,*(__m128i*)conjugatedft);
-  x1_flip = _mm_shuffle_epi8(x1_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x3_flip = _mm_sign_epi16(xtmp3,*(__m128i*)conjugatedft);
-  x3_flip = _mm_shuffle_epi8(x3_flip,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2));
-  x02t    = _mm_subs_epi16(xtmp0,xtmp2);
-  x13t    = _mm_subs_epi16(x1_flip,x3_flip);
-  y128[3] = _mm_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  y128[1] = _mm_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-#elif defined(__arm__)
-  int16x8_t *tw16a_128=(int16x8_t *)tw16,*tw16b_128=(int16x8_t *)tw16c,*x128=(int16x8_t *)x,*y128=(int16x8_t *)y;
-
-  /*  This is the original version before unrolling
-
-  bfly4_tw1(x128,x128+1,x128+2,x128+3,
-      y128,y128+1,y128+2,y128+3);
-
-  transpose16(y128,ytmp);
-
-  bfly4_16(ytmp,ytmp+1,ytmp+2,ytmp+3,
-     y128,y128+1,y128+2,y128+3,
-     tw16_128,tw16_128+1,tw16_128+2);
-  */
-
-  register int16x8_t x1_flip,x3_flip,x02t,x13t;
-  register int16x8_t xtmp0,xtmp1,xtmp2,xtmp3;
-  register uint32x4x2_t ytmp0,ytmp1;
-  register int16x8_t ytmp0b,ytmp1b,ytmp2b,ytmp3b;
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-
-  x02t    = vqaddq_s16(x128[0],x128[2]);
-  x13t    = vqaddq_s16(x128[1],x128[3]);
-  xtmp0   = vqaddq_s16(x02t,x13t);
-  xtmp2   = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(x128[1],*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(x128[3],*(int16x8_t*)conjugatedft));
-  x02t    = vqsubq_s16(x128[0],x128[2]);
-  x13t    = vqsubq_s16(x1_flip,x3_flip);
-  xtmp3   = vqaddq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp1   = vqsubq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  ytmp0  = vtrnq_u32((uint32x4_t)(xtmp0),(uint32x4_t)(xtmp1));
-// y0[0] = [x00 x10 x02 x12], y0[1] = [x01 x11 x03 x13]
-  ytmp1  = vtrnq_u32((uint32x4_t)(xtmp2),(uint32x4_t)(xtmp3));
-// y1[0] = [x20 x30 x22 x32], y1[1] = [x21 x31 x23 x33]
-
-
-  ytmp0b = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[0]),vget_low_s16((int16x8_t)ytmp1.val[0]));
-// y0 = [x00 x10 x20 x30] 
-  ytmp1b = vcombine_s16(vget_low_s16((int16x8_t)ytmp0.val[1]),vget_low_s16((int16x8_t)ytmp1.val[1]));
-// t1 = [x01 x11 x21 x31] 
-  ytmp2b = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[0]),vget_high_s16((int16x8_t)ytmp1.val[0]));
-// t2 = [x02 x12 x22 x32]
-  ytmp3b = vcombine_s16(vget_high_s16((int16x8_t)ytmp0.val[1]),vget_high_s16((int16x8_t)ytmp1.val[1]));
-// t3 = [x03 x13 x23 x33]
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2(ytmp1b,tw16a_128[0],tw16b_128[0]);
-  xtmp2 = packed_cmult2(ytmp2b,tw16a_128[1],tw16b_128[1]);
-  xtmp3 = packed_cmult2(ytmp3b,tw16a_128[2],tw16b_128[2]);
-
-  x02t    = vqaddq_s16(ytmp0b,xtmp2);
-  x13t    = vqaddq_s16(xtmp1,xtmp3);
-  y128[0] = vqaddq_s16(x02t,x13t);
-  y128[2] = vqsubq_s16(x02t,x13t);
-  x1_flip = vrev32q_s16(vmulq_s16(xtmp1,*(int16x8_t*)conjugatedft));
-  x3_flip = vrev32q_s16(vmulq_s16(xtmp3,*(int16x8_t*)conjugatedft));
-  x02t    = vqsubq_s16(ytmp0b,xtmp2);
-  x13t    = vqsubq_s16(x1_flip,x3_flip);
-  y128[3] = vqaddq_s16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  y128[1] = vqsubq_s16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-#endif
-}
-
-#if defined(__x86_64__) || defined(__i386__)
-#ifdef __AVX2__
-// Does two 16-point IDFTS (x[0 .. 15] is 128 LSBs of input vector, x[16..31] is in 128 MSBs) 
-static inline void idft16_simd256(int16_t *x,int16_t *y) __attribute__((always_inline));
-static inline void idft16_simd256(int16_t *x,int16_t *y)
-{
-
-  __m256i *tw16a_256=(__m256i *)tw16rep,*tw16b_256=(__m256i *)tw16crep,*x256=(__m256i *)x,*y256=(__m256i *)y;
-  register __m256i x1_flip,x3_flip,x02t,x13t;
-  register __m256i ytmp0,ytmp1,ytmp2,ytmp3,xtmp0,xtmp1,xtmp2,xtmp3;
-  register __m256i complex_shuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
-
-  // First stage : 4 Radix-4 butterflies without input twiddles
-
-  x02t    = _mm256_adds_epi16(x256[0],x256[2]);
-  x13t    = _mm256_adds_epi16(x256[1],x256[3]);
-  xtmp0   = _mm256_adds_epi16(x02t,x13t);
-  xtmp2   = _mm256_subs_epi16(x02t,x13t);
-  x1_flip = _mm256_sign_epi16(x256[1],*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(x256[3],*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm256_subs_epi16(x256[0],x256[2]);
-  x13t    = _mm256_subs_epi16(x1_flip,x3_flip);
-  xtmp3   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  xtmp1   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  ytmp0   = _mm256_unpacklo_epi32(xtmp0,xtmp1);  
-  ytmp1   = _mm256_unpackhi_epi32(xtmp0,xtmp1);
-  ytmp2   = _mm256_unpacklo_epi32(xtmp2,xtmp3);
-  ytmp3   = _mm256_unpackhi_epi32(xtmp2,xtmp3);
-  xtmp0   = _mm256_unpacklo_epi64(ytmp0,ytmp2);
-  xtmp1   = _mm256_unpackhi_epi64(ytmp0,ytmp2);
-  xtmp2   = _mm256_unpacklo_epi64(ytmp1,ytmp3);
-  xtmp3   = _mm256_unpackhi_epi64(ytmp1,ytmp3);
-
-  // Second stage : 4 Radix-4 butterflies with input twiddles
-  xtmp1 = packed_cmult2_256(xtmp1,tw16a_256[0],tw16b_256[0]);
-  xtmp2 = packed_cmult2_256(xtmp2,tw16a_256[1],tw16b_256[1]);
-  xtmp3 = packed_cmult2_256(xtmp3,tw16a_256[2],tw16b_256[2]);
-
-  x02t    = _mm256_adds_epi16(xtmp0,xtmp2);
-  x13t    = _mm256_adds_epi16(xtmp1,xtmp3);
-  ytmp0   = _mm256_adds_epi16(x02t,x13t);
-  ytmp2   = _mm256_subs_epi16(x02t,x13t);
-  x1_flip = _mm256_sign_epi16(xtmp1,*(__m256i*)conjugatedft);
-  x1_flip = _mm256_shuffle_epi8(x1_flip,complex_shuffle);
-  x3_flip = _mm256_sign_epi16(xtmp3,*(__m256i*)conjugatedft);
-  x3_flip = _mm256_shuffle_epi8(x3_flip,complex_shuffle);
-  x02t    = _mm256_subs_epi16(xtmp0,xtmp2);
-  x13t    = _mm256_subs_epi16(x1_flip,x3_flip);
-  ytmp3   = _mm256_adds_epi16(x02t,x13t);  // x0 + x1f - x2 - x3f
-  ytmp1   = _mm256_subs_epi16(x02t,x13t);  // x0 - x1f - x2 + x3f
-
-  // [y0  y1  y2  y3  y16 y17 y18 y19]
-  // [y4  y5  y6  y7  y20 y21 y22 y23]
-  // [y8  y9  y10 y11 y24 y25 y26 y27]
-  // [y12 y13 y14 y15 y28 y29 y30 y31]
-
-  y256[0] = _mm256_insertf128_si256(ytmp0,_mm256_extracti128_si256(ytmp1,0),1);
-  y256[1] = _mm256_insertf128_si256(ytmp2,_mm256_extracti128_si256(ytmp3,0),1);
-  y256[2] = _mm256_insertf128_si256(ytmp1,_mm256_extracti128_si256(ytmp0,1),0);
-  y256[3] = _mm256_insertf128_si256(ytmp3,_mm256_extracti128_si256(ytmp2,1),0);
-
-}
-#endif  
-#endif
-
-// 64-point optimized DFT
-
-const static int16_t tw64[96] __attribute__((aligned(32))) = { 
-32767,0,32609,-3212,32137,-6393,31356,-9512,
-30272,-12540,28897,-15447,27244,-18205,25329,-20788,
-23169,-23170,20787,-25330,18204,-27245,15446,-28898,
-12539,-30273,9511,-31357,6392,-32138,3211,-32610,
-32767,0,32137,-6393,30272,-12540,27244,-18205,
-23169,-23170,18204,-27245,12539,-30273,6392,-32138,
-0,-32767,-6393,-32138,-12540,-30273,-18205,-27245,
--23170,-23170,-27245,-18205,-30273,-12540,-32138,-6393,
-32767,0,31356,-9512,27244,-18205,20787,-25330,
-12539,-30273,3211,-32610,-6393,-32138,-15447,-28898,
--23170,-23170,-28898,-15447,-32138,-6393,-32610,3211,
--30273,12539,-25330,20787,-18205,27244,-9512,31356
-                                                };
-const static int16_t tw64a[96] __attribute__((aligned(32))) = { 
-32767,0,32609,3212,32137,6393,31356,9512,
-30272,12540,28897,15447,27244,18205,25329,20788,
-23169,23170,20787,25330,18204,27245,15446,28898,
-12539,30273,9511,31357,6392,32138,3211,32610,
-32767,0,32137,6393,30272,12540,27244,18205,
-23169,23170,18204,27245,12539,30273,6392,32138,
-0,32767,-6393,32138,-12540,30273,-18205,27245,
--23170,23170,-27245,18205,-30273,12540,-32138,6393,
-32767,0,31356,9512,27244,18205,20787,25330,
-12539,30273,3211,32610,-6393,32138,-15447,28898,
--23170,23170,-28898,15447,-32138,6393,-32610,-3211,
--30273,-12539,-25330,-20787,-18205,-27244,-9512,-31356
-                                                 };
-const static int16_t tw64b[96] __attribute__((aligned(32))) = { 
-0,32767,-3212,32609,-6393,32137,-9512,31356,
--12540,30272,-15447,28897,-18205,27244,-20788,25329,
--23170,23169,-25330,20787,-27245,18204,-28898,15446,
--30273,12539,-31357,9511,-32138,6392,-32610,3211,
-0,32767,-6393,32137,-12540,30272,-18205,27244,
--23170,23169,-27245,18204,-30273,12539,-32138,6392,
--32767,0,-32138,-6393,-30273,-12540,-27245,-18205,
--23170,-23170,-18205,-27245,-12540,-30273,-6393,-32138,
-0,32767,-9512,31356,-18205,27244,-25330,20787,
--30273,12539,-32610,3211,-32138,-6393,-28898,-15447,
--23170,-23170,-15447,-28898,-6393,-32138,3211,-32610,
-12539,-30273,20787,-25330,27244,-18205,31356,-9512
-                                                 };
-const static int16_t tw64c[96] __attribute__((aligned(32))) = { 
-0,32767,3212,32609,6393,32137,9512,31356,
-12540,30272,15447,28897,18205,27244,20788,25329,
-23170,23169,25330,20787,27245,18204,28898,15446,
-30273,12539,31357,9511,32138,6392,32610,3211,
-0,32767,6393,32137,12540,30272,18205,27244,
-23170,23169,27245,18204,30273,12539,32138,6392,
-32767,0,32138,-6393,30273,-12540,27245,-18205,
-23170,-23170,18205,-27245,12540,-30273,6393,-32138,
-0,32767,9512,31356,18205,27244,25330,20787,
-30273,12539,32610,3211,32138,-6393,28898,-15447,
-23170,-23170,15447,-28898,6393,-32138,-3211,-32610,
--12539,-30273,-20787,-25330,-27244,-18205,-31356,-9512
-                                                 };
-#if defined(__x86_64__) || defined(__i386__)
-#define simd_q15_t __m128i
-#define simdshort_q15_t __m64
-#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
-#define set1_int16(a) _mm_set1_epi16(a);
-#define mulhi_int16(a,b) _mm_mulhrs_epi16 (a,b)
-#ifdef __AVX2__
-#define simd256_q15_t __m256i
-#define shiftright_int16_simd256(a,shift) _mm256_srai_epi16(a,shift)
-#define set1_int16_simd256(a) _mm256_set1_epi16(a);
-#define mulhi_int16_simd256(a,b) _mm256_mulhrs_epi16(a,b); //_mm256_slli_epi16(_mm256_mulhi_epi16(a,b),1);
-#endif
-
-#elif defined(__arm__)
-#define simd_q15_t int16x8_t
-#define simdshort_q15_t int16x4_t
-#define shiftright_int16(a,shift) vshrq_n_s16(a,shift)
-#define set1_int16(a) vdupq_n_s16(a)
-#define mulhi_int16(a,b) vqdmulhq_s16(a,b);
-#define _mm_empty() 
-#define _m_empty()
-
-#endif
-
-#ifndef __AVX2__
-void dft64(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[16],ytmp[16],*tw64a_128=(simd_q15_t *)tw64a,*tw64b_128=(simd_q15_t *)tw64b,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y;
-
-
-#ifdef D64STATS
-  time_stats_t ts_t,ts_d,ts_b;
-
-  reset_meas(&ts_t);
-  reset_meas(&ts_d);
-  reset_meas(&ts_b);
-  start_meas(&ts_t);
-#endif
-
-
-  transpose16_ooff(x128,xtmp,4);
-  // xtmp0  = x00 x10 x20 x30
-  // xtmp4  = x01 x11 x21 x31
-  // xtmp8  = x02 x12 x22 x32
-  // xtmp12 = x03 x13 x23 x33
-  transpose16_ooff(x128+4,xtmp+1,4);
-  // xtmp1  = x40 x50 x60 x70
-  // xtmp5  = x41 x51 x61 x71
-  // xtmp9  = x42 x52 x62 x72
-  // xtmp13 = x43 x53 x63 x73
-  transpose16_ooff(x128+8,xtmp+2,4);
-  // xtmp2  = x80 x90 xa0 xb0
-  // xtmp6  = x41 x51 x61 x71
-  // xtmp10 = x82 x92 xa2 xb2
-  // xtmp14 = x83 x93 xa3 xb3
-  transpose16_ooff(x128+12,xtmp+3,4);
-  // xtmp3  = xc0 xd0 xe0 xf0
-  // xtmp7  = xc1 xd1 xe1 xf1
-  // xtmp11 = xc2 xd2 xe2 xf2
-  // xtmp15 = xc3 xd3 xe3 xf3
-
-#ifdef D64STATS
-  stop_meas(&ts_t);
-  start_meas(&ts_d);
-#endif
-
-  // xtmp0  = x00 x10 x20 x30
-  // xtmp1  = x40 x50 x60 x70
-  // xtmp2  = x80 x90 xa0 xb0
-  // xtmp3  = xc0 xd0 xe0 xf0
-  dft16((int16_t*)(xtmp),(int16_t*)ytmp);
-
-  // xtmp4  = x01 x11 x21 x31
-  // xtmp5  = x41 x51 x61 x71
-  // xtmp6  = x81 x91 xa1 xb1
-  // xtmp7  = xc1 xd1 xe1 xf1
-  dft16((int16_t*)(xtmp+4),(int16_t*)(ytmp+4));
-  dft16((int16_t*)(xtmp+8),(int16_t*)(ytmp+8));
-  dft16((int16_t*)(xtmp+12),(int16_t*)(ytmp+12));
-
-
-#ifdef D64STATS
-  stop_meas(&ts_d);
-  start_meas(&ts_b);
-#endif
-
-
-  bfly4_16(ytmp,ytmp+4,ytmp+8,ytmp+12,
-           y128,y128+4,y128+8,y128+12,
-           tw64a_128,tw64a_128+4,tw64a_128+8,
-           tw64b_128,tw64b_128+4,tw64b_128+8);
-
-  bfly4_16(ytmp+1,ytmp+5,ytmp+9,ytmp+13,
-           y128+1,y128+5,y128+9,y128+13,
-           tw64a_128+1,tw64a_128+5,tw64a_128+9,
-           tw64b_128+1,tw64b_128+5,tw64b_128+9);
-
-  bfly4_16(ytmp+2,ytmp+6,ytmp+10,ytmp+14,
-           y128+2,y128+6,y128+10,y128+14,
-           tw64a_128+2,tw64a_128+6,tw64a_128+10,
-           tw64b_128+2,tw64b_128+6,tw64b_128+10);
-
-  bfly4_16(ytmp+3,ytmp+7,ytmp+11,ytmp+15,
-           y128+3,y128+7,y128+11,y128+15,
-           tw64a_128+3,tw64a_128+7,tw64a_128+11,
-           tw64b_128+3,tw64b_128+7,tw64b_128+11);
-
-#ifdef D64STATS
-  stop_meas(&ts_b);
-  printf("t: %llu cycles, d: %llu cycles, b: %llu cycles\n",ts_t.diff,ts_d.diff,ts_b.diff);
-#endif
-
-
-  if (scale>0) {
-    y128[0]  = shiftright_int16(y128[0],3);
-    y128[1]  = shiftright_int16(y128[1],3);
-    y128[2]  = shiftright_int16(y128[2],3);
-    y128[3]  = shiftright_int16(y128[3],3);
-    y128[4]  = shiftright_int16(y128[4],3);
-    y128[5]  = shiftright_int16(y128[5],3);
-    y128[6]  = shiftright_int16(y128[6],3);
-    y128[7]  = shiftright_int16(y128[7],3);
-    y128[8]  = shiftright_int16(y128[8],3);
-    y128[9]  = shiftright_int16(y128[9],3);
-    y128[10] = shiftright_int16(y128[10],3);
-    y128[11] = shiftright_int16(y128[11],3);
-    y128[12] = shiftright_int16(y128[12],3);
-    y128[13] = shiftright_int16(y128[13],3);
-    y128[14] = shiftright_int16(y128[14],3);
-    y128[15] = shiftright_int16(y128[15],3);
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-void dft64(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[16],ytmp[16],*tw64a_256=(simd256_q15_t *)tw64a,*tw64b_256=(simd256_q15_t *)tw64b,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y;
-  simd256_q15_t xintl0,xintl1,xintl2,xintl3,xintl4,xintl5,xintl6,xintl7;
-  simd256_q15_t const perm_mask = _mm256_set_epi32(7, 3, 5, 1, 6, 2, 4, 0);
-
-
-#ifdef D64STATS
-  time_stats_t ts_t,ts_d,ts_b;
-
-  reset_meas(&ts_t);
-  reset_meas(&ts_d);
-  reset_meas(&ts_b);
-  start_meas(&ts_t);
-#endif
-
-#ifdef D64STATS
-  stop_meas(&ts_t);
-  start_meas(&ts_d);
-#endif
-  /*  
-  print_shorts256("x2560",(int16_t*)x256);
-  print_shorts256("x2561",(int16_t*)(x256+1));
-  print_shorts256("x2562",(int16_t*)(x256+2));
-  print_shorts256("x2563",(int16_t*)(x256+3));
-  print_shorts256("x2564",(int16_t*)(x256+4));
-  print_shorts256("x2565",(int16_t*)(x256+5));
-  print_shorts256("x2566",(int16_t*)(x256+6));
-  print_shorts256("x2567",(int16_t*)(x256+7));
-  */
-  xintl0 = _mm256_permutevar8x32_epi32(x256[0],perm_mask);  // x0  x4  x1  x5  x2  x6  x3  x7
-  xintl1 = _mm256_permutevar8x32_epi32(x256[1],perm_mask);  // x8  x12 x9  x13 x10 x14 x11 x15
-  xintl2 = _mm256_permutevar8x32_epi32(x256[2],perm_mask);  // x16 x20 x17 x21 x18 x22 x19 x23
-  xintl3 = _mm256_permutevar8x32_epi32(x256[3],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-  xintl4 = _mm256_permutevar8x32_epi32(x256[4],perm_mask);  // x32 x28 x25 x29 x26 x30 x27 x31
-  xintl5 = _mm256_permutevar8x32_epi32(x256[5],perm_mask);  // x40 x28 x25 x29 x26 x30 x27 x31
-  xintl6 = _mm256_permutevar8x32_epi32(x256[6],perm_mask);  // x48 x28 x25 x29 x26 x30 x27 x31
-  xintl7 = _mm256_permutevar8x32_epi32(x256[7],perm_mask);  // x56 x28 x25 x29 x26 x30 x27 x31
-  /*
-  print_shorts256("xintl0",(int16_t*)&xintl0);
-  print_shorts256("xintl1",(int16_t*)&xintl1);
-  print_shorts256("xintl2",(int16_t*)&xintl2);
-  print_shorts256("xintl3",(int16_t*)&xintl3);
-  print_shorts256("xintl4",(int16_t*)&xintl4);
-  print_shorts256("xintl5",(int16_t*)&xintl5);
-  print_shorts256("xintl6",(int16_t*)&xintl6);
-  print_shorts256("xintl7",(int16_t*)&xintl7);
-  */
-  xtmp[0] = _mm256_unpacklo_epi64(xintl0,xintl1);        // x0  x4  x8  x12 x1  x5  x9  x13
-  xtmp[4] = _mm256_unpackhi_epi64(xintl0,xintl1);        // x2  x6  x10 x14 x3  x7  x11 x15
-  xtmp[1] = _mm256_unpacklo_epi64(xintl2,xintl3);        // x16 x20 x24 x28 x17 x21 x25 x29
-  xtmp[5] = _mm256_unpackhi_epi64(xintl2,xintl3);        // x18 x22 x26 x30 x19 x23 x27 x31
-  xtmp[2] = _mm256_unpacklo_epi64(xintl4,xintl5);        // x32 x36 x40 x44 x33 x37 x41 x45
-  xtmp[6] = _mm256_unpackhi_epi64(xintl4,xintl5);        // x34 x38 x42 x46 x35 x39 x43 x47
-  xtmp[3] = _mm256_unpacklo_epi64(xintl6,xintl7);        // x48 x52 x56 x60 x49 x53 x57 x61
-  xtmp[7] = _mm256_unpackhi_epi64(xintl6,xintl7);        // x50 x54 x58 x62 x51 x55 x59 x63
-  /*
-  print_shorts256("xtmp0",(int16_t*)xtmp);
-  print_shorts256("xtmp1",(int16_t*)(xtmp+1));
-  print_shorts256("xtmp2",(int16_t*)(xtmp+2));
-  print_shorts256("xtmp3",(int16_t*)(xtmp+3));
-  print_shorts256("xtmp4",(int16_t*)(xtmp+4));
-  print_shorts256("xtmp5",(int16_t*)(xtmp+5));
-  print_shorts256("xtmp6",(int16_t*)(xtmp+6));
-  print_shorts256("xtmp7",(int16_t*)(xtmp+7));
-  */
-  dft16_simd256((int16_t*)(xtmp),(int16_t*)ytmp);
-  // [y0  y1  y2  y3  y4  y5  y6  y7]
-  // [y8  y9  y10 y11 y12 y13 y14 y15]
-  // [y16 y17 y18 y19 y20 y21 y22 y23]
-  // [y24 y25 y26 y27 y28 y29 y30 y31]
-  /*
-  print_shorts256("ytmp0",(int16_t*)ytmp);
-  print_shorts256("ytmp1",(int16_t*)(ytmp+1));
-  print_shorts256("ytmp2",(int16_t*)(ytmp+2));
-  print_shorts256("ytmp3",(int16_t*)(ytmp+3));
-  */
-  dft16_simd256((int16_t*)(xtmp+4),(int16_t*)(ytmp+4));
-  // [y32 y33 y34 y35 y36 y37 y38 y39]
-  // [y40 y41 y42 y43 y44 y45 y46 y47]
-  // [y48 y49 y50 y51 y52 y53 y54 y55]
-  // [y56 y57 y58 y59 y60 y61 y62 y63]
-  /*
-  print_shorts256("ytmp4",(int16_t*)(ytmp+4));
-  print_shorts256("ytmp5",(int16_t*)(ytmp+5));
-  print_shorts256("ytmp6",(int16_t*)(ytmp+6));
-  print_shorts256("ytmp7",(int16_t*)(ytmp+7));
-  */
-#ifdef D64STATS
-  stop_meas(&ts_d);
-  start_meas(&ts_b);
-#endif
-
-
-  bfly4_16_256(ytmp,ytmp+2,ytmp+4,ytmp+6,
-	       y256,y256+2,y256+4,y256+6,
-	       tw64a_256,tw64a_256+2,tw64a_256+4,
-	       tw64b_256,tw64b_256+2,tw64b_256+4);
-  // [y0  y1  y2  y3  y4  y5  y6  y7]
-  // [y16 y17 y18 y19 y20 y21 y22 y23]
-  // [y32 y33 y34 y35 y36 y37 y38 y39]
-  // [y48 y49 y50 y51 y52 y53 y54 y55]
-
-  bfly4_16_256(ytmp+1,ytmp+3,ytmp+5,ytmp+7,
-	       y256+1,y256+3,y256+5,y256+7,
-	       tw64a_256+1,tw64a_256+3,tw64a_256+5,
-	       tw64b_256+1,tw64b_256+3,tw64b_256+5);
-  // [y8  y9  y10 y11 y12 y13 y14 y15]
-  // [y24 y25 y26 y27 y28 y29 y30 y31]
-  // [y40 y41 y42 y43 y44 y45 y46 y47]
-  // [y56 y57 y58 y59 y60 y61 y62 y63]
-  /*  
-  print_shorts256("y256_0",(int16_t*)&y256[0]);
-  print_shorts256("y256_1",(int16_t*)&y256[1]);
-  print_shorts256("y256_2",(int16_t*)&y256[2]);
-  print_shorts256("y256_3",(int16_t*)&y256[3]);
-  print_shorts256("y256_4",(int16_t*)&y256[4]);
-  print_shorts256("y256_5",(int16_t*)&y256[5]);
-  print_shorts256("y256_6",(int16_t*)&y256[6]);
-  print_shorts256("y256_7",(int16_t*)&y256[7]);
-  */
-
-#ifdef D64STATS
-  stop_meas(&ts_b);
-  printf("t: %llu cycles, d: %llu cycles, b: %llu cycles\n",ts_t.diff,ts_d.diff,ts_b.diff);
-#endif
-
-
-  if (scale>0) {
-    y256[0]  = shiftright_int16_simd256(y256[0],3);
-    y256[1]  = shiftright_int16_simd256(y256[1],3);
-    y256[2]  = shiftright_int16_simd256(y256[2],3);
-    y256[3]  = shiftright_int16_simd256(y256[3],3);
-    y256[4]  = shiftright_int16_simd256(y256[4],3);
-    y256[5]  = shiftright_int16_simd256(y256[5],3);
-    y256[6]  = shiftright_int16_simd256(y256[6],3);
-    y256[7]  = shiftright_int16_simd256(y256[7],3);
-  }
-
-  _mm_empty();
-  _m_empty();
-
-
-}
-#endif
-
-#ifndef __AVX2__
-void idft64(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[16],ytmp[16],*tw64a_128=(simd_q15_t *)tw64,*tw64b_128=(simd_q15_t *)tw64c,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y;
-
-
-#ifdef D64STATS
-  time_stats_t ts_t,ts_d,ts_b;
-
-  reset_meas(&ts_t);
-  reset_meas(&ts_d);
-  reset_meas(&ts_b);
-  start_meas(&ts_t);
-#endif
-
-
-  transpose16_ooff(x128,xtmp,4);
-  transpose16_ooff(x128+4,xtmp+1,4);
-  transpose16_ooff(x128+8,xtmp+2,4);
-  transpose16_ooff(x128+12,xtmp+3,4);
-
-
-#ifdef D64STATS
-  stop_meas(&ts_t);
-  start_meas(&ts_d);
-#endif
-
-
-  idft16((int16_t*)(xtmp),(int16_t*)ytmp);
-  idft16((int16_t*)(xtmp+4),(int16_t*)(ytmp+4));
-  idft16((int16_t*)(xtmp+8),(int16_t*)(ytmp+8));
-  idft16((int16_t*)(xtmp+12),(int16_t*)(ytmp+12));
-
-
-#ifdef D64STATS
-  stop_meas(&ts_d);
-  start_meas(&ts_b);
-#endif
-
-
-  ibfly4_16(ytmp,ytmp+4,ytmp+8,ytmp+12,
-            y128,y128+4,y128+8,y128+12,
-            tw64a_128,tw64a_128+4,tw64a_128+8,
-            tw64b_128,tw64b_128+4,tw64b_128+8);
-  ibfly4_16(ytmp+1,ytmp+5,ytmp+9,ytmp+13,
-            y128+1,y128+5,y128+9,y128+13,
-            tw64a_128+1,tw64a_128+5,tw64a_128+9,
-            tw64b_128+1,tw64b_128+5,tw64b_128+9);
-
-  ibfly4_16(ytmp+2,ytmp+6,ytmp+10,ytmp+14,
-            y128+2,y128+6,y128+10,y128+14,
-            tw64a_128+2,tw64a_128+6,tw64a_128+10,
-            tw64b_128+2,tw64b_128+6,tw64b_128+10);
-
-  ibfly4_16(ytmp+3,ytmp+7,ytmp+11,ytmp+15,
-            y128+3,y128+7,y128+11,y128+15,
-            tw64a_128+3,tw64a_128+7,tw64a_128+11,
-            tw64b_128+3,tw64b_128+7,tw64b_128+11);
-
-#ifdef D64STATS
-  stop_meas(&ts_b);
-  printf("t: %llu cycles, d: %llu cycles, b: %llu cycles\n",ts_t.diff,ts_d.diff,ts_b.diff);
-#endif
-
-
-  if (scale>0) {
-
-    y128[0]  = shiftright_int16(y128[0],3);
-    y128[1]  = shiftright_int16(y128[1],3);
-    y128[2]  = shiftright_int16(y128[2],3);
-    y128[3]  = shiftright_int16(y128[3],3);
-    y128[4]  = shiftright_int16(y128[4],3);
-    y128[5]  = shiftright_int16(y128[5],3);
-    y128[6]  = shiftright_int16(y128[6],3);
-    y128[7]  = shiftright_int16(y128[7],3);
-    y128[8]  = shiftright_int16(y128[8],3);
-    y128[9]  = shiftright_int16(y128[9],3);
-    y128[10] = shiftright_int16(y128[10],3);
-    y128[11] = shiftright_int16(y128[11],3);
-    y128[12] = shiftright_int16(y128[12],3);
-    y128[13] = shiftright_int16(y128[13],3);
-    y128[14] = shiftright_int16(y128[14],3);
-    y128[15] = shiftright_int16(y128[15],3);
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-void idft64(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[16],ytmp[16],*tw64a_256=(simd256_q15_t *)tw64,*tw64b_256=(simd256_q15_t *)tw64c,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y;
-  register simd256_q15_t xintl0,xintl1,xintl2,xintl3,xintl4,xintl5,xintl6,xintl7;
-  simd256_q15_t const perm_mask = _mm256_set_epi32(7, 3, 5, 1, 6, 2, 4, 0);
-
-
-#ifdef D64STATS
-  time_stats_t ts_t,ts_d,ts_b;
-
-  reset_meas(&ts_t);
-  reset_meas(&ts_d);
-  reset_meas(&ts_b);
-  start_meas(&ts_t);
-#endif
-
-#ifdef D64STATS
-  stop_meas(&ts_t);
-  start_meas(&ts_d);
-#endif
-
-  xintl0 = _mm256_permutevar8x32_epi32(x256[0],perm_mask);  // x0  x4  x1  x5  x2  x6  x3  x7
-  xintl1 = _mm256_permutevar8x32_epi32(x256[1],perm_mask);  // x8  x12 x9  x13 x10 x14 x11 x15
-  xintl2 = _mm256_permutevar8x32_epi32(x256[2],perm_mask);  // x16 x20 x17 x21 x18 x22 x19 x23
-  xintl3 = _mm256_permutevar8x32_epi32(x256[3],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-  xintl4 = _mm256_permutevar8x32_epi32(x256[4],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-  xintl5 = _mm256_permutevar8x32_epi32(x256[5],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-  xintl6 = _mm256_permutevar8x32_epi32(x256[6],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-  xintl7 = _mm256_permutevar8x32_epi32(x256[7],perm_mask);  // x24 x28 x25 x29 x26 x30 x27 x31
-
-  xtmp[0] = _mm256_unpacklo_epi64(xintl0,xintl1);        // x0  x4  x8  x12 x1  x5  x9  x13
-  xtmp[4] = _mm256_unpackhi_epi64(xintl0,xintl1);        // x2  x6  x10 x14 x3  x7  x11 x15
-  xtmp[1] = _mm256_unpacklo_epi64(xintl2,xintl3);        // x16 x20 x24 x28 x17 x21 x25 x29
-  xtmp[5] = _mm256_unpackhi_epi64(xintl2,xintl3);        // x18 x22 x26 x30 x19 x23 x27 x31
-  xtmp[2] = _mm256_unpacklo_epi64(xintl4,xintl5);        // x32 x36 x40 x44 x33 x37 x41 x45
-  xtmp[6] = _mm256_unpackhi_epi64(xintl4,xintl5);        // x34 x38 x42 x46 x35 x39 x43 x47
-  xtmp[3] = _mm256_unpacklo_epi64(xintl6,xintl7);        // x48 x52 x56 x60 x49 x53 x57 x61
-  xtmp[7] = _mm256_unpackhi_epi64(xintl6,xintl7);        // x50 x54 x58 x62 x51 x55 x59 x63
-
-
-  idft16_simd256((int16_t*)(xtmp),(int16_t*)ytmp);
-  // [y0  y1  y2  y3  y16 y17 y18 y19]
-  // [y4  y5  y6  y7  y20 y21 y22 y23]
-  // [y8  y9  y10 y11 y24 y25 y26 y27]
-  // [y12 y13 y14 y15 y28 y29 y30 y31]
-
-  idft16_simd256((int16_t*)(xtmp+4),(int16_t*)(ytmp+4));
-  // [y32 y33 y34 y35 y48 y49 y50 y51]
-  // [y36 y37 y38 y39 y52 y53 y54 y55]
-  // [y40 y41 y42 y43 y56 y57 y58 y59]
-  // [y44 y45 y46 y47 y60 y61 y62 y63]
-
-#ifdef D64STATS
-  stop_meas(&ts_d);
-  start_meas(&ts_b);
-#endif
-
-
-  ibfly4_16_256(ytmp,ytmp+2,ytmp+4,ytmp+6,
-		y256,y256+2,y256+4,y256+6,
-		tw64a_256,tw64a_256+2,tw64a_256+4,
-		tw64b_256,tw64b_256+2,tw64b_256+4);
-  // [y0  y1  y2  y3  y4  y5  y6  y7]
-  // [y16 y17 y18 y19 y20 y21 y22 y23]
-  // [y32 y33 y34 y35 y36 y37 y38 y39]
-  // [y48 y49 y50 y51 y52 y53 y54 y55]
-
-  ibfly4_16_256(ytmp+1,ytmp+3,ytmp+5,ytmp+7,
-		y256+1,y256+3,y256+5,y256+7,
-		tw64a_256+1,tw64a_256+3,tw64a_256+5,
-		tw64b_256+1,tw64b_256+3,tw64b_256+5);
-  // [y8  y9  y10 y11 y12 y13 y14 y15]
-  // [y24 y25 y26 y27 y28 y29 y30 y31]
-  // [y40 y41 y42 y43 y44 y45 y46 y47]
-  // [y56 y57 y58 y59 y60 y61 y62 y63]
-
-
-#ifdef D64STATS
-  stop_meas(&ts_b);
-  printf("t: %llu cycles, d: %llu cycles, b: %llu cycles\n",ts_t.diff,ts_d.diff,ts_b.diff);
-#endif
-
-
-  if (scale>0) {
-    y256[0]  = shiftright_int16_simd256(y256[0],3);
-    y256[1]  = shiftright_int16_simd256(y256[1],3);
-    y256[2]  = shiftright_int16_simd256(y256[2],3);
-    y256[3]  = shiftright_int16_simd256(y256[3],3);
-    y256[4]  = shiftright_int16_simd256(y256[4],3);
-    y256[5]  = shiftright_int16_simd256(y256[5],3);
-    y256[6]  = shiftright_int16_simd256(y256[6],3);
-    y256[7]  = shiftright_int16_simd256(y256[7],3);
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-#endif
-
-int16_t tw128[128] __attribute__((aligned(32))) = {  32767,0,32727,-1608,32609,-3212,32412,-4808,32137,-6393,31785,-7962,31356,-9512,30851,-11039,30272,-12540,29621,-14010,28897,-15447,28105,-16846,27244,-18205,26318,-19520,25329,-20788,24278,-22005,23169,-23170,22004,-24279,20787,-25330,19519,-26319,18204,-27245,16845,-28106,15446,-28898,14009,-29622,12539,-30273,11038,-30852,9511,-31357,7961,-31786,6392,-32138,4807,-32413,3211,-32610,1607,-32728,0,-32767,-1608,-32728,-3212,-32610,-4808,-32413,-6393,-32138,-7962,-31786,-9512,-31357,-11039,-30852,-12540,-30273,-14010,-29622,-15447,-28898,-16846,-28106,-18205,-27245,-19520,-26319,-20788,-25330,-22005,-24279,-23170,-23170,-24279,-22005,-25330,-20788,-26319,-19520,-27245,-18205,-28106,-16846,-28898,-15447,-29622,-14010,-30273,-12540,-30852,-11039,-31357,-9512,-31786,-7962,-32138,-6393,-32413,-4808,-32610,-3212,-32728,-1608};
-
-int16_t tw128a[128] __attribute__((aligned(32))) = { 32767,0,32727,1608,32609,3212,32412,4808,32137,6393,31785,7962,31356,9512,30851,11039,30272,12540,29621,14010,28897,15447,28105,16846,27244,18205,26318,19520,25329,20788,24278,22005,23169,23170,22004,24279,20787,25330,19519,26319,18204,27245,16845,28106,15446,28898,14009,29622,12539,30273,11038,30852,9511,31357,7961,31786,6392,32138,4807,32413,3211,32610,1607,32728,0,32767,-1608,32728,-3212,32610,-4808,32413,-6393,32138,-7962,31786,-9512,31357,-11039,30852,-12540,30273,-14010,29622,-15447,28898,-16846,28106,-18205,27245,-19520,26319,-20788,25330,-22005,24279,-23170,23170,-24279,22005,-25330,20788,-26319,19520,-27245,18205,-28106,16846,-28898,15447,-29622,14010,-30273,12540,-30852,11039,-31357,9512,-31786,7962,-32138,6393,-32413,4808,-32610,3212,-32728,1608};
-
-int16_t tw128b[128] __attribute__((aligned(32))) = {0,32767,-1608,32727,-3212,32609,-4808,32412,-6393,32137,-7962,31785,-9512,31356,-11039,30851,-12540,30272,-14010,29621,-15447,28897,-16846,28105,-18205,27244,-19520,26318,-20788,25329,-22005,24278,-23170,23169,-24279,22004,-25330,20787,-26319,19519,-27245,18204,-28106,16845,-28898,15446,-29622,14009,-30273,12539,-30852,11038,-31357,9511,-31786,7961,-32138,6392,-32413,4807,-32610,3211,-32728,1607,-32767,0,-32728,-1608,-32610,-3212,-32413,-4808,-32138,-6393,-31786,-7962,-31357,-9512,-30852,-11039,-30273,-12540,-29622,-14010,-28898,-15447,-28106,-16846,-27245,-18205,-26319,-19520,-25330,-20788,-24279,-22005,-23170,-23170,-22005,-24279,-20788,-25330,-19520,-26319,-18205,-27245,-16846,-28106,-15447,-28898,-14010,-29622,-12540,-30273,-11039,-30852,-9512,-31357,-7962,-31786,-6393,-32138,-4808,-32413,-3212,-32610,-1608,-32728};
-
-int16_t tw128c[128] __attribute__((aligned(32))) = {0,32767,1608,32727,3212,32609,4808,32412,6393,32137,7962,31785,9512,31356,11039,30851,12540,30272,14010,29621,15447,28897,16846,28105,18205,27244,19520,26318,20788,25329,22005,24278,23170,23169,24279,22004,25330,20787,26319,19519,27245,18204,28106,16845,28898,15446,29622,14009,30273,12539,30852,11038,31357,9511,31786,7961,32138,6392,32413,4807,32610,3211,32728,1607,32767,0,32728,-1608,32610,-3212,32413,-4808,32138,-6393,31786,-7962,31357,-9512,30852,-11039,30273,-12540,29622,-14010,28898,-15447,28106,-16846,27245,-18205,26319,-19520,25330,-20788,24279,-22005,23170,-23170,22005,-24279,20788,-25330,19520,-26319,18205,-27245,16846,-28106,15447,-28898,14010,-29622,12540,-30273,11039,-30852,9512,-31357,7962,-31786,6393,-32138,4808,-32413,3212,-32610,1608,-32728};
-
-#ifndef __AVX2__
-void dft128(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[64],*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[32],*tw128a_128p=(simd_q15_t *)tw128a,*tw128b_128p=(simd_q15_t *)tw128b,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-
-  transpose4_ooff(x64  ,xtmp,32);
-  transpose4_ooff(x64+2,xtmp+1,32);
-  transpose4_ooff(x64+4,xtmp+2,32);
-  transpose4_ooff(x64+6,xtmp+3,32);
-  transpose4_ooff(x64+8,xtmp+4,32);
-  transpose4_ooff(x64+10,xtmp+5,32);
-  transpose4_ooff(x64+12,xtmp+6,32);
-  transpose4_ooff(x64+14,xtmp+7,32);
-  transpose4_ooff(x64+16,xtmp+8,32);
-  transpose4_ooff(x64+18,xtmp+9,32);
-  transpose4_ooff(x64+20,xtmp+10,32);
-  transpose4_ooff(x64+22,xtmp+11,32);
-  transpose4_ooff(x64+24,xtmp+12,32);
-  transpose4_ooff(x64+26,xtmp+13,32);
-  transpose4_ooff(x64+28,xtmp+14,32);
-  transpose4_ooff(x64+30,xtmp+15,32);
-  transpose4_ooff(x64+32,xtmp+16,32);
-  transpose4_ooff(x64+34,xtmp+17,32);
-  transpose4_ooff(x64+36,xtmp+18,32);
-  transpose4_ooff(x64+38,xtmp+19,32);
-  transpose4_ooff(x64+40,xtmp+20,32);
-  transpose4_ooff(x64+42,xtmp+21,32);
-  transpose4_ooff(x64+44,xtmp+22,32);
-  transpose4_ooff(x64+46,xtmp+23,32);
-  transpose4_ooff(x64+48,xtmp+24,32);
-  transpose4_ooff(x64+50,xtmp+25,32);
-  transpose4_ooff(x64+52,xtmp+26,32);
-  transpose4_ooff(x64+54,xtmp+27,32);
-  transpose4_ooff(x64+56,xtmp+28,32);
-  transpose4_ooff(x64+58,xtmp+29,32);
-  transpose4_ooff(x64+60,xtmp+30,32);
-  transpose4_ooff(x64+62,xtmp+31,32);
-
-  dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1);
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("dft128a.m","dfta",ytmp,64,1,1);
-    LOG_M("dft128b.m","dftb",ytmp+16,64,1,1);
-  }
-  for (i=0; i<16; i++) {
-    bfly2_16(ytmpp,ytmpp+16,
-             y128p,y128p+16,
-             tw128a_128p,
-             tw128b_128p);
-    tw128a_128p++;
-    tw128b_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    y128[0] = mulhi_int16(y128[0],ONE_OVER_SQRT2_Q15_128);
-    y128[1] = mulhi_int16(y128[1],ONE_OVER_SQRT2_Q15_128);
-    y128[2] = mulhi_int16(y128[2],ONE_OVER_SQRT2_Q15_128);
-    y128[3] = mulhi_int16(y128[3],ONE_OVER_SQRT2_Q15_128);
-    y128[4] = mulhi_int16(y128[4],ONE_OVER_SQRT2_Q15_128);
-    y128[5] = mulhi_int16(y128[5],ONE_OVER_SQRT2_Q15_128);
-    y128[6] = mulhi_int16(y128[6],ONE_OVER_SQRT2_Q15_128);
-    y128[7] = mulhi_int16(y128[7],ONE_OVER_SQRT2_Q15_128);
-    y128[8] = mulhi_int16(y128[8],ONE_OVER_SQRT2_Q15_128);
-    y128[9] = mulhi_int16(y128[9],ONE_OVER_SQRT2_Q15_128);
-    y128[10] = mulhi_int16(y128[10],ONE_OVER_SQRT2_Q15_128);
-    y128[11] = mulhi_int16(y128[11],ONE_OVER_SQRT2_Q15_128);
-    y128[12] = mulhi_int16(y128[12],ONE_OVER_SQRT2_Q15_128);
-    y128[13] = mulhi_int16(y128[13],ONE_OVER_SQRT2_Q15_128);
-    y128[14] = mulhi_int16(y128[14],ONE_OVER_SQRT2_Q15_128);
-    y128[15] = mulhi_int16(y128[15],ONE_OVER_SQRT2_Q15_128);
-    y128[16] = mulhi_int16(y128[16],ONE_OVER_SQRT2_Q15_128);
-    y128[17] = mulhi_int16(y128[17],ONE_OVER_SQRT2_Q15_128);
-    y128[18] = mulhi_int16(y128[18],ONE_OVER_SQRT2_Q15_128);
-    y128[19] = mulhi_int16(y128[19],ONE_OVER_SQRT2_Q15_128);
-    y128[20] = mulhi_int16(y128[20],ONE_OVER_SQRT2_Q15_128);
-    y128[21] = mulhi_int16(y128[21],ONE_OVER_SQRT2_Q15_128);
-    y128[22] = mulhi_int16(y128[22],ONE_OVER_SQRT2_Q15_128);
-    y128[23] = mulhi_int16(y128[23],ONE_OVER_SQRT2_Q15_128);
-    y128[24] = mulhi_int16(y128[24],ONE_OVER_SQRT2_Q15_128);
-    y128[25] = mulhi_int16(y128[25],ONE_OVER_SQRT2_Q15_128);
-    y128[26] = mulhi_int16(y128[26],ONE_OVER_SQRT2_Q15_128);
-    y128[27] = mulhi_int16(y128[27],ONE_OVER_SQRT2_Q15_128);
-    y128[28] = mulhi_int16(y128[28],ONE_OVER_SQRT2_Q15_128);
-    y128[29] = mulhi_int16(y128[29],ONE_OVER_SQRT2_Q15_128);
-    y128[30] = mulhi_int16(y128[30],ONE_OVER_SQRT2_Q15_128);
-    y128[31] = mulhi_int16(y128[31],ONE_OVER_SQRT2_Q15_128);
-
-
-  }
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-     LOG_M("dft128out.m","dft128",y,128,1,1);
-     exit(-1);
-  }
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-void dft128(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[16],*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[16],*y256=(simd256_q15_t*)y;
-  simd256_q15_t *tw128a_256p=(simd256_q15_t *)tw128a,*tw128b_256p=(simd256_q15_t *)tw128b,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_256 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-  transpose4_ooff_simd256(x256  ,xtmp,8);
-  transpose4_ooff_simd256(x256+2,xtmp+1,8);
-  transpose4_ooff_simd256(x256+4,xtmp+2,8);
-  transpose4_ooff_simd256(x256+6,xtmp+3,8);
-  transpose4_ooff_simd256(x256+8,xtmp+4,8);
-  transpose4_ooff_simd256(x256+10,xtmp+5,8);
-  transpose4_ooff_simd256(x256+12,xtmp+6,8);
-  transpose4_ooff_simd256(x256+14,xtmp+7,8);
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {  
-     LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1);
-     LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1);
-  }
-
-  dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {  
-    LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1);
-    LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1);
-  }
-
-  for (i=0; i<8; i++) {
-    bfly2_16_256(ytmpp,ytmpp+8,
-		 y256p,y256p+8,
-		 tw128a_256p,
-		 tw128b_256p);
-    tw128a_256p++;
-    tw128b_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    y256[0] = mulhi_int16_simd256(y256[0],ONE_OVER_SQRT2_Q15_256);
-    y256[1] = mulhi_int16_simd256(y256[1],ONE_OVER_SQRT2_Q15_256);
-    y256[2] = mulhi_int16_simd256(y256[2],ONE_OVER_SQRT2_Q15_256);
-    y256[3] = mulhi_int16_simd256(y256[3],ONE_OVER_SQRT2_Q15_256);
-    y256[4] = mulhi_int16_simd256(y256[4],ONE_OVER_SQRT2_Q15_256);
-    y256[5] = mulhi_int16_simd256(y256[5],ONE_OVER_SQRT2_Q15_256);
-    y256[6] = mulhi_int16_simd256(y256[6],ONE_OVER_SQRT2_Q15_256);
-    y256[7] = mulhi_int16_simd256(y256[7],ONE_OVER_SQRT2_Q15_256);
-    y256[8] = mulhi_int16_simd256(y256[8],ONE_OVER_SQRT2_Q15_256);
-    y256[9] = mulhi_int16_simd256(y256[9],ONE_OVER_SQRT2_Q15_256);
-    y256[10] = mulhi_int16_simd256(y256[10],ONE_OVER_SQRT2_Q15_256);
-    y256[11] = mulhi_int16_simd256(y256[11],ONE_OVER_SQRT2_Q15_256);
-    y256[12] = mulhi_int16_simd256(y256[12],ONE_OVER_SQRT2_Q15_256);
-    y256[13] = mulhi_int16_simd256(y256[13],ONE_OVER_SQRT2_Q15_256);
-    y256[14] = mulhi_int16_simd256(y256[14],ONE_OVER_SQRT2_Q15_256);
-    y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
-
-  }
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {  
-   LOG_M("dft128.m","dft",y256,128,1,1);
-   exit(-1);
-  }
-}
-
-#endif
-
-#ifndef __AVX2__
-void idft128(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[64],*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[32],*tw128_128p=(simd_q15_t *)tw128,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-
-  transpose4_ooff(x64  ,xtmp,32);
-  transpose4_ooff(x64+2,xtmp+1,32);
-  transpose4_ooff(x64+4,xtmp+2,32);
-  transpose4_ooff(x64+6,xtmp+3,32);
-  transpose4_ooff(x64+8,xtmp+4,32);
-  transpose4_ooff(x64+10,xtmp+5,32);
-  transpose4_ooff(x64+12,xtmp+6,32);
-  transpose4_ooff(x64+14,xtmp+7,32);
-  transpose4_ooff(x64+16,xtmp+8,32);
-  transpose4_ooff(x64+18,xtmp+9,32);
-  transpose4_ooff(x64+20,xtmp+10,32);
-  transpose4_ooff(x64+22,xtmp+11,32);
-  transpose4_ooff(x64+24,xtmp+12,32);
-  transpose4_ooff(x64+26,xtmp+13,32);
-  transpose4_ooff(x64+28,xtmp+14,32);
-  transpose4_ooff(x64+30,xtmp+15,32);
-  transpose4_ooff(x64+32,xtmp+16,32);
-  transpose4_ooff(x64+34,xtmp+17,32);
-  transpose4_ooff(x64+36,xtmp+18,32);
-  transpose4_ooff(x64+38,xtmp+19,32);
-  transpose4_ooff(x64+40,xtmp+20,32);
-  transpose4_ooff(x64+42,xtmp+21,32);
-  transpose4_ooff(x64+44,xtmp+22,32);
-  transpose4_ooff(x64+46,xtmp+23,32);
-  transpose4_ooff(x64+48,xtmp+24,32);
-  transpose4_ooff(x64+50,xtmp+25,32);
-  transpose4_ooff(x64+52,xtmp+26,32);
-  transpose4_ooff(x64+54,xtmp+27,32);
-  transpose4_ooff(x64+56,xtmp+28,32);
-  transpose4_ooff(x64+58,xtmp+29,32);
-  transpose4_ooff(x64+60,xtmp+30,32);
-  transpose4_ooff(x64+62,xtmp+31,32);
-
-  idft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1);
-
-
-  for (i=0; i<16; i++) {
-    ibfly2(ytmpp,ytmpp+16,
-           y128p,y128p+16,
-           tw128_128p);
-    tw128_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    y128[0]  = mulhi_int16(y128[0],ONE_OVER_SQRT2_Q15_128);
-    y128[1]  = mulhi_int16(y128[1],ONE_OVER_SQRT2_Q15_128);
-    y128[2]  = mulhi_int16(y128[2],ONE_OVER_SQRT2_Q15_128);
-    y128[3]  = mulhi_int16(y128[3],ONE_OVER_SQRT2_Q15_128);
-    y128[4]  = mulhi_int16(y128[4],ONE_OVER_SQRT2_Q15_128);
-    y128[5]  = mulhi_int16(y128[5],ONE_OVER_SQRT2_Q15_128);
-    y128[6]  = mulhi_int16(y128[6],ONE_OVER_SQRT2_Q15_128);
-    y128[7]  = mulhi_int16(y128[7],ONE_OVER_SQRT2_Q15_128);
-    y128[8]  = mulhi_int16(y128[8],ONE_OVER_SQRT2_Q15_128);
-    y128[9]  = mulhi_int16(y128[9],ONE_OVER_SQRT2_Q15_128);
-    y128[10] = mulhi_int16(y128[10],ONE_OVER_SQRT2_Q15_128);
-    y128[11] = mulhi_int16(y128[11],ONE_OVER_SQRT2_Q15_128);
-    y128[12] = mulhi_int16(y128[12],ONE_OVER_SQRT2_Q15_128);
-    y128[13] = mulhi_int16(y128[13],ONE_OVER_SQRT2_Q15_128);
-    y128[14] = mulhi_int16(y128[14],ONE_OVER_SQRT2_Q15_128);
-    y128[15] = mulhi_int16(y128[15],ONE_OVER_SQRT2_Q15_128);
-    y128[16] = mulhi_int16(y128[16],ONE_OVER_SQRT2_Q15_128);
-    y128[17] = mulhi_int16(y128[17],ONE_OVER_SQRT2_Q15_128);
-    y128[18] = mulhi_int16(y128[18],ONE_OVER_SQRT2_Q15_128);
-    y128[19] = mulhi_int16(y128[19],ONE_OVER_SQRT2_Q15_128);
-    y128[20] = mulhi_int16(y128[20],ONE_OVER_SQRT2_Q15_128);
-    y128[21] = mulhi_int16(y128[21],ONE_OVER_SQRT2_Q15_128);
-    y128[22] = mulhi_int16(y128[22],ONE_OVER_SQRT2_Q15_128);
-    y128[23] = mulhi_int16(y128[23],ONE_OVER_SQRT2_Q15_128);
-    y128[24] = mulhi_int16(y128[24],ONE_OVER_SQRT2_Q15_128);
-    y128[25] = mulhi_int16(y128[25],ONE_OVER_SQRT2_Q15_128);
-    y128[26] = mulhi_int16(y128[26],ONE_OVER_SQRT2_Q15_128);
-    y128[27] = mulhi_int16(y128[27],ONE_OVER_SQRT2_Q15_128);
-    y128[28] = mulhi_int16(y128[28],ONE_OVER_SQRT2_Q15_128);
-    y128[29] = mulhi_int16(y128[29],ONE_OVER_SQRT2_Q15_128);
-    y128[30] = mulhi_int16(y128[30],ONE_OVER_SQRT2_Q15_128);
-    y128[31] = mulhi_int16(y128[31],ONE_OVER_SQRT2_Q15_128);
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-void idft128(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[16],*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[16],*y256=(simd256_q15_t*)y;
-  simd256_q15_t *tw128_256p=(simd256_q15_t *)tw128,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_256 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-
-  transpose4_ooff_simd256(x256  ,xtmp,8);
-  transpose4_ooff_simd256(x256+2,xtmp+1,8);
-  transpose4_ooff_simd256(x256+4,xtmp+2,8);
-  transpose4_ooff_simd256(x256+6,xtmp+3,8);
-  transpose4_ooff_simd256(x256+8,xtmp+4,8);
-  transpose4_ooff_simd256(x256+10,xtmp+5,8);
-  transpose4_ooff_simd256(x256+12,xtmp+6,8);
-  transpose4_ooff_simd256(x256+14,xtmp+7,8);
-
-  idft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
-
-
-  for (i=0; i<8; i++) {
-    ibfly2_256(ytmpp,ytmpp+8,
-	       y256p,y256p+8,
-	       tw128_256p);
-    tw128_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    y256[0] = mulhi_int16_simd256(y256[0],ONE_OVER_SQRT2_Q15_256);
-    y256[1] = mulhi_int16_simd256(y256[1],ONE_OVER_SQRT2_Q15_256);
-    y256[2] = mulhi_int16_simd256(y256[2],ONE_OVER_SQRT2_Q15_256);
-    y256[3] = mulhi_int16_simd256(y256[3],ONE_OVER_SQRT2_Q15_256);
-    y256[4] = mulhi_int16_simd256(y256[4],ONE_OVER_SQRT2_Q15_256);
-    y256[5] = mulhi_int16_simd256(y256[5],ONE_OVER_SQRT2_Q15_256);
-    y256[6] = mulhi_int16_simd256(y256[6],ONE_OVER_SQRT2_Q15_256);
-    y256[7] = mulhi_int16_simd256(y256[7],ONE_OVER_SQRT2_Q15_256);
-    y256[8] = mulhi_int16_simd256(y256[8],ONE_OVER_SQRT2_Q15_256);
-    y256[9] = mulhi_int16_simd256(y256[9],ONE_OVER_SQRT2_Q15_256);
-    y256[10] = mulhi_int16_simd256(y256[10],ONE_OVER_SQRT2_Q15_256);
-    y256[11] = mulhi_int16_simd256(y256[11],ONE_OVER_SQRT2_Q15_256);
-    y256[12] = mulhi_int16_simd256(y256[12],ONE_OVER_SQRT2_Q15_256);
-    y256[13] = mulhi_int16_simd256(y256[13],ONE_OVER_SQRT2_Q15_256);
-    y256[14] = mulhi_int16_simd256(y256[14],ONE_OVER_SQRT2_Q15_256);
-    y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
-
-  }
-
-}
-
-#endif
-
-int16_t tw256[384] __attribute__((aligned(32))) = {  32767,0,32757,-805,32727,-1608,32678,-2411,32609,-3212,32520,-4012,32412,-4808,32284,-5602,32137,-6393,31970,-7180,31785,-7962,31580,-8740,31356,-9512,31113,-10279,30851,-11039,30571,-11793,30272,-12540,29955,-13279,29621,-14010,29268,-14733,28897,-15447,28510,-16151,28105,-16846,27683,-17531,27244,-18205,26789,-18868,26318,-19520,25831,-20160,25329,-20788,24811,-21403,24278,-22005,23731,-22595,23169,-23170,22594,-23732,22004,-24279,21402,-24812,20787,-25330,20159,-25832,19519,-26319,18867,-26790,18204,-27245,17530,-27684,16845,-28106,16150,-28511,15446,-28898,14732,-29269,14009,-29622,13278,-29956,12539,-30273,11792,-30572,11038,-30852,10278,-31114,9511,-31357,8739,-31581,7961,-31786,7179,-31971,6392,-32138,5601,-32285,4807,-32413,4011,-32521,3211,-32610,2410,-32679,1607,-32728,804,-32758,
-                                                     32767,0,32727,-1608,32609,-3212,32412,-4808,32137,-6393,31785,-7962,31356,-9512,30851,-11039,30272,-12540,29621,-14010,28897,-15447,28105,-16846,27244,-18205,26318,-19520,25329,-20788,24278,-22005,23169,-23170,22004,-24279,20787,-25330,19519,-26319,18204,-27245,16845,-28106,15446,-28898,14009,-29622,12539,-30273,11038,-30852,9511,-31357,7961,-31786,6392,-32138,4807,-32413,3211,-32610,1607,-32728,0,-32767,-1608,-32728,-3212,-32610,-4808,-32413,-6393,-32138,-7962,-31786,-9512,-31357,-11039,-30852,-12540,-30273,-14010,-29622,-15447,-28898,-16846,-28106,-18205,-27245,-19520,-26319,-20788,-25330,-22005,-24279,-23170,-23170,-24279,-22005,-25330,-20788,-26319,-19520,-27245,-18205,-28106,-16846,-28898,-15447,-29622,-14010,-30273,-12540,-30852,-11039,-31357,-9512,-31786,-7962,-32138,-6393,-32413,-4808,-32610,-3212,-32728,-1608,
-                                                     32767,0,32678,-2411,32412,-4808,31970,-7180,31356,-9512,30571,-11793,29621,-14010,28510,-16151,27244,-18205,25831,-20160,24278,-22005,22594,-23732,20787,-25330,18867,-26790,16845,-28106,14732,-29269,12539,-30273,10278,-31114,7961,-31786,5601,-32285,3211,-32610,804,-32758,-1608,-32728,-4012,-32521,-6393,-32138,-8740,-31581,-11039,-30852,-13279,-29956,-15447,-28898,-17531,-27684,-19520,-26319,-21403,-24812,-23170,-23170,-24812,-21403,-26319,-19520,-27684,-17531,-28898,-15447,-29956,-13279,-30852,-11039,-31581,-8740,-32138,-6393,-32521,-4012,-32728,-1608,-32758,804,-32610,3211,-32285,5601,-31786,7961,-31114,10278,-30273,12539,-29269,14732,-28106,16845,-26790,18867,-25330,20787,-23732,22594,-22005,24278,-20160,25831,-18205,27244,-16151,28510,-14010,29621,-11793,30571,-9512,31356,-7180,31970,-4808,32412,-2411,32678
-                                                  };
-
-int16_t tw256a[384] __attribute__((aligned(32))) = { 32767,0,32757,804,32727,1607,32678,2410,32609,3211,32520,4011,32412,4807,32284,5601,32137,6392,31970,7179,31785,7961,31580,8739,31356,9511,31113,10278,30851,11038,30571,11792,30272,12539,29955,13278,29621,14009,29268,14732,28897,15446,28510,16150,28105,16845,27683,17530,27244,18204,26789,18867,26318,19519,25831,20159,25329,20787,24811,21402,24278,22004,23731,22594,23169,23169,22594,23731,22004,24278,21402,24811,20787,25329,20159,25831,19519,26318,18867,26789,18204,27244,17530,27683,16845,28105,16150,28510,15446,28897,14732,29268,14009,29621,13278,29955,12539,30272,11792,30571,11038,30851,10278,31113,9511,31356,8739,31580,7961,31785,7179,31970,6392,32137,5601,32284,4807,32412,4011,32520,3211,32609,2410,32678,1607,32727,804,32757,
-                                                     32767,0,32727,1607,32609,3211,32412,4807,32137,6392,31785,7961,31356,9511,30851,11038,30272,12539,29621,14009,28897,15446,28105,16845,27244,18204,26318,19519,25329,20787,24278,22004,23169,23169,22004,24278,20787,25329,19519,26318,18204,27244,16845,28105,15446,28897,14009,29621,12539,30272,11038,30851,9511,31356,7961,31785,6392,32137,4807,32412,3211,32609,1607,32727,0,32767,-1608,32727,-3212,32609,-4808,32412,-6393,32137,-7962,31785,-9512,31356,-11039,30851,-12540,30272,-14010,29621,-15447,28897,-16846,28105,-18205,27244,-19520,26318,-20788,25329,-22005,24278,-23170,23169,-24279,22004,-25330,20787,-26319,19519,-27245,18204,-28106,16845,-28898,15446,-29622,14009,-30273,12539,-30852,11038,-31357,9511,-31786,7961,-32138,6392,-32413,4807,-32610,3211,-32728,1607,
-                                                     32767,0,32678,2410,32412,4807,31970,7179,31356,9511,30571,11792,29621,14009,28510,16150,27244,18204,25831,20159,24278,22004,22594,23731,20787,25329,18867,26789,16845,28105,14732,29268,12539,30272,10278,31113,7961,31785,5601,32284,3211,32609,804,32757,-1608,32727,-4012,32520,-6393,32137,-8740,31580,-11039,30851,-13279,29955,-15447,28897,-17531,27683,-19520,26318,-21403,24811,-23170,23169,-24812,21402,-26319,19519,-27684,17530,-28898,15446,-29956,13278,-30852,11038,-31581,8739,-32138,6392,-32521,4011,-32728,1607,-32758,-805,-32610,-3212,-32285,-5602,-31786,-7962,-31114,-10279,-30273,-12540,-29269,-14733,-28106,-16846,-26790,-18868,-25330,-20788,-23732,-22595,-22005,-24279,-20160,-25832,-18205,-27245,-16151,-28511,-14010,-29622,-11793,-30572,-9512,-31357,-7180,-31971,-4808,-32413,-2411,-32679
-                                                   };
-
-int16_t tw256b[384] __attribute__((aligned(32))) = {0,32767,-805,32757,-1608,32727,-2411,32678,-3212,32609,-4012,32520,-4808,32412,-5602,32284,-6393,32137,-7180,31970,-7962,31785,-8740,31580,-9512,31356,-10279,31113,-11039,30851,-11793,30571,-12540,30272,-13279,29955,-14010,29621,-14733,29268,-15447,28897,-16151,28510,-16846,28105,-17531,27683,-18205,27244,-18868,26789,-19520,26318,-20160,25831,-20788,25329,-21403,24811,-22005,24278,-22595,23731,-23170,23169,-23732,22594,-24279,22004,-24812,21402,-25330,20787,-25832,20159,-26319,19519,-26790,18867,-27245,18204,-27684,17530,-28106,16845,-28511,16150,-28898,15446,-29269,14732,-29622,14009,-29956,13278,-30273,12539,-30572,11792,-30852,11038,-31114,10278,-31357,9511,-31581,8739,-31786,7961,-31971,7179,-32138,6392,-32285,5601,-32413,4807,-32521,4011,-32610,3211,-32679,2410,-32728,1607,-32758,804,
-                                                    0,32767,-1608,32727,-3212,32609,-4808,32412,-6393,32137,-7962,31785,-9512,31356,-11039,30851,-12540,30272,-14010,29621,-15447,28897,-16846,28105,-18205,27244,-19520,26318,-20788,25329,-22005,24278,-23170,23169,-24279,22004,-25330,20787,-26319,19519,-27245,18204,-28106,16845,-28898,15446,-29622,14009,-30273,12539,-30852,11038,-31357,9511,-31786,7961,-32138,6392,-32413,4807,-32610,3211,-32728,1607,-32767,0,-32728,-1608,-32610,-3212,-32413,-4808,-32138,-6393,-31786,-7962,-31357,-9512,-30852,-11039,-30273,-12540,-29622,-14010,-28898,-15447,-28106,-16846,-27245,-18205,-26319,-19520,-25330,-20788,-24279,-22005,-23170,-23170,-22005,-24279,-20788,-25330,-19520,-26319,-18205,-27245,-16846,-28106,-15447,-28898,-14010,-29622,-12540,-30273,-11039,-30852,-9512,-31357,-7962,-31786,-6393,-32138,-4808,-32413,-3212,-32610,-1608,-32728,
-                                                    0,32767,-2411,32678,-4808,32412,-7180,31970,-9512,31356,-11793,30571,-14010,29621,-16151,28510,-18205,27244,-20160,25831,-22005,24278,-23732,22594,-25330,20787,-26790,18867,-28106,16845,-29269,14732,-30273,12539,-31114,10278,-31786,7961,-32285,5601,-32610,3211,-32758,804,-32728,-1608,-32521,-4012,-32138,-6393,-31581,-8740,-30852,-11039,-29956,-13279,-28898,-15447,-27684,-17531,-26319,-19520,-24812,-21403,-23170,-23170,-21403,-24812,-19520,-26319,-17531,-27684,-15447,-28898,-13279,-29956,-11039,-30852,-8740,-31581,-6393,-32138,-4012,-32521,-1608,-32728,804,-32758,3211,-32610,5601,-32285,7961,-31786,10278,-31114,12539,-30273,14732,-29269,16845,-28106,18867,-26790,20787,-25330,22594,-23732,24278,-22005,25831,-20160,27244,-18205,28510,-16151,29621,-14010,30571,-11793,31356,-9512,31970,-7180,32412,-4808,32678,-2411
-                                                   };
-#ifndef __AVX2__
-void dft256(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[64],ytmp[64],*tw256a_128p=(simd_q15_t *)tw256a,*tw256b_128p=(simd_q15_t *)tw256b,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-
-#ifdef D256STATS
-  time_stats_t ts_t,ts_d,ts_b;
-
-  reset_meas(&ts_t);
-  reset_meas(&ts_d);
-  reset_meas(&ts_b);
-  start_meas(&ts_t);
-#endif
-  /*
-  for (i=0,j=0;i<64;i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,16);
-  }
-  */
-  transpose16_ooff(x128+0,xtmp+0,16);
-  transpose16_ooff(x128+4,xtmp+1,16);
-  transpose16_ooff(x128+8,xtmp+2,16);
-  transpose16_ooff(x128+12,xtmp+3,16);
-  transpose16_ooff(x128+16,xtmp+4,16);
-  transpose16_ooff(x128+20,xtmp+5,16);
-  transpose16_ooff(x128+24,xtmp+6,16);
-  transpose16_ooff(x128+28,xtmp+7,16);
-  transpose16_ooff(x128+32,xtmp+8,16);
-  transpose16_ooff(x128+36,xtmp+9,16);
-  transpose16_ooff(x128+40,xtmp+10,16);
-  transpose16_ooff(x128+44,xtmp+11,16);
-  transpose16_ooff(x128+48,xtmp+12,16);
-  transpose16_ooff(x128+52,xtmp+13,16);
-  transpose16_ooff(x128+56,xtmp+14,16);
-  transpose16_ooff(x128+60,xtmp+15,16);
-
-#ifdef D256STATS
-  stop_meas(&ts_t);
-  start_meas(&ts_d);
-#endif
-
-  dft64((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft64((int16_t*)(xtmp+16),(int16_t*)(ytmp+16),1);
-  dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-  dft64((int16_t*)(xtmp+48),(int16_t*)(ytmp+48),1);
-
-#ifdef D256STATS
-  stop_meas(&ts_d);
-  start_meas(&ts_b);
-#endif
-
-  for (i=0; i<16; i+=4) {
-    bfly4_16(ytmpp,ytmpp+16,ytmpp+32,ytmpp+48,
-             y128p,y128p+16,y128p+32,y128p+48,
-             tw256a_128p,tw256a_128p+16,tw256a_128p+32,
-             tw256b_128p,tw256b_128p+16,tw256b_128p+32);
-    bfly4_16(ytmpp+1,ytmpp+17,ytmpp+33,ytmpp+49,
-             y128p+1,y128p+17,y128p+33,y128p+49,
-             tw256a_128p+1,tw256a_128p+17,tw256a_128p+33,
-             tw256b_128p+1,tw256b_128p+17,tw256b_128p+33);
-    bfly4_16(ytmpp+2,ytmpp+18,ytmpp+34,ytmpp+50,
-             y128p+2,y128p+18,y128p+34,y128p+50,
-             tw256a_128p+2,tw256a_128p+18,tw256a_128p+34,
-             tw256b_128p+2,tw256b_128p+18,tw256b_128p+34);
-    bfly4_16(ytmpp+3,ytmpp+19,ytmpp+35,ytmpp+51,
-             y128p+3,y128p+19,y128p+35,y128p+51,
-             tw256a_128p+3,tw256a_128p+19,tw256a_128p+35,
-             tw256b_128p+3,tw256b_128p+19,tw256b_128p+35);
-    tw256a_128p+=4;
-    tw256b_128p+=4;
-    y128p+=4;
-    ytmpp+=4;
-  }
-
-#ifdef D256STATS
-  stop_meas(&ts_b);
-  printf("t: %llu cycles, d: %llu cycles, b: %llu cycles\n",ts_t.diff,ts_d.diff,ts_b.diff);
-#endif
-
-  if (scale>0) {
-
-    for (i=0; i<4; i++) {
-      y128[0]  = shiftright_int16(y128[0],1);
-      y128[1]  = shiftright_int16(y128[1],1);
-      y128[2]  = shiftright_int16(y128[2],1);
-      y128[3]  = shiftright_int16(y128[3],1);
-      y128[4]  = shiftright_int16(y128[4],1);
-      y128[5]  = shiftright_int16(y128[5],1);
-      y128[6]  = shiftright_int16(y128[6],1);
-      y128[7]  = shiftright_int16(y128[7],1);
-      y128[8]  = shiftright_int16(y128[8],1);
-      y128[9]  = shiftright_int16(y128[9],1);
-      y128[10] = shiftright_int16(y128[10],1);
-      y128[11] = shiftright_int16(y128[11],1);
-      y128[12] = shiftright_int16(y128[12],1);
-      y128[13] = shiftright_int16(y128[13],1);
-      y128[14] = shiftright_int16(y128[14],1);
-      y128[15] = shiftright_int16(y128[15],1);
-
-      y128+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-
-
-void idft256(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[64],ytmp[64],*tw256_128p=(simd_q15_t *)tw256,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<64; i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,16);
-  }
-
-
-  idft64((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft64((int16_t*)(xtmp+16),(int16_t*)(ytmp+16),1);
-  idft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-  idft64((int16_t*)(xtmp+48),(int16_t*)(ytmp+48),1);
-
-  for (i=0; i<16; i++) {
-    ibfly4(ytmpp,ytmpp+16,ytmpp+32,ytmpp+48,
-           y128p,y128p+16,y128p+32,y128p+48,
-           tw256_128p,tw256_128p+16,tw256_128p+32);
-    tw256_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<4; i++) {
-      y128[0]  = shiftright_int16(y128[0],1);
-      y128[1]  = shiftright_int16(y128[1],1);
-      y128[2]  = shiftright_int16(y128[2],1);
-      y128[3]  = shiftright_int16(y128[3],1);
-      y128[4]  = shiftright_int16(y128[4],1);
-      y128[5]  = shiftright_int16(y128[5],1);
-      y128[6]  = shiftright_int16(y128[6],1);
-      y128[7]  = shiftright_int16(y128[7],1);
-      y128[8]  = shiftright_int16(y128[8],1);
-      y128[9]  = shiftright_int16(y128[9],1);
-      y128[10] = shiftright_int16(y128[10],1);
-      y128[11] = shiftright_int16(y128[11],1);
-      y128[12] = shiftright_int16(y128[12],1);
-      y128[13] = shiftright_int16(y128[13],1);
-      y128[14] = shiftright_int16(y128[14],1);
-      y128[15] = shiftright_int16(y128[15],1);
-
-      y128+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else //__AVX2__
-
-void dft256(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[32],ytmp[32],*tw256a_256p=(simd256_q15_t *)tw256a,*tw256b_256p=(simd256_q15_t *)tw256b,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-
-  transpose16_ooff_simd256(x256+0,xtmp+0,8);
-  transpose16_ooff_simd256(x256+4,xtmp+1,8);
-  transpose16_ooff_simd256(x256+8,xtmp+2,8);
-  transpose16_ooff_simd256(x256+12,xtmp+3,8);
-  transpose16_ooff_simd256(x256+16,xtmp+4,8);
-  transpose16_ooff_simd256(x256+20,xtmp+5,8);
-  transpose16_ooff_simd256(x256+24,xtmp+6,8);
-  transpose16_ooff_simd256(x256+28,xtmp+7,8);
-  /*
-  char vname[10];
-  for (i=0;i<32;i++) {
-    sprintf(vname,"xtmp%d",i);
-    print_shorts256(vname,(int16_t*)(xtmp+i));
-  }
-  exit(-1);*/
-
-  dft64((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
-  dft64((int16_t*)(xtmp+16),(int16_t*)(ytmp+16),1);
-  dft64((int16_t*)(xtmp+24),(int16_t*)(ytmp+24),1);
-
-
-  bfly4_16_256(ytmpp,ytmpp+8,ytmpp+16,ytmpp+24,
-	       y256p,y256p+8,y256p+16,y256p+24,
-	       tw256a_256p,tw256a_256p+8,tw256a_256p+16,
-	       tw256b_256p,tw256b_256p+8,tw256b_256p+16);
-  bfly4_16_256(ytmpp+1,ytmpp+9,ytmpp+17,ytmpp+25,
-	       y256p+1,y256p+9,y256p+17,y256p+25,
-	       tw256a_256p+1,tw256a_256p+9,tw256a_256p+17,
-	       tw256b_256p+1,tw256b_256p+9,tw256b_256p+17);
-  bfly4_16_256(ytmpp+2,ytmpp+10,ytmpp+18,ytmpp+26,
-	       y256p+2,y256p+10,y256p+18,y256p+26,
-	       tw256a_256p+2,tw256a_256p+10,tw256a_256p+18,
-	       tw256b_256p+2,tw256b_256p+10,tw256b_256p+18);
-  bfly4_16_256(ytmpp+3,ytmpp+11,ytmpp+19,ytmpp+27,
-	       y256p+3,y256p+11,y256p+19,y256p+27,
-	       tw256a_256p+3,tw256a_256p+11,tw256a_256p+19,
-	       tw256b_256p+3,tw256b_256p+11,tw256b_256p+19);
-  bfly4_16_256(ytmpp+4,ytmpp+12,ytmpp+20,ytmpp+28,
-	       y256p+4,y256p+12,y256p+20,y256p+28,
-	       tw256a_256p+4,tw256a_256p+12,tw256a_256p+20,
-	       tw256b_256p+4,tw256b_256p+12,tw256b_256p+20);
-  bfly4_16_256(ytmpp+5,ytmpp+13,ytmpp+21,ytmpp+29,
-	       y256p+5,y256p+13,y256p+21,y256p+29,
-	       tw256a_256p+5,tw256a_256p+13,tw256a_256p+21,
-	       tw256b_256p+5,tw256b_256p+13,tw256b_256p+21);
-  bfly4_16_256(ytmpp+6,ytmpp+14,ytmpp+22,ytmpp+30,
-	       y256p+6,y256p+14,y256p+22,y256p+30,
-	       tw256a_256p+6,tw256a_256p+14,tw256a_256p+22,
-	       tw256b_256p+6,tw256b_256p+14,tw256b_256p+22);
-  bfly4_16_256(ytmpp+7,ytmpp+15,ytmpp+23,ytmpp+31,
-	       y256p+7,y256p+15,y256p+23,y256p+31,
-	       tw256a_256p+7,tw256a_256p+15,tw256a_256p+23,
-	       tw256b_256p+7,tw256b_256p+15,tw256b_256p+23);
-
-  if (scale>0) {
-
-    for (i=0; i<2; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft256(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[32],ytmp[32],*tw256_256p=(simd256_q15_t *)tw256,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-
-  transpose16_ooff_simd256(x256+0,xtmp+0,8);
-  transpose16_ooff_simd256(x256+4,xtmp+1,8);
-  transpose16_ooff_simd256(x256+8,xtmp+2,8);
-  transpose16_ooff_simd256(x256+12,xtmp+3,8);
-  transpose16_ooff_simd256(x256+16,xtmp+4,8);
-  transpose16_ooff_simd256(x256+20,xtmp+5,8);
-  transpose16_ooff_simd256(x256+24,xtmp+6,8);
-  transpose16_ooff_simd256(x256+28,xtmp+7,8);
-  
-  idft64((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
-  idft64((int16_t*)(xtmp+16),(int16_t*)(ytmp+16),1);
-  idft64((int16_t*)(xtmp+24),(int16_t*)(ytmp+24),1);
-  
-  
-  ibfly4_256(ytmpp,ytmpp+8,ytmpp+16,ytmpp+24,
-	     y256p,y256p+8,y256p+16,y256p+24,
-	     tw256_256p,tw256_256p+8,tw256_256p+16);
-
-  ibfly4_256(ytmpp+1,ytmpp+9,ytmpp+17,ytmpp+25,
-	     y256p+1,y256p+9,y256p+17,y256p+25,
-	     tw256_256p+1,tw256_256p+9,tw256_256p+17);
-
-  ibfly4_256(ytmpp+2,ytmpp+10,ytmpp+18,ytmpp+26,
-	     y256p+2,y256p+10,y256p+18,y256p+26,
-	     tw256_256p+2,tw256_256p+10,tw256_256p+18);
-
-  ibfly4_256(ytmpp+3,ytmpp+11,ytmpp+19,ytmpp+27,
-	     y256p+3,y256p+11,y256p+19,y256p+27,
-	     tw256_256p+3,tw256_256p+11,tw256_256p+19);
-
-  ibfly4_256(ytmpp+4,ytmpp+12,ytmpp+20,ytmpp+28,
-	     y256p+4,y256p+12,y256p+20,y256p+28,
-	     tw256_256p+4,tw256_256p+12,tw256_256p+20);
-
-  ibfly4_256(ytmpp+5,ytmpp+13,ytmpp+21,ytmpp+29,
-	     y256p+5,y256p+13,y256p+21,y256p+29,
-	     tw256_256p+5,tw256_256p+13,tw256_256p+21);
-
-  ibfly4_256(ytmpp+6,ytmpp+14,ytmpp+22,ytmpp+30,
-	     y256p+6,y256p+14,y256p+22,y256p+30,
-	     tw256_256p+6,tw256_256p+14,tw256_256p+22);
-
-  ibfly4_256(ytmpp+7,ytmpp+15,ytmpp+23,ytmpp+31,
-	     y256p+7,y256p+15,y256p+23,y256p+31,
-	     tw256_256p+7,tw256_256p+15,tw256_256p+23);
-
-  
-  if (scale>0) {
-
-    for (i=0; i<2; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#endif
-int16_t tw512[512] __attribute__((aligned(32))) = {
-  32767,0,32764,-403,32757,-805,32744,-1207,32727,-1608,32705,-2010,32678,-2411,32646,-2812,32609,-3212,32567,-3612,32520,-4012,32468,-4410,32412,-4808,32350,-5206,32284,-5602,32213,-5998,32137,-6393,32056,-6787,31970,-7180,31880,-7572,31785,-7962,31684,-8352,31580,-8740,31470,-9127,31356,-9512,31236,-9896,31113,-10279,30984,-10660,30851,-11039,30713,-11417,30571,-11793,30424,-12167,30272,-12540,30116,-12910,29955,-13279,29790,-13646,29621,-14010,29446,-14373,29268,-14733,29085,-15091,28897,-15447,28706,-15800,28510,-16151,28309,-16500,28105,-16846,27896,-17190,27683,-17531,27466,-17869,27244,-18205,27019,-18538,26789,-18868,26556,-19195,26318,-19520,26077,-19841,25831,-20160,25582,-20475,25329,-20788,25072,-21097,24811,-21403,24546,-21706,24278,-22005,24006,-22302,23731,-22595,23452,-22884,23169,-23170,22883,-23453,22594,-23732,22301,-24007,22004,-24279,21705,-24547,21402,-24812,21096,-25073,20787,-25330,20474,-25583,20159,-25832,19840,-26078,19519,-26319,19194,-26557,18867,-26790,18537,-27020,18204,-27245,17868,-27467,17530,-27684,17189,-27897,16845,-28106,16499,-28310,16150,-28511,15799,-28707,15446,-28898,15090,-29086,14732,-29269,14372,-29447,14009,-29622,13645,-29791,13278,-29956,12909,-30117,12539,-30273,12166,-30425,11792,-30572,11416,-30714,11038,-30852,10659,-30985,10278,-31114,9895,-31237,9511,-31357,9126,-31471,8739,-31581,8351,-31685,7961,-31786,7571,-31881,7179,-31971,6786,-32057,6392,-32138,5997,-32214,5601,-32285,5205,-32351,4807,-32413,4409,-32469,4011,-32521,3611,-32568,3211,-32610,2811,-32647,2410,-32679,2009,-32706,1607,-32728,1206,-32745,804,-32758,402,-32765,0,-32767,-403,-32765,-805,-32758,-1207,-32745,-1608,-32728,-2010,-32706,-2411,-32679,-2812,-32647,-3212,-32610,-3612,-32568,-4012,-32521,-4410,-32469,-4808,-32413,-5206,-32351,-5602,-32285,-5998,-32214,-6393,-32138,-6787,-32057,-7180,-31971,-7572,-31881,-7962,-31786,-8352,-31685,-8740,-31581,-9127,-31471,-9512,-31357,-9896,-31237,-10279,-31114,-10660,-30985,-11039,-30852,-11417,-30714,-11793,-30572,-12167,-30425,-12540,-30273,-12910,-30117,-13279,-29956,-13646,-29791,-14010,-29622,-14373,-29447,-14733,-29269,-15091,-29086,-15447,-28898,-15800,-28707,-16151,-28511,-16500,-28310,-16846,-28106,-17190,-27897,-17531,-27684,-17869,-27467,-18205,-27245,-18538,-27020,-18868,-26790,-19195,-26557,-19520,-26319,-19841,-26078,-20160,-25832,-20475,-25583,-20788,-25330,-21097,-25073,-21403,-24812,-21706,-24547,-22005,-24279,-22302,-24007,-22595,-23732,-22884,-23453,-23170,-23170,-23453,-22884,-23732,-22595,-24007,-22302,-24279,-22005,-24547,-21706,-24812,-21403,-25073,-21097,-25330,-20788,-25583,-20475,-25832,-20160,-26078,-19841,-26319,-19520,-26557,-19195,-26790,-18868,-27020,-18538,-27245,-18205,-27467,-17869,-27684,-17531,-27897,-17190,-28106,-16846,-28310,-16500,-28511,-16151,-28707,-15800,-28898,-15447,-29086,-15091,-29269,-14733,-29447,-14373,-29622,-14010,-29791,-13646,-29956,-13279,-30117,-12910,-30273,-12540,-30425,-12167,-30572,-11793,-30714,-11417,-30852,-11039,-30985,-10660,-31114,-10279,-31237,-9896,-31357,-9512,-31471,-9127,-31581,-8740,-31685,-8352,-31786,-7962,-31881,-7572,-31971,-7180,-32057,-6787,-32138,-6393,-32214,-5998,-32285,-5602,-32351,-5206,-32413,-4808,-32469,-4410,-32521,-4012,-32568,-3612,-32610,-3212,-32647,-2812,-32679,-2411,-32706,-2010,-32728,-1608,-32745,-1207,-32758,-805,-32765,-403
-};
-
-int16_t tw512a[512] __attribute__((aligned(32))) = {
-  32767,0,32764,403,32757,805,32744,1207,32727,1608,32705,2010,32678,2411,32646,2812,32609,3212,32567,3612,32520,4012,32468,4410,32412,4808,32350,5206,32284,5602,32213,5998,32137,6393,32056,6787,31970,7180,31880,7572,31785,7962,31684,8352,31580,8740,31470,9127,31356,9512,31236,9896,31113,10279,30984,10660,30851,11039,30713,11417,30571,11793,30424,12167,30272,12540,30116,12910,29955,13279,29790,13646,29621,14010,29446,14373,29268,14733,29085,15091,28897,15447,28706,15800,28510,16151,28309,16500,28105,16846,27896,17190,27683,17531,27466,17869,27244,18205,27019,18538,26789,18868,26556,19195,26318,19520,26077,19841,25831,20160,25582,20475,25329,20788,25072,21097,24811,21403,24546,21706,24278,22005,24006,22302,23731,22595,23452,22884,23169,23170,22883,23453,22594,23732,22301,24007,22004,24279,21705,24547,21402,24812,21096,25073,20787,25330,20474,25583,20159,25832,19840,26078,19519,26319,19194,26557,18867,26790,18537,27020,18204,27245,17868,27467,17530,27684,17189,27897,16845,28106,16499,28310,16150,28511,15799,28707,15446,28898,15090,29086,14732,29269,14372,29447,14009,29622,13645,29791,13278,29956,12909,30117,12539,30273,12166,30425,11792,30572,11416,30714,11038,30852,10659,30985,10278,31114,9895,31237,9511,31357,9126,31471,8739,31581,8351,31685,7961,31786,7571,31881,7179,31971,6786,32057,6392,32138,5997,32214,5601,32285,5205,32351,4807,32413,4409,32469,4011,32521,3611,32568,3211,32610,2811,32647,2410,32679,2009,32706,1607,32728,1206,32745,804,32758,402,32765,0,32767,-403,32765,-805,32758,-1207,32745,-1608,32728,-2010,32706,-2411,32679,-2812,32647,-3212,32610,-3612,32568,-4012,32521,-4410,32469,-4808,32413,-5206,32351,-5602,32285,-5998,32214,-6393,32138,-6787,32057,-7180,31971,-7572,31881,-7962,31786,-8352,31685,-8740,31581,-9127,31471,-9512,31357,-9896,31237,-10279,31114,-10660,30985,-11039,30852,-11417,30714,-11793,30572,-12167,30425,-12540,30273,-12910,30117,-13279,29956,-13646,29791,-14010,29622,-14373,29447,-14733,29269,-15091,29086,-15447,28898,-15800,28707,-16151,28511,-16500,28310,-16846,28106,-17190,27897,-17531,27684,-17869,27467,-18205,27245,-18538,27020,-18868,26790,-19195,26557,-19520,26319,-19841,26078,-20160,25832,-20475,25583,-20788,25330,-21097,25073,-21403,24812,-21706,24547,-22005,24279,-22302,24007,-22595,23732,-22884,23453,-23170,23170,-23453,22884,-23732,22595,-24007,22302,-24279,22005,-24547,21706,-24812,21403,-25073,21097,-25330,20788,-25583,20475,-25832,20160,-26078,19841,-26319,19520,-26557,19195,-26790,18868,-27020,18538,-27245,18205,-27467,17869,-27684,17531,-27897,17190,-28106,16846,-28310,16500,-28511,16151,-28707,15800,-28898,15447,-29086,15091,-29269,14733,-29447,14373,-29622,14010,-29791,13646,-29956,13279,-30117,12910,-30273,12540,-30425,12167,-30572,11793,-30714,11417,-30852,11039,-30985,10660,-31114,10279,-31237,9896,-31357,9512,-31471,9127,-31581,8740,-31685,8352,-31786,7962,-31881,7572,-31971,7180,-32057,6787,-32138,6393,-32214,5998,-32285,5602,-32351,5206,-32413,4808,-32469,4410,-32521,4012,-32568,3612,-32610,3212,-32647,2812,-32679,2411,-32706,2010,-32728,1608,-32745,1207,-32758,805,-32765,403
-};
-
-
-
-int16_t tw512b[512] __attribute__((aligned(32))) = {
-  0,32767,-403,32764,-805,32757,-1207,32744,-1608,32727,-2010,32705,-2411,32678,-2812,32646,-3212,32609,-3612,32567,-4012,32520,-4410,32468,-4808,32412,-5206,32350,-5602,32284,-5998,32213,-6393,32137,-6787,32056,-7180,31970,-7572,31880,-7962,31785,-8352,31684,-8740,31580,-9127,31470,-9512,31356,-9896,31236,-10279,31113,-10660,30984,-11039,30851,-11417,30713,-11793,30571,-12167,30424,-12540,30272,-12910,30116,-13279,29955,-13646,29790,-14010,29621,-14373,29446,-14733,29268,-15091,29085,-15447,28897,-15800,28706,-16151,28510,-16500,28309,-16846,28105,-17190,27896,-17531,27683,-17869,27466,-18205,27244,-18538,27019,-18868,26789,-19195,26556,-19520,26318,-19841,26077,-20160,25831,-20475,25582,-20788,25329,-21097,25072,-21403,24811,-21706,24546,-22005,24278,-22302,24006,-22595,23731,-22884,23452,-23170,23169,-23453,22883,-23732,22594,-24007,22301,-24279,22004,-24547,21705,-24812,21402,-25073,21096,-25330,20787,-25583,20474,-25832,20159,-26078,19840,-26319,19519,-26557,19194,-26790,18867,-27020,18537,-27245,18204,-27467,17868,-27684,17530,-27897,17189,-28106,16845,-28310,16499,-28511,16150,-28707,15799,-28898,15446,-29086,15090,-29269,14732,-29447,14372,-29622,14009,-29791,13645,-29956,13278,-30117,12909,-30273,12539,-30425,12166,-30572,11792,-30714,11416,-30852,11038,-30985,10659,-31114,10278,-31237,9895,-31357,9511,-31471,9126,-31581,8739,-31685,8351,-31786,7961,-31881,7571,-31971,7179,-32057,6786,-32138,6392,-32214,5997,-32285,5601,-32351,5205,-32413,4807,-32469,4409,-32521,4011,-32568,3611,-32610,3211,-32647,2811,-32679,2410,-32706,2009,-32728,1607,-32745,1206,-32758,804,-32765,402,-32767,0,-32765,-403,-32758,-805,-32745,-1207,-32728,-1608,-32706,-2010,-32679,-2411,-32647,-2812,-32610,-3212,-32568,-3612,-32521,-4012,-32469,-4410,-32413,-4808,-32351,-5206,-32285,-5602,-32214,-5998,-32138,-6393,-32057,-6787,-31971,-7180,-31881,-7572,-31786,-7962,-31685,-8352,-31581,-8740,-31471,-9127,-31357,-9512,-31237,-9896,-31114,-10279,-30985,-10660,-30852,-11039,-30714,-11417,-30572,-11793,-30425,-12167,-30273,-12540,-30117,-12910,-29956,-13279,-29791,-13646,-29622,-14010,-29447,-14373,-29269,-14733,-29086,-15091,-28898,-15447,-28707,-15800,-28511,-16151,-28310,-16500,-28106,-16846,-27897,-17190,-27684,-17531,-27467,-17869,-27245,-18205,-27020,-18538,-26790,-18868,-26557,-19195,-26319,-19520,-26078,-19841,-25832,-20160,-25583,-20475,-25330,-20788,-25073,-21097,-24812,-21403,-24547,-21706,-24279,-22005,-24007,-22302,-23732,-22595,-23453,-22884,-23170,-23170,-22884,-23453,-22595,-23732,-22302,-24007,-22005,-24279,-21706,-24547,-21403,-24812,-21097,-25073,-20788,-25330,-20475,-25583,-20160,-25832,-19841,-26078,-19520,-26319,-19195,-26557,-18868,-26790,-18538,-27020,-18205,-27245,-17869,-27467,-17531,-27684,-17190,-27897,-16846,-28106,-16500,-28310,-16151,-28511,-15800,-28707,-15447,-28898,-15091,-29086,-14733,-29269,-14373,-29447,-14010,-29622,-13646,-29791,-13279,-29956,-12910,-30117,-12540,-30273,-12167,-30425,-11793,-30572,-11417,-30714,-11039,-30852,-10660,-30985,-10279,-31114,-9896,-31237,-9512,-31357,-9127,-31471,-8740,-31581,-8352,-31685,-7962,-31786,-7572,-31881,-7180,-31971,-6787,-32057,-6393,-32138,-5998,-32214,-5602,-32285,-5206,-32351,-4808,-32413,-4410,-32469,-4012,-32521,-3612,-32568,-3212,-32610,-2812,-32647,-2411,-32679,-2010,-32706,-1608,-32728,-1207,-32745,-805,-32758,-403,-32765
-};
-
-int16_t tw512c[512] __attribute__((aligned(32))) = {
-  0,32767,403,32764,805,32757,1207,32744,1608,32727,2010,32705,2411,32678,2812,32646,3212,32609,3612,32567,4012,32520,4410,32468,4808,32412,5206,32350,5602,32284,5998,32213,6393,32137,6787,32056,7180,31970,7572,31880,7962,31785,8352,31684,8740,31580,9127,31470,9512,31356,9896,31236,10279,31113,10660,30984,11039,30851,11417,30713,11793,30571,12167,30424,12540,30272,12910,30116,13279,29955,13646,29790,14010,29621,14373,29446,14733,29268,15091,29085,15447,28897,15800,28706,16151,28510,16500,28309,16846,28105,17190,27896,17531,27683,17869,27466,18205,27244,18538,27019,18868,26789,19195,26556,19520,26318,19841,26077,20160,25831,20475,25582,20788,25329,21097,25072,21403,24811,21706,24546,22005,24278,22302,24006,22595,23731,22884,23452,23170,23169,23453,22883,23732,22594,24007,22301,24279,22004,24547,21705,24812,21402,25073,21096,25330,20787,25583,20474,25832,20159,26078,19840,26319,19519,26557,19194,26790,18867,27020,18537,27245,18204,27467,17868,27684,17530,27897,17189,28106,16845,28310,16499,28511,16150,28707,15799,28898,15446,29086,15090,29269,14732,29447,14372,29622,14009,29791,13645,29956,13278,30117,12909,30273,12539,30425,12166,30572,11792,30714,11416,30852,11038,30985,10659,31114,10278,31237,9895,31357,9511,31471,9126,31581,8739,31685,8351,31786,7961,31881,7571,31971,7179,32057,6786,32138,6392,32214,5997,32285,5601,32351,5205,32413,4807,32469,4409,32521,4011,32568,3611,32610,3211,32647,2811,32679,2410,32706,2009,32728,1607,32745,1206,32758,804,32765,402,32767,0,32765,-403,32758,-805,32745,-1207,32728,-1608,32706,-2010,32679,-2411,32647,-2812,32610,-3212,32568,-3612,32521,-4012,32469,-4410,32413,-4808,32351,-5206,32285,-5602,32214,-5998,32138,-6393,32057,-6787,31971,-7180,31881,-7572,31786,-7962,31685,-8352,31581,-8740,31471,-9127,31357,-9512,31237,-9896,31114,-10279,30985,-10660,30852,-11039,30714,-11417,30572,-11793,30425,-12167,30273,-12540,30117,-12910,29956,-13279,29791,-13646,29622,-14010,29447,-14373,29269,-14733,29086,-15091,28898,-15447,28707,-15800,28511,-16151,28310,-16500,28106,-16846,27897,-17190,27684,-17531,27467,-17869,27245,-18205,27020,-18538,26790,-18868,26557,-19195,26319,-19520,26078,-19841,25832,-20160,25583,-20475,25330,-20788,25073,-21097,24812,-21403,24547,-21706,24279,-22005,24007,-22302,23732,-22595,23453,-22884,23170,-23170,22884,-23453,22595,-23732,22302,-24007,22005,-24279,21706,-24547,21403,-24812,21097,-25073,20788,-25330,20475,-25583,20160,-25832,19841,-26078,19520,-26319,19195,-26557,18868,-26790,18538,-27020,18205,-27245,17869,-27467,17531,-27684,17190,-27897,16846,-28106,16500,-28310,16151,-28511,15800,-28707,15447,-28898,15091,-29086,14733,-29269,14373,-29447,14010,-29622,13646,-29791,13279,-29956,12910,-30117,12540,-30273,12167,-30425,11793,-30572,11417,-30714,11039,-30852,10660,-30985,10279,-31114,9896,-31237,9512,-31357,9127,-31471,8740,-31581,8352,-31685,7962,-31786,7572,-31881,7180,-31971,6787,-32057,6393,-32138,5998,-32214,5602,-32285,5206,-32351,4808,-32413,4410,-32469,4012,-32521,3612,-32568,3212,-32610,2812,-32647,2411,-32679,2010,-32706,1608,-32728,1207,-32745,805,-32758,403,-32765
-};
-
-#ifndef __AVX2__
-void dft512(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[256],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[128],*tw512a_128p=(simd_q15_t *)tw512a,*tw512b_128p=(simd_q15_t *)tw512b,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-  xtmpp = xtmp;
-
-  for (i=0; i<4; i++) {
-    transpose4_ooff(x64  ,xtmpp,128);
-    transpose4_ooff(x64+2,xtmpp+1,128);
-    transpose4_ooff(x64+4,xtmpp+2,128);
-    transpose4_ooff(x64+6,xtmpp+3,128);
-    transpose4_ooff(x64+8,xtmpp+4,128);
-    transpose4_ooff(x64+10,xtmpp+5,128);
-    transpose4_ooff(x64+12,xtmpp+6,128);
-    transpose4_ooff(x64+14,xtmpp+7,128);
-    transpose4_ooff(x64+16,xtmpp+8,128);
-    transpose4_ooff(x64+18,xtmpp+9,128);
-    transpose4_ooff(x64+20,xtmpp+10,128);
-    transpose4_ooff(x64+22,xtmpp+11,128);
-    transpose4_ooff(x64+24,xtmpp+12,128);
-    transpose4_ooff(x64+26,xtmpp+13,128);
-    transpose4_ooff(x64+28,xtmpp+14,128);
-    transpose4_ooff(x64+30,xtmpp+15,128);
-    transpose4_ooff(x64+32,xtmpp+16,128);
-    transpose4_ooff(x64+34,xtmpp+17,128);
-    transpose4_ooff(x64+36,xtmpp+18,128);
-    transpose4_ooff(x64+38,xtmpp+19,128);
-    transpose4_ooff(x64+40,xtmpp+20,128);
-    transpose4_ooff(x64+42,xtmpp+21,128);
-    transpose4_ooff(x64+44,xtmpp+22,128);
-    transpose4_ooff(x64+46,xtmpp+23,128);
-    transpose4_ooff(x64+48,xtmpp+24,128);
-    transpose4_ooff(x64+50,xtmpp+25,128);
-    transpose4_ooff(x64+52,xtmpp+26,128);
-    transpose4_ooff(x64+54,xtmpp+27,128);
-    transpose4_ooff(x64+56,xtmpp+28,128);
-    transpose4_ooff(x64+58,xtmpp+29,128);
-    transpose4_ooff(x64+60,xtmpp+30,128);
-    transpose4_ooff(x64+62,xtmpp+31,128);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  dft256((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft256((int16_t*)(xtmp+128),(int16_t*)(ytmp+64),1);
-
-
-  for (i=0; i<64; i+=8) {
-    bfly2_16(ytmpp,ytmpp+64,
-             y128p,y128p+64,
-             tw512a_128p,
-             tw512b_128p);
-    bfly2_16(ytmpp+1,ytmpp+65,
-             y128p+1,y128p+65,
-             tw512a_128p+1,
-             tw512b_128p+1);
-    bfly2_16(ytmpp+2,ytmpp+66,
-             y128p+2,y128p+66,
-             tw512a_128p+2,
-             tw512b_128p+2);
-    bfly2_16(ytmpp+3,ytmpp+67,
-             y128p+3,y128p+67,
-             tw512a_128p+3,
-             tw512b_128p+3);
-    bfly2_16(ytmpp+4,ytmpp+68,
-             y128p+4,y128p+68,
-             tw512a_128p+4,
-             tw512b_128p+4);
-    bfly2_16(ytmpp+5,ytmpp+69,
-             y128p+5,y128p+69,
-             tw512a_128p+5,
-             tw512b_128p+5);
-    bfly2_16(ytmpp+6,ytmpp+70,
-             y128p+6,y128p+70,
-             tw512a_128p+6,
-             tw512b_128p+6);
-    bfly2_16(ytmpp+7,ytmpp+71,
-             y128p+7,y128p+71,
-             tw512a_128p+7,
-             tw512b_128p+7);
-    tw512a_128p+=8;
-    tw512b_128p+=8;
-    y128p+=8;
-    ytmpp+=8;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<8; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft512(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[256],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[128],*tw512_128p=(simd_q15_t *)tw512,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-  xtmpp = xtmp;
-
-  for (i=0; i<4; i++) {
-    transpose4_ooff(x64  ,xtmpp,128);
-    transpose4_ooff(x64+2,xtmpp+1,128);
-    transpose4_ooff(x64+4,xtmpp+2,128);
-    transpose4_ooff(x64+6,xtmpp+3,128);
-    transpose4_ooff(x64+8,xtmpp+4,128);
-    transpose4_ooff(x64+10,xtmpp+5,128);
-    transpose4_ooff(x64+12,xtmpp+6,128);
-    transpose4_ooff(x64+14,xtmpp+7,128);
-    transpose4_ooff(x64+16,xtmpp+8,128);
-    transpose4_ooff(x64+18,xtmpp+9,128);
-    transpose4_ooff(x64+20,xtmpp+10,128);
-    transpose4_ooff(x64+22,xtmpp+11,128);
-    transpose4_ooff(x64+24,xtmpp+12,128);
-    transpose4_ooff(x64+26,xtmpp+13,128);
-    transpose4_ooff(x64+28,xtmpp+14,128);
-    transpose4_ooff(x64+30,xtmpp+15,128);
-    transpose4_ooff(x64+32,xtmpp+16,128);
-    transpose4_ooff(x64+34,xtmpp+17,128);
-    transpose4_ooff(x64+36,xtmpp+18,128);
-    transpose4_ooff(x64+38,xtmpp+19,128);
-    transpose4_ooff(x64+40,xtmpp+20,128);
-    transpose4_ooff(x64+42,xtmpp+21,128);
-    transpose4_ooff(x64+44,xtmpp+22,128);
-    transpose4_ooff(x64+46,xtmpp+23,128);
-    transpose4_ooff(x64+48,xtmpp+24,128);
-    transpose4_ooff(x64+50,xtmpp+25,128);
-    transpose4_ooff(x64+52,xtmpp+26,128);
-    transpose4_ooff(x64+54,xtmpp+27,128);
-    transpose4_ooff(x64+56,xtmpp+28,128);
-    transpose4_ooff(x64+58,xtmpp+29,128);
-    transpose4_ooff(x64+60,xtmpp+30,128);
-    transpose4_ooff(x64+62,xtmpp+31,128);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  idft256((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft256((int16_t*)(xtmp+128),(int16_t*)(ytmp+64),1);
-
-
-  for (i=0; i<64; i++) {
-    ibfly2(ytmpp,ytmpp+64,
-           y128p,y128p+64,
-           tw512_128p);
-    tw512_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<8; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else //__AVX2__
-
-void dft512(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[64],*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[64],*y256=(simd256_q15_t*)y;
-  simd256_q15_t *tw512_256p=(simd256_q15_t*)tw512,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_256 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-
-  transpose4_ooff_simd256(x256  ,xtmp,32);
-  transpose4_ooff_simd256(x256+2,xtmp+1,32);
-  transpose4_ooff_simd256(x256+4,xtmp+2,32);
-  transpose4_ooff_simd256(x256+6,xtmp+3,32);
-  transpose4_ooff_simd256(x256+8,xtmp+4,32);
-  transpose4_ooff_simd256(x256+10,xtmp+5,32);
-  transpose4_ooff_simd256(x256+12,xtmp+6,32);
-  transpose4_ooff_simd256(x256+14,xtmp+7,32);
-  transpose4_ooff_simd256(x256+16,xtmp+8,32);
-  transpose4_ooff_simd256(x256+18,xtmp+9,32);
-  transpose4_ooff_simd256(x256+20,xtmp+10,32);
-  transpose4_ooff_simd256(x256+22,xtmp+11,32);
-  transpose4_ooff_simd256(x256+24,xtmp+12,32);
-  transpose4_ooff_simd256(x256+26,xtmp+13,32);
-  transpose4_ooff_simd256(x256+28,xtmp+14,32);
-  transpose4_ooff_simd256(x256+30,xtmp+15,32);
-  transpose4_ooff_simd256(x256+32,xtmp+16,32);
-  transpose4_ooff_simd256(x256+34,xtmp+17,32);
-  transpose4_ooff_simd256(x256+36,xtmp+18,32);
-  transpose4_ooff_simd256(x256+38,xtmp+19,32);
-  transpose4_ooff_simd256(x256+40,xtmp+20,32);
-  transpose4_ooff_simd256(x256+42,xtmp+21,32);
-  transpose4_ooff_simd256(x256+44,xtmp+22,32);
-  transpose4_ooff_simd256(x256+46,xtmp+23,32);
-  transpose4_ooff_simd256(x256+48,xtmp+24,32);
-  transpose4_ooff_simd256(x256+50,xtmp+25,32);
-  transpose4_ooff_simd256(x256+52,xtmp+26,32);
-  transpose4_ooff_simd256(x256+54,xtmp+27,32);
-  transpose4_ooff_simd256(x256+56,xtmp+28,32);
-  transpose4_ooff_simd256(x256+58,xtmp+29,32);
-  transpose4_ooff_simd256(x256+60,xtmp+30,32);
-  transpose4_ooff_simd256(x256+62,xtmp+31,32);
-
-  dft256((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft256((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-
-
-  for (i=0; i<32; i++) {
-    bfly2_256(ytmpp,ytmpp+32,
-	      y256p,y256p+32,
-	      tw512_256p);
-    tw512_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0;i<4;i++) {
-      y256[0] = mulhi_int16_simd256(y256[0],ONE_OVER_SQRT2_Q15_256);
-      y256[1] = mulhi_int16_simd256(y256[1],ONE_OVER_SQRT2_Q15_256);
-      y256[2] = mulhi_int16_simd256(y256[2],ONE_OVER_SQRT2_Q15_256);
-      y256[3] = mulhi_int16_simd256(y256[3],ONE_OVER_SQRT2_Q15_256);
-      y256[4] = mulhi_int16_simd256(y256[4],ONE_OVER_SQRT2_Q15_256);
-      y256[5] = mulhi_int16_simd256(y256[5],ONE_OVER_SQRT2_Q15_256);
-      y256[6] = mulhi_int16_simd256(y256[6],ONE_OVER_SQRT2_Q15_256);
-      y256[7] = mulhi_int16_simd256(y256[7],ONE_OVER_SQRT2_Q15_256);
-      y256[8] = mulhi_int16_simd256(y256[8],ONE_OVER_SQRT2_Q15_256);
-      y256[9] = mulhi_int16_simd256(y256[9],ONE_OVER_SQRT2_Q15_256);
-      y256[10] = mulhi_int16_simd256(y256[10],ONE_OVER_SQRT2_Q15_256);
-      y256[11] = mulhi_int16_simd256(y256[11],ONE_OVER_SQRT2_Q15_256);
-      y256[12] = mulhi_int16_simd256(y256[12],ONE_OVER_SQRT2_Q15_256);
-      y256[13] = mulhi_int16_simd256(y256[13],ONE_OVER_SQRT2_Q15_256);
-      y256[14] = mulhi_int16_simd256(y256[14],ONE_OVER_SQRT2_Q15_256);
-      y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
-      y256+=16;
-    }
-  }
-
-}
-
-void idft512(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[64],*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[64],*y256=(simd256_q15_t*)y;
-  simd256_q15_t *tw512_256p=(simd256_q15_t *)tw512,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_256 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-
-  transpose4_ooff_simd256(x256  ,xtmp,32);
-  transpose4_ooff_simd256(x256+2,xtmp+1,32);
-  transpose4_ooff_simd256(x256+4,xtmp+2,32);
-  transpose4_ooff_simd256(x256+6,xtmp+3,32);
-  transpose4_ooff_simd256(x256+8,xtmp+4,32);
-  transpose4_ooff_simd256(x256+10,xtmp+5,32);
-  transpose4_ooff_simd256(x256+12,xtmp+6,32);
-  transpose4_ooff_simd256(x256+14,xtmp+7,32);
-  transpose4_ooff_simd256(x256+16,xtmp+8,32);
-  transpose4_ooff_simd256(x256+18,xtmp+9,32);
-  transpose4_ooff_simd256(x256+20,xtmp+10,32);
-  transpose4_ooff_simd256(x256+22,xtmp+11,32);
-  transpose4_ooff_simd256(x256+24,xtmp+12,32);
-  transpose4_ooff_simd256(x256+26,xtmp+13,32);
-  transpose4_ooff_simd256(x256+28,xtmp+14,32);
-  transpose4_ooff_simd256(x256+30,xtmp+15,32);
-  transpose4_ooff_simd256(x256+32,xtmp+16,32);
-  transpose4_ooff_simd256(x256+34,xtmp+17,32);
-  transpose4_ooff_simd256(x256+36,xtmp+18,32);
-  transpose4_ooff_simd256(x256+38,xtmp+19,32);
-  transpose4_ooff_simd256(x256+40,xtmp+20,32);
-  transpose4_ooff_simd256(x256+42,xtmp+21,32);
-  transpose4_ooff_simd256(x256+44,xtmp+22,32);
-  transpose4_ooff_simd256(x256+46,xtmp+23,32);
-  transpose4_ooff_simd256(x256+48,xtmp+24,32);
-  transpose4_ooff_simd256(x256+50,xtmp+25,32);
-  transpose4_ooff_simd256(x256+52,xtmp+26,32);
-  transpose4_ooff_simd256(x256+54,xtmp+27,32);
-  transpose4_ooff_simd256(x256+56,xtmp+28,32);
-  transpose4_ooff_simd256(x256+58,xtmp+29,32);
-  transpose4_ooff_simd256(x256+60,xtmp+30,32);
-  transpose4_ooff_simd256(x256+62,xtmp+31,32);
-
-  idft256((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft256((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-
-
-  for (i=0; i<32; i++) {
-    ibfly2_256(ytmpp,ytmpp+32,
-	       y256p,y256p+32,
-	       tw512_256p);
-    tw512_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0;i<4;i++) {
-      y256[0] = mulhi_int16_simd256(y256[0],ONE_OVER_SQRT2_Q15_256);
-      y256[1] = mulhi_int16_simd256(y256[1],ONE_OVER_SQRT2_Q15_256);
-      y256[2] = mulhi_int16_simd256(y256[2],ONE_OVER_SQRT2_Q15_256);
-      y256[3] = mulhi_int16_simd256(y256[3],ONE_OVER_SQRT2_Q15_256);
-      y256[4] = mulhi_int16_simd256(y256[4],ONE_OVER_SQRT2_Q15_256);
-      y256[5] = mulhi_int16_simd256(y256[5],ONE_OVER_SQRT2_Q15_256);
-      y256[6] = mulhi_int16_simd256(y256[6],ONE_OVER_SQRT2_Q15_256);
-      y256[7] = mulhi_int16_simd256(y256[7],ONE_OVER_SQRT2_Q15_256);
-      y256[8] = mulhi_int16_simd256(y256[8],ONE_OVER_SQRT2_Q15_256);
-      y256[9] = mulhi_int16_simd256(y256[9],ONE_OVER_SQRT2_Q15_256);
-      y256[10] = mulhi_int16_simd256(y256[10],ONE_OVER_SQRT2_Q15_256);
-      y256[11] = mulhi_int16_simd256(y256[11],ONE_OVER_SQRT2_Q15_256);
-      y256[12] = mulhi_int16_simd256(y256[12],ONE_OVER_SQRT2_Q15_256);
-      y256[13] = mulhi_int16_simd256(y256[13],ONE_OVER_SQRT2_Q15_256);
-      y256[14] = mulhi_int16_simd256(y256[14],ONE_OVER_SQRT2_Q15_256);
-      y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
-      y256+=16;
-    }
-  }
-
-}
-
-#endif
-
-int16_t tw1024[1536] __attribute__((aligned(32)));
-
-#ifndef __AVX2__
-void dft1024(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[256],ytmp[256],*tw1024_128p=(simd_q15_t *)tw1024,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<256; i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,64);
-  }
-
-
-  dft256((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft256((int16_t*)(xtmp+64),(int16_t*)(ytmp+64),1);
-  dft256((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-  dft256((int16_t*)(xtmp+192),(int16_t*)(ytmp+192),1);
-
-  for (i=0; i<64; i++) {
-    bfly4(ytmpp,ytmpp+64,ytmpp+128,ytmpp+192,
-          y128p,y128p+64,y128p+128,y128p+192,
-          tw1024_128p,tw1024_128p+64,tw1024_128p+128);
-    tw1024_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<16; i++) {
-      y128[0]  = shiftright_int16(y128[0],1);
-      y128[1]  = shiftright_int16(y128[1],1);
-      y128[2]  = shiftright_int16(y128[2],1);
-      y128[3]  = shiftright_int16(y128[3],1);
-      y128[4]  = shiftright_int16(y128[4],1);
-      y128[5]  = shiftright_int16(y128[5],1);
-      y128[6]  = shiftright_int16(y128[6],1);
-      y128[7]  = shiftright_int16(y128[7],1);
-      y128[8]  = shiftright_int16(y128[8],1);
-      y128[9]  = shiftright_int16(y128[9],1);
-      y128[10] = shiftright_int16(y128[10],1);
-      y128[11] = shiftright_int16(y128[11],1);
-      y128[12] = shiftright_int16(y128[12],1);
-      y128[13] = shiftright_int16(y128[13],1);
-      y128[14] = shiftright_int16(y128[14],1);
-      y128[15] = shiftright_int16(y128[15],1);
-
-      y128+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft1024(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[256],ytmp[256],*tw1024_128p=(simd_q15_t *)tw1024,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<256; i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,64);
-  }
-
-
-  idft256((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft256((int16_t*)(xtmp+64),(int16_t*)(ytmp+64),1);
-  idft256((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-  idft256((int16_t*)(xtmp+192),(int16_t*)(ytmp+192),1);
-
-  for (i=0; i<64; i++) {
-    ibfly4(ytmpp,ytmpp+64,ytmpp+128,ytmpp+192,
-           y128p,y128p+64,y128p+128,y128p+192,
-           tw1024_128p,tw1024_128p+64,tw1024_128p+128);
-    tw1024_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<16; i++) {
-      y128[0]  = shiftright_int16(y128[0],1);
-      y128[1]  = shiftright_int16(y128[1],1);
-      y128[2]  = shiftright_int16(y128[2],1);
-      y128[3]  = shiftright_int16(y128[3],1);
-      y128[4]  = shiftright_int16(y128[4],1);
-      y128[5]  = shiftright_int16(y128[5],1);
-      y128[6]  = shiftright_int16(y128[6],1);
-      y128[7]  = shiftright_int16(y128[7],1);
-      y128[8]  = shiftright_int16(y128[8],1);
-      y128[9]  = shiftright_int16(y128[9],1);
-      y128[10] = shiftright_int16(y128[10],1);
-      y128[11] = shiftright_int16(y128[11],1);
-      y128[12] = shiftright_int16(y128[12],1);
-      y128[13] = shiftright_int16(y128[13],1);
-      y128[14] = shiftright_int16(y128[14],1);
-      y128[15] = shiftright_int16(y128[15],1);
-
-      y128+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else //__AVX2__
-void dft1024(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[128],ytmp[128],*tw1024_256p=(simd256_q15_t *)tw1024,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<128; i+=4,j++) {
-    transpose16_ooff_simd256(x256+i,xtmp+j,32);
-  }
-
-
-  dft256((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft256((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-  dft256((int16_t*)(xtmp+64),(int16_t*)(ytmp+64),1);
-  dft256((int16_t*)(xtmp+96),(int16_t*)(ytmp+96),1);
-
-  for (i=0; i<32; i++) {
-    bfly4_256(ytmpp,ytmpp+32,ytmpp+64,ytmpp+96,
-	      y256p,y256p+32,y256p+64,y256p+96,
-	      tw1024_256p,tw1024_256p+32,tw1024_256p+64);
-    tw1024_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<8; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft1024(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[128],ytmp[128],*tw1024_256p=(simd256_q15_t *)tw1024,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<128; i+=4,j++) {
-    transpose16_ooff_simd256(x256+i,xtmp+j,32);
-  }
-
-
-  idft256((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft256((int16_t*)(xtmp+32),(int16_t*)(ytmp+32),1);
-  idft256((int16_t*)(xtmp+64),(int16_t*)(ytmp+64),1);
-  idft256((int16_t*)(xtmp+96),(int16_t*)(ytmp+96),1);
-
-  for (i=0; i<32; i++) {
-    ibfly4_256(ytmpp,ytmpp+32,ytmpp+64,ytmpp+96,
-	       y256p,y256p+32,y256p+64,y256p+96,
-	       tw1024_256p,tw1024_256p+32,tw1024_256p+64);
-    tw1024_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<8; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-#endif
-
-int16_t tw2048[2048] __attribute__((aligned(32)));
-
-#ifndef __AVX2__
-void dft2048(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[1024],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[512],*tw2048_128p=(simd_q15_t *)tw2048,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-  xtmpp = xtmp;
-
-  for (i=0; i<16; i++) {
-    transpose4_ooff(x64  ,xtmpp,512);
-    transpose4_ooff(x64+2,xtmpp+1,512);
-    transpose4_ooff(x64+4,xtmpp+2,512);
-    transpose4_ooff(x64+6,xtmpp+3,512);
-    transpose4_ooff(x64+8,xtmpp+4,512);
-    transpose4_ooff(x64+10,xtmpp+5,512);
-    transpose4_ooff(x64+12,xtmpp+6,512);
-    transpose4_ooff(x64+14,xtmpp+7,512);
-    transpose4_ooff(x64+16,xtmpp+8,512);
-    transpose4_ooff(x64+18,xtmpp+9,512);
-    transpose4_ooff(x64+20,xtmpp+10,512);
-    transpose4_ooff(x64+22,xtmpp+11,512);
-    transpose4_ooff(x64+24,xtmpp+12,512);
-    transpose4_ooff(x64+26,xtmpp+13,512);
-    transpose4_ooff(x64+28,xtmpp+14,512);
-    transpose4_ooff(x64+30,xtmpp+15,512);
-    transpose4_ooff(x64+32,xtmpp+16,512);
-    transpose4_ooff(x64+34,xtmpp+17,512);
-    transpose4_ooff(x64+36,xtmpp+18,512);
-    transpose4_ooff(x64+38,xtmpp+19,512);
-    transpose4_ooff(x64+40,xtmpp+20,512);
-    transpose4_ooff(x64+42,xtmpp+21,512);
-    transpose4_ooff(x64+44,xtmpp+22,512);
-    transpose4_ooff(x64+46,xtmpp+23,512);
-    transpose4_ooff(x64+48,xtmpp+24,512);
-    transpose4_ooff(x64+50,xtmpp+25,512);
-    transpose4_ooff(x64+52,xtmpp+26,512);
-    transpose4_ooff(x64+54,xtmpp+27,512);
-    transpose4_ooff(x64+56,xtmpp+28,512);
-    transpose4_ooff(x64+58,xtmpp+29,512);
-    transpose4_ooff(x64+60,xtmpp+30,512);
-    transpose4_ooff(x64+62,xtmpp+31,512);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  dft1024((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft1024((int16_t*)(xtmp+512),(int16_t*)(ytmp+256),1);
-
-
-  for (i=0; i<256; i++) {
-    bfly2(ytmpp,ytmpp+256,
-          y128p,y128p+256,
-          tw2048_128p);
-    tw2048_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<32; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-
-}
-
-void idft2048(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[1024],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[512],*tw2048_128p=(simd_q15_t *)tw2048,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-  xtmpp = xtmp;
-
-  for (i=0; i<16; i++) {
-    transpose4_ooff(x64  ,xtmpp,512);
-    transpose4_ooff(x64+2,xtmpp+1,512);
-    transpose4_ooff(x64+4,xtmpp+2,512);
-    transpose4_ooff(x64+6,xtmpp+3,512);
-    transpose4_ooff(x64+8,xtmpp+4,512);
-    transpose4_ooff(x64+10,xtmpp+5,512);
-    transpose4_ooff(x64+12,xtmpp+6,512);
-    transpose4_ooff(x64+14,xtmpp+7,512);
-    transpose4_ooff(x64+16,xtmpp+8,512);
-    transpose4_ooff(x64+18,xtmpp+9,512);
-    transpose4_ooff(x64+20,xtmpp+10,512);
-    transpose4_ooff(x64+22,xtmpp+11,512);
-    transpose4_ooff(x64+24,xtmpp+12,512);
-    transpose4_ooff(x64+26,xtmpp+13,512);
-    transpose4_ooff(x64+28,xtmpp+14,512);
-    transpose4_ooff(x64+30,xtmpp+15,512);
-    transpose4_ooff(x64+32,xtmpp+16,512);
-    transpose4_ooff(x64+34,xtmpp+17,512);
-    transpose4_ooff(x64+36,xtmpp+18,512);
-    transpose4_ooff(x64+38,xtmpp+19,512);
-    transpose4_ooff(x64+40,xtmpp+20,512);
-    transpose4_ooff(x64+42,xtmpp+21,512);
-    transpose4_ooff(x64+44,xtmpp+22,512);
-    transpose4_ooff(x64+46,xtmpp+23,512);
-    transpose4_ooff(x64+48,xtmpp+24,512);
-    transpose4_ooff(x64+50,xtmpp+25,512);
-    transpose4_ooff(x64+52,xtmpp+26,512);
-    transpose4_ooff(x64+54,xtmpp+27,512);
-    transpose4_ooff(x64+56,xtmpp+28,512);
-    transpose4_ooff(x64+58,xtmpp+29,512);
-    transpose4_ooff(x64+60,xtmpp+30,512);
-    transpose4_ooff(x64+62,xtmpp+31,512);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  idft1024((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft1024((int16_t*)(xtmp+512),(int16_t*)(ytmp+256),1);
-
-
-  for (i=0; i<256; i++) {
-    ibfly2(ytmpp,ytmpp+256,
-           y128p,y128p+256,
-           tw2048_128p);
-    tw2048_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<32; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-
-void dft2048(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[256],*xtmpp,*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[256],*tw2048_256p=(simd256_q15_t *)tw2048,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-
-  xtmpp = xtmp;
-
-  for (i=0; i<4; i++) {
-    transpose4_ooff_simd256(x256  ,xtmpp,128);
-    transpose4_ooff_simd256(x256+2,xtmpp+1,128);
-    transpose4_ooff_simd256(x256+4,xtmpp+2,128);
-    transpose4_ooff_simd256(x256+6,xtmpp+3,128);
-    transpose4_ooff_simd256(x256+8,xtmpp+4,128);
-    transpose4_ooff_simd256(x256+10,xtmpp+5,128);
-    transpose4_ooff_simd256(x256+12,xtmpp+6,128);
-    transpose4_ooff_simd256(x256+14,xtmpp+7,128);
-    transpose4_ooff_simd256(x256+16,xtmpp+8,128);
-    transpose4_ooff_simd256(x256+18,xtmpp+9,128);
-    transpose4_ooff_simd256(x256+20,xtmpp+10,128);
-    transpose4_ooff_simd256(x256+22,xtmpp+11,128);
-    transpose4_ooff_simd256(x256+24,xtmpp+12,128);
-    transpose4_ooff_simd256(x256+26,xtmpp+13,128);
-    transpose4_ooff_simd256(x256+28,xtmpp+14,128);
-    transpose4_ooff_simd256(x256+30,xtmpp+15,128);
-    transpose4_ooff_simd256(x256+32,xtmpp+16,128);
-    transpose4_ooff_simd256(x256+34,xtmpp+17,128);
-    transpose4_ooff_simd256(x256+36,xtmpp+18,128);
-    transpose4_ooff_simd256(x256+38,xtmpp+19,128);
-    transpose4_ooff_simd256(x256+40,xtmpp+20,128);
-    transpose4_ooff_simd256(x256+42,xtmpp+21,128);
-    transpose4_ooff_simd256(x256+44,xtmpp+22,128);
-    transpose4_ooff_simd256(x256+46,xtmpp+23,128);
-    transpose4_ooff_simd256(x256+48,xtmpp+24,128);
-    transpose4_ooff_simd256(x256+50,xtmpp+25,128);
-    transpose4_ooff_simd256(x256+52,xtmpp+26,128);
-    transpose4_ooff_simd256(x256+54,xtmpp+27,128);
-    transpose4_ooff_simd256(x256+56,xtmpp+28,128);
-    transpose4_ooff_simd256(x256+58,xtmpp+29,128);
-    transpose4_ooff_simd256(x256+60,xtmpp+30,128);
-    transpose4_ooff_simd256(x256+62,xtmpp+31,128);
-    x256+=64;
-    xtmpp+=32;
-  }
-
-  dft1024((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft1024((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-
-
-  for (i=0; i<128; i++) {
-    bfly2_256(ytmpp,ytmpp+128,
-	      y256p,y256p+128,
-	      tw2048_256p);
-    tw2048_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y256p = y256;
-
-    for (i=0; i<16; i++) {
-      y256p[0]  = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
-      y256p[1]  = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
-      y256p[2]  = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
-      y256p[3]  = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
-      y256p[4]  = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
-      y256p[5]  = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
-      y256p[6]  = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
-      y256p[7]  = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
-      y256p[8]  = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
-      y256p[9]  = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
-      y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
-      y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
-      y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
-      y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
-      y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
-      y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
-      y256p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft2048(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[256],*xtmpp,*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[256],*tw2048_256p=(simd256_q15_t *)tw2048,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-
-  xtmpp = xtmp;
-  
-  for (i=0; i<4; i++) {
-    transpose4_ooff_simd256(x256  ,xtmpp,128);
-    transpose4_ooff_simd256(x256+2,xtmpp+1,128);
-    transpose4_ooff_simd256(x256+4,xtmpp+2,128);
-    transpose4_ooff_simd256(x256+6,xtmpp+3,128);
-    transpose4_ooff_simd256(x256+8,xtmpp+4,128);
-    transpose4_ooff_simd256(x256+10,xtmpp+5,128);
-    transpose4_ooff_simd256(x256+12,xtmpp+6,128);
-    transpose4_ooff_simd256(x256+14,xtmpp+7,128);
-    transpose4_ooff_simd256(x256+16,xtmpp+8,128);
-    transpose4_ooff_simd256(x256+18,xtmpp+9,128);
-    transpose4_ooff_simd256(x256+20,xtmpp+10,128);
-    transpose4_ooff_simd256(x256+22,xtmpp+11,128);
-    transpose4_ooff_simd256(x256+24,xtmpp+12,128);
-    transpose4_ooff_simd256(x256+26,xtmpp+13,128);
-    transpose4_ooff_simd256(x256+28,xtmpp+14,128);
-    transpose4_ooff_simd256(x256+30,xtmpp+15,128);
-    transpose4_ooff_simd256(x256+32,xtmpp+16,128);
-    transpose4_ooff_simd256(x256+34,xtmpp+17,128);
-    transpose4_ooff_simd256(x256+36,xtmpp+18,128);
-    transpose4_ooff_simd256(x256+38,xtmpp+19,128);
-    transpose4_ooff_simd256(x256+40,xtmpp+20,128);
-    transpose4_ooff_simd256(x256+42,xtmpp+21,128);
-    transpose4_ooff_simd256(x256+44,xtmpp+22,128);
-    transpose4_ooff_simd256(x256+46,xtmpp+23,128);
-    transpose4_ooff_simd256(x256+48,xtmpp+24,128);
-    transpose4_ooff_simd256(x256+50,xtmpp+25,128);
-    transpose4_ooff_simd256(x256+52,xtmpp+26,128);
-    transpose4_ooff_simd256(x256+54,xtmpp+27,128);
-    transpose4_ooff_simd256(x256+56,xtmpp+28,128);
-    transpose4_ooff_simd256(x256+58,xtmpp+29,128);
-    transpose4_ooff_simd256(x256+60,xtmpp+30,128);
-    transpose4_ooff_simd256(x256+62,xtmpp+31,128);
-    x256+=64;
-    xtmpp+=32;
-  }
-
-  idft1024((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft1024((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-
-
-  for (i=0; i<128; i++) {
-    ibfly2_256(ytmpp,ytmpp+128,
-	       y256p,y256p+128,
-	       tw2048_256p);
-    tw2048_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y256p = y256;
-
-    for (i=0; i<16; i++) {
-      y256p[0]  = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
-      y256p[1]  = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
-      y256p[2]  = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
-      y256p[3]  = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
-      y256p[4]  = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
-      y256p[5]  = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
-      y256p[6]  = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
-      y256p[7]  = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
-      y256p[8]  = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
-      y256p[9]  = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
-      y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
-      y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
-      y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
-      y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
-      y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
-      y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
-      y256p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#endif
-
-
-
-int16_t tw4096[3*2*1024];
-
-#ifndef __AVX2__
-void dft4096(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[1024],ytmp[1024],*tw4096_128p=(simd_q15_t *)tw4096,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<1024; i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,256);
-  }
-
-
-  dft1024((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft1024((int16_t*)(xtmp+256),(int16_t*)(ytmp+256),1);
-  dft1024((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
-  dft1024((int16_t*)(xtmp+768),(int16_t*)(ytmp+768),1);
-
-  for (i=0; i<256; i++) {
-    bfly4(ytmpp,ytmpp+256,ytmpp+512,ytmpp+768,
-          y128p,y128p+256,y128p+512,y128p+768,
-          tw4096_128p,tw4096_128p+256,tw4096_128p+512);
-    tw4096_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<64; i++) {
-      y128[0]  = shiftright_int16(y128[0],1);
-      y128[1]  = shiftright_int16(y128[1],1);
-      y128[2]  = shiftright_int16(y128[2],1);
-      y128[3]  = shiftright_int16(y128[3],1);
-      y128[4]  = shiftright_int16(y128[4],1);
-      y128[5]  = shiftright_int16(y128[5],1);
-      y128[6]  = shiftright_int16(y128[6],1);
-      y128[7]  = shiftright_int16(y128[7],1);
-      y128[8]  = shiftright_int16(y128[8],1);
-      y128[9]  = shiftright_int16(y128[9],1);
-      y128[10] = shiftright_int16(y128[10],1);
-      y128[11] = shiftright_int16(y128[11],1);
-      y128[12] = shiftright_int16(y128[12],1);
-      y128[13] = shiftright_int16(y128[13],1);
-      y128[14] = shiftright_int16(y128[14],1);
-      y128[15] = shiftright_int16(y128[15],1);
-
-      y128+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
- 
-
-void idft4096(int16_t *x,int16_t *y,int scale)
-{
-
-  simd_q15_t xtmp[1024],ytmp[1024],*tw4096_128p=(simd_q15_t *)tw4096,*x128=(simd_q15_t *)x,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<1024; i+=4,j++) {
-    transpose16_ooff(x128+i,xtmp+j,256);
-  }
-
-
-  idft1024((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft1024((int16_t*)(xtmp+256),(int16_t*)(ytmp+256),1);
-  idft1024((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
-  idft1024((int16_t*)(xtmp+768),(int16_t*)(ytmp+768),1);
-
-  for (i=0; i<256; i++) {
-    ibfly4(ytmpp,ytmpp+256,ytmpp+512,ytmpp+768,
-           y128p,y128p+256,y128p+512,y128p+768,
-           tw4096_128p,tw4096_128p+256,tw4096_128p+512);
-    tw4096_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<64; i++) {
-      y128[0]  = shiftright_int16(y128[0],scale);
-      y128[1]  = shiftright_int16(y128[1],scale);
-      y128[2]  = shiftright_int16(y128[2],scale);
-      y128[3]  = shiftright_int16(y128[3],scale);
-      y128[4]  = shiftright_int16(y128[4],scale);
-      y128[5]  = shiftright_int16(y128[5],scale);
-      y128[6]  = shiftright_int16(y128[6],scale);
-      y128[7]  = shiftright_int16(y128[7],scale);
-      y128[8]  = shiftright_int16(y128[8],scale);
-      y128[9]  = shiftright_int16(y128[9],scale);
-      y128[10] = shiftright_int16(y128[10],scale);
-      y128[11] = shiftright_int16(y128[11],scale);
-      y128[12] = shiftright_int16(y128[12],scale);
-      y128[13] = shiftright_int16(y128[13],scale);
-      y128[14] = shiftright_int16(y128[14],scale);
-      y128[15] = shiftright_int16(y128[15],scale);
-
-      y128+=16;
-    }
- 
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else //__AVX2__
-void dft4096(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[512],ytmp[512],*tw4096_256p=(simd256_q15_t *)tw4096,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<512; i+=4,j++) {
-    transpose16_ooff_simd256(x256+i,xtmp+j,128);
-  }
-
-
-  dft1024((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  dft1024((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-  dft1024((int16_t*)(xtmp+256),(int16_t*)(ytmp+256),1);
-  dft1024((int16_t*)(xtmp+384),(int16_t*)(ytmp+384),1);
-
-  for (i=0; i<128; i++) {
-    bfly4_256(ytmpp,ytmpp+128,ytmpp+256,ytmpp+384,
-	      y256p,y256p+128,y256p+256,y256p+384,
-	      tw4096_256p,tw4096_256p+128,tw4096_256p+256);
-    tw4096_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<32; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft4096(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[512],ytmp[512],*tw4096_256p=(simd256_q15_t *)tw4096,*x256=(simd256_q15_t *)x,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i,j;
-
-  for (i=0,j=0; i<512; i+=4,j++) {
-    transpose16_ooff_simd256(x256+i,xtmp+j,128);
-  }
-
-
-  idft1024((int16_t*)(xtmp),(int16_t*)(ytmp),1);
-  idft1024((int16_t*)(xtmp+128),(int16_t*)(ytmp+128),1);
-  idft1024((int16_t*)(xtmp+256),(int16_t*)(ytmp+256),1);
-  idft1024((int16_t*)(xtmp+384),(int16_t*)(ytmp+384),1);
-
-  for (i=0; i<128; i++) {
-    ibfly4_256(ytmpp,ytmpp+128,ytmpp+256,ytmpp+384,
-	       y256p,y256p+128,y256p+256,y256p+384,
-	       tw4096_256p,tw4096_256p+128,tw4096_256p+256);
-    tw4096_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-
-    for (i=0; i<32; i++) {
-      y256[0]  = shiftright_int16_simd256(y256[0],1);
-      y256[1]  = shiftright_int16_simd256(y256[1],1);
-      y256[2]  = shiftright_int16_simd256(y256[2],1);
-      y256[3]  = shiftright_int16_simd256(y256[3],1);
-      y256[4]  = shiftright_int16_simd256(y256[4],1);
-      y256[5]  = shiftright_int16_simd256(y256[5],1);
-      y256[6]  = shiftright_int16_simd256(y256[6],1);
-      y256[7]  = shiftright_int16_simd256(y256[7],1);
-      y256[8]  = shiftright_int16_simd256(y256[8],1);
-      y256[9]  = shiftright_int16_simd256(y256[9],1);
-      y256[10] = shiftright_int16_simd256(y256[10],1);
-      y256[11] = shiftright_int16_simd256(y256[11],1);
-      y256[12] = shiftright_int16_simd256(y256[12],1);
-      y256[13] = shiftright_int16_simd256(y256[13],1);
-      y256[14] = shiftright_int16_simd256(y256[14],1);
-      y256[15] = shiftright_int16_simd256(y256[15],1);
-
-      y256+=16;
-    }
-
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#endif //__AVX2__
-
-
-int16_t tw8192[2*4096] __attribute__((aligned(32)));
-
-#ifndef __AVX2__
-void dft8192(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[4096],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[1024],*tw8192_128p=(simd_q15_t *)tw8192,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-  
-  xtmpp = xtmp;
-
-  for (i=0; i<64; i++) {
-    transpose4_ooff(x64  ,xtmpp,2048);
-    transpose4_ooff(x64+2,xtmpp+1,2048);
-    transpose4_ooff(x64+4,xtmpp+2,2048);
-    transpose4_ooff(x64+6,xtmpp+3,2048);
-    transpose4_ooff(x64+8,xtmpp+4,2048);
-    transpose4_ooff(x64+10,xtmpp+5,2048);
-    transpose4_ooff(x64+12,xtmpp+6,2048);
-    transpose4_ooff(x64+14,xtmpp+7,2048);
-    transpose4_ooff(x64+16,xtmpp+8,2048);
-    transpose4_ooff(x64+18,xtmpp+9,2048);
-    transpose4_ooff(x64+20,xtmpp+10,2048);
-    transpose4_ooff(x64+22,xtmpp+11,2048);
-    transpose4_ooff(x64+24,xtmpp+12,2048);
-    transpose4_ooff(x64+26,xtmpp+13,2048);
-    transpose4_ooff(x64+28,xtmpp+14,2048);
-    transpose4_ooff(x64+30,xtmpp+15,2048);
-    transpose4_ooff(x64+32,xtmpp+16,2048);
-    transpose4_ooff(x64+34,xtmpp+17,2048);
-    transpose4_ooff(x64+36,xtmpp+18,2048);
-    transpose4_ooff(x64+38,xtmpp+19,2048);
-    transpose4_ooff(x64+40,xtmpp+20,2048);
-    transpose4_ooff(x64+42,xtmpp+21,2048);
-    transpose4_ooff(x64+44,xtmpp+22,2048);
-    transpose4_ooff(x64+46,xtmpp+23,2048);
-    transpose4_ooff(x64+48,xtmpp+24,2048);
-    transpose4_ooff(x64+50,xtmpp+25,2048);
-    transpose4_ooff(x64+52,xtmpp+26,2048);
-    transpose4_ooff(x64+54,xtmpp+27,2048);
-    transpose4_ooff(x64+56,xtmpp+28,2048);
-    transpose4_ooff(x64+58,xtmpp+29,2048);
-    transpose4_ooff(x64+60,xtmpp+30,2048);
-    transpose4_ooff(x64+62,xtmpp+31,2048);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  dft4096((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft4096((int16_t*)(xtmp+2048),(int16_t*)(ytmp+1024),1);
-
-
-  for (i=0; i<1024; i++) {
-    bfly2(ytmpp,ytmpp+1024,
-          y128p,y128p+1024,
-          tw8192_128p);
-    tw8192_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<128; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft8192(int16_t *x,int16_t *y,int scale)
-{
-
-  simdshort_q15_t xtmp[4096],*xtmpp,*x64 = (simdshort_q15_t *)x;
-  simd_q15_t ytmp[2048],*tw8192_128p=(simd_q15_t *)tw8192,*y128=(simd_q15_t *)y,*y128p=(simd_q15_t *)y;
-  simd_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16(ONE_OVER_SQRT2_Q15);
-  
-  xtmpp = xtmp;
-
-  for (i=0; i<64; i++) {
-    transpose4_ooff(x64  ,xtmpp,2048);
-    transpose4_ooff(x64+2,xtmpp+1,2048);
-    transpose4_ooff(x64+4,xtmpp+2,2048);
-    transpose4_ooff(x64+6,xtmpp+3,2048);
-    transpose4_ooff(x64+8,xtmpp+4,2048);
-    transpose4_ooff(x64+10,xtmpp+5,2048);
-    transpose4_ooff(x64+12,xtmpp+6,2048);
-    transpose4_ooff(x64+14,xtmpp+7,2048);
-    transpose4_ooff(x64+16,xtmpp+8,2048);
-    transpose4_ooff(x64+18,xtmpp+9,2048);
-    transpose4_ooff(x64+20,xtmpp+10,2048);
-    transpose4_ooff(x64+22,xtmpp+11,2048);
-    transpose4_ooff(x64+24,xtmpp+12,2048);
-    transpose4_ooff(x64+26,xtmpp+13,2048);
-    transpose4_ooff(x64+28,xtmpp+14,2048);
-    transpose4_ooff(x64+30,xtmpp+15,2048);
-    transpose4_ooff(x64+32,xtmpp+16,2048);
-    transpose4_ooff(x64+34,xtmpp+17,2048);
-    transpose4_ooff(x64+36,xtmpp+18,2048);
-    transpose4_ooff(x64+38,xtmpp+19,2048);
-    transpose4_ooff(x64+40,xtmpp+20,2048);
-    transpose4_ooff(x64+42,xtmpp+21,2048);
-    transpose4_ooff(x64+44,xtmpp+22,2048);
-    transpose4_ooff(x64+46,xtmpp+23,2048);
-    transpose4_ooff(x64+48,xtmpp+24,2048);
-    transpose4_ooff(x64+50,xtmpp+25,2048);
-    transpose4_ooff(x64+52,xtmpp+26,2048);
-    transpose4_ooff(x64+54,xtmpp+27,2048);
-    transpose4_ooff(x64+56,xtmpp+28,2048);
-    transpose4_ooff(x64+58,xtmpp+29,2048);
-    transpose4_ooff(x64+60,xtmpp+30,2048);
-    transpose4_ooff(x64+62,xtmpp+31,2048);
-    x64+=64;
-    xtmpp+=32;
-  }
-
-  idft4096((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft4096((int16_t*)(xtmp+2048),(int16_t*)(ytmp+1024),1);
-
-
-  for (i=0; i<1024; i++) {
-    ibfly2(ytmpp,ytmpp+1024,
-           y128p,y128p+1024,
-           tw8192_128p);
-    tw8192_128p++;
-    y128p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y128p = y128;
-
-    for (i=0; i<128; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT2_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT2_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT2_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT2_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT2_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT2_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT2_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT2_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT2_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT2_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT2_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT2_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT2_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT2_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT2_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT2_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#else // __AVX2__
-void dft8192(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[1024],*xtmpp,*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[1024],*tw8192_256p=(simd256_q15_t *)tw8192,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-  
-  xtmpp = xtmp;
-
-  for (i=0; i<16; i++) {
-    transpose4_ooff_simd256(x256  ,xtmpp,512);
-    transpose4_ooff_simd256(x256+2,xtmpp+1,512);
-    transpose4_ooff_simd256(x256+4,xtmpp+2,512);
-    transpose4_ooff_simd256(x256+6,xtmpp+3,512);
-    transpose4_ooff_simd256(x256+8,xtmpp+4,512);
-    transpose4_ooff_simd256(x256+10,xtmpp+5,512);
-    transpose4_ooff_simd256(x256+12,xtmpp+6,512);
-    transpose4_ooff_simd256(x256+14,xtmpp+7,512);
-    transpose4_ooff_simd256(x256+16,xtmpp+8,512);
-    transpose4_ooff_simd256(x256+18,xtmpp+9,512);
-    transpose4_ooff_simd256(x256+20,xtmpp+10,512);
-    transpose4_ooff_simd256(x256+22,xtmpp+11,512);
-    transpose4_ooff_simd256(x256+24,xtmpp+12,512);
-    transpose4_ooff_simd256(x256+26,xtmpp+13,512);
-    transpose4_ooff_simd256(x256+28,xtmpp+14,512);
-    transpose4_ooff_simd256(x256+30,xtmpp+15,512);
-    transpose4_ooff_simd256(x256+32,xtmpp+16,512);
-    transpose4_ooff_simd256(x256+34,xtmpp+17,512);
-    transpose4_ooff_simd256(x256+36,xtmpp+18,512);
-    transpose4_ooff_simd256(x256+38,xtmpp+19,512);
-    transpose4_ooff_simd256(x256+40,xtmpp+20,512);
-    transpose4_ooff_simd256(x256+42,xtmpp+21,512);
-    transpose4_ooff_simd256(x256+44,xtmpp+22,512);
-    transpose4_ooff_simd256(x256+46,xtmpp+23,512);
-    transpose4_ooff_simd256(x256+48,xtmpp+24,512);
-    transpose4_ooff_simd256(x256+50,xtmpp+25,512);
-    transpose4_ooff_simd256(x256+52,xtmpp+26,512);
-    transpose4_ooff_simd256(x256+54,xtmpp+27,512);
-    transpose4_ooff_simd256(x256+56,xtmpp+28,512);
-    transpose4_ooff_simd256(x256+58,xtmpp+29,512);
-    transpose4_ooff_simd256(x256+60,xtmpp+30,512);
-    transpose4_ooff_simd256(x256+62,xtmpp+31,512);
-    x256+=64;
-    xtmpp+=32;
-  }
-
-  dft4096((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  dft4096((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
-
-
-  for (i=0; i<512; i++) {
-    bfly2_256(ytmpp,ytmpp+512,
-	      y256p,y256p+512,
-	      tw8192_256p);
-    tw8192_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y256p = y256;
-
-    for (i=0; i<64; i++) {
-      y256p[0]  = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
-      y256p[1]  = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
-      y256p[2]  = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
-      y256p[3]  = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
-      y256p[4]  = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
-      y256p[5]  = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
-      y256p[6]  = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
-      y256p[7]  = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
-      y256p[8]  = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
-      y256p[9]  = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
-      y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
-      y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
-      y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
-      y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
-      y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
-      y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
-      y256p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft8192(int16_t *x,int16_t *y,int scale)
-{
-
-  simd256_q15_t xtmp[1024],*xtmpp,*x256 = (simd256_q15_t *)x;
-  simd256_q15_t ytmp[1024],*tw8192_256p=(simd256_q15_t *)tw8192,*y256=(simd256_q15_t *)y,*y256p=(simd256_q15_t *)y;
-  simd256_q15_t *ytmpp = &ytmp[0];
-  int i;
-  simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
-  
-  xtmpp = xtmp;
-
-  for (i=0; i<16; i++) {
-    transpose4_ooff_simd256(x256  ,xtmpp,512);
-    transpose4_ooff_simd256(x256+2,xtmpp+1,512);
-    transpose4_ooff_simd256(x256+4,xtmpp+2,512);
-    transpose4_ooff_simd256(x256+6,xtmpp+3,512);
-    transpose4_ooff_simd256(x256+8,xtmpp+4,512);
-    transpose4_ooff_simd256(x256+10,xtmpp+5,512);
-    transpose4_ooff_simd256(x256+12,xtmpp+6,512);
-    transpose4_ooff_simd256(x256+14,xtmpp+7,512);
-    transpose4_ooff_simd256(x256+16,xtmpp+8,512);
-    transpose4_ooff_simd256(x256+18,xtmpp+9,512);
-    transpose4_ooff_simd256(x256+20,xtmpp+10,512);
-    transpose4_ooff_simd256(x256+22,xtmpp+11,512);
-    transpose4_ooff_simd256(x256+24,xtmpp+12,512);
-    transpose4_ooff_simd256(x256+26,xtmpp+13,512);
-    transpose4_ooff_simd256(x256+28,xtmpp+14,512);
-    transpose4_ooff_simd256(x256+30,xtmpp+15,512);
-    transpose4_ooff_simd256(x256+32,xtmpp+16,512);
-    transpose4_ooff_simd256(x256+34,xtmpp+17,512);
-    transpose4_ooff_simd256(x256+36,xtmpp+18,512);
-    transpose4_ooff_simd256(x256+38,xtmpp+19,512);
-    transpose4_ooff_simd256(x256+40,xtmpp+20,512);
-    transpose4_ooff_simd256(x256+42,xtmpp+21,512);
-    transpose4_ooff_simd256(x256+44,xtmpp+22,512);
-    transpose4_ooff_simd256(x256+46,xtmpp+23,512);
-    transpose4_ooff_simd256(x256+48,xtmpp+24,512);
-    transpose4_ooff_simd256(x256+50,xtmpp+25,512);
-    transpose4_ooff_simd256(x256+52,xtmpp+26,512);
-    transpose4_ooff_simd256(x256+54,xtmpp+27,512);
-    transpose4_ooff_simd256(x256+56,xtmpp+28,512);
-    transpose4_ooff_simd256(x256+58,xtmpp+29,512);
-    transpose4_ooff_simd256(x256+60,xtmpp+30,512);
-    transpose4_ooff_simd256(x256+62,xtmpp+31,512);
-    x256+=64;
-    xtmpp+=32;
-  }
-
-  idft4096((int16_t*)(xtmp),(int16_t*)ytmp,1);
-  idft4096((int16_t*)(xtmp+512),(int16_t*)(ytmp+512),1);
-
-
-  for (i=0; i<512; i++) {
-    ibfly2_256(ytmpp,ytmpp+512,
-	       y256p,y256p+512,
-	       tw8192_256p);
-    tw8192_256p++;
-    y256p++;
-    ytmpp++;
-  }
-
-  if (scale>0) {
-    y256p = y256;
-
-    for (i=0; i<64; i++) {
-      y256p[0]  = mulhi_int16_simd256(y256p[0],ONE_OVER_SQRT2_Q15_128);
-      y256p[1]  = mulhi_int16_simd256(y256p[1],ONE_OVER_SQRT2_Q15_128);
-      y256p[2]  = mulhi_int16_simd256(y256p[2],ONE_OVER_SQRT2_Q15_128);
-      y256p[3]  = mulhi_int16_simd256(y256p[3],ONE_OVER_SQRT2_Q15_128);
-      y256p[4]  = mulhi_int16_simd256(y256p[4],ONE_OVER_SQRT2_Q15_128);
-      y256p[5]  = mulhi_int16_simd256(y256p[5],ONE_OVER_SQRT2_Q15_128);
-      y256p[6]  = mulhi_int16_simd256(y256p[6],ONE_OVER_SQRT2_Q15_128);
-      y256p[7]  = mulhi_int16_simd256(y256p[7],ONE_OVER_SQRT2_Q15_128);
-      y256p[8]  = mulhi_int16_simd256(y256p[8],ONE_OVER_SQRT2_Q15_128);
-      y256p[9]  = mulhi_int16_simd256(y256p[9],ONE_OVER_SQRT2_Q15_128);
-      y256p[10] = mulhi_int16_simd256(y256p[10],ONE_OVER_SQRT2_Q15_128);
-      y256p[11] = mulhi_int16_simd256(y256p[11],ONE_OVER_SQRT2_Q15_128);
-      y256p[12] = mulhi_int16_simd256(y256p[12],ONE_OVER_SQRT2_Q15_128);
-      y256p[13] = mulhi_int16_simd256(y256p[13],ONE_OVER_SQRT2_Q15_128);
-      y256p[14] = mulhi_int16_simd256(y256p[14],ONE_OVER_SQRT2_Q15_128);
-      y256p[15] = mulhi_int16_simd256(y256p[15],ONE_OVER_SQRT2_Q15_128);
-      y256p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-
-#endif
-
-int16_t twa1536[1024],twb1536[1024];
-
-// 512 x 3
-void idft1536(int16_t *input, int16_t *output, int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][512 ]__attribute__((aligned(32)));
-  uint32_t tmpo[3][512] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<512; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  idft512((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  idft512((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  idft512((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  for (i=0,i2=0; i<1024; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i),
-          (simd_q15_t*)(twa1536+i),(simd_q15_t*)(twb1536+i));
-  }
-
-
-  if (scale==1) {
-    for (i=0; i<24; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-void dft1536(int16_t *input, int16_t *output, int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][512] __attribute__((aligned(32)));
-  uint32_t tmpo[3][512] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<512; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft512((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  dft512((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  dft512((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  /*
-  for (i=1; i<512; i++) {
-    tmpo[0][i] = tmpo[0][i<<1];
-    tmpo[1][i] = tmpo[1][i<<1];
-    tmpo[2][i] = tmpo[2][i<<1];
-    }*/
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1);
-    LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1);
-    LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1);
-  }
-  for (i=0,i2=0; i<1024; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i),
-          (simd_q15_t*)(twa1536+i),(simd_q15_t*)(twb1536+i));
-  }
-
-  if (scale==1) {
-    for (i=0; i<24; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-int16_t twa3072[2048] __attribute__((aligned(32)));
-int16_t twb3072[2048] __attribute__((aligned(32)));
-// 1024 x 3
-void dft3072(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][1024] __attribute__((aligned(32)));
-  uint32_t tmpo[3][1024] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<1024; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft1024((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  dft1024((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  dft1024((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  for (i=0,i2=0; i<2048; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+2048+i),(simd_q15_t*)(output+4096+i),
-          (simd_q15_t*)(twa3072+i),(simd_q15_t*)(twb3072+i));
-  }
-
-  if (scale==1) {
-    for (i=0; i<48; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-}
-
-void idft3072(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][1024]__attribute__((aligned(32)));
-  uint32_t tmpo[3][1024] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<1024; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-  idft1024((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  idft1024((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  idft1024((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  for (i=0,i2=0; i<2048; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+2048+i),(simd_q15_t*)(output+4096+i),
-          (simd_q15_t*)(twa3072+i),(simd_q15_t*)(twb3072+i));
-  }
-
-
-  if (scale==1) {
-    for (i=0; i<48; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-}
-
-
-int16_t twa6144[4096] __attribute__((aligned(32)));
-int16_t twb6144[4096] __attribute__((aligned(32)));
-
-void idft6144(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][2048] __attribute__((aligned(32)));
-  uint32_t tmpo[3][2048] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<2048; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  idft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("idft6144in.m","in",input,6144,1,1);
-    LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1);
-    LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1);
-    LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1);
-  }
-
-  for (i=0,i2=0; i<4096; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
-	   (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
-	   (simd_q15_t*)(twa6144+i),(simd_q15_t*)(twb6144+i));
-  }
-
-
-  if (scale==1) {
-    for (i=0; i<96; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-
-void dft6144(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][2048] __attribute__((aligned(32)));
-  uint32_t tmpo[3][2048] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<2048; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  dft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  dft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-
-  /*
-  for (i=1; i<2048; i++) {
-    tmpo[0][i] = tmpo[0][i<<1];
-    tmpo[1][i] = tmpo[1][i<<1];
-    tmpo[2][i] = tmpo[2][i<<1];
-    }*/
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1);
-    LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1);
-    LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1);
-  }
-  for (i=0,i2=0; i<4096; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
-          (simd_q15_t*)(twa6144+i),(simd_q15_t*)(twb6144+i));
-  }
-
-  if (scale==1) {
-    for (i=0; i<96; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-
-}
-
-int16_t twa9216[6144] __attribute__((aligned(32)));
-int16_t twb9216[6144] __attribute__((aligned(32)));
-// 3072 x 3
-void dft9216(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-void idft9216(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-int16_t twa12288[8192] __attribute__((aligned(32)));
-int16_t twb12288[8192] __attribute__((aligned(32)));
-// 4096 x 3
-void dft12288(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][4096] __attribute__((aligned(32)));
-  uint32_t tmpo[3][4096] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<4096; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
-  dft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
-  dft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
-  /*
-  for (i=1; i<4096; i++) {
-    tmpo[0][i] = tmpo[0][i<<1];
-    tmpo[1][i] = tmpo[1][i<<1];
-    tmpo[2][i] = tmpo[2][i<<1];
-    }*/
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1);
-    LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1);
-    LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1);
-  }
-  for (i=0,i2=0; i<8192; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
-          (simd_q15_t*)(twa12288+i),(simd_q15_t*)(twb12288+i));
-  }
-
-  if (scale==1) {
-    for (i=0; i<192; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-
-}
-
-void idft12288(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][4096] __attribute__((aligned(32)));
-  uint32_t tmpo[3][4096] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<4096; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-
-
-  idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
-  idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
-  idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
-
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("idft12288in.m","in",input,12288,1,1);
-    LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1);
-    LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1);
-    LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1);
-  }
-
-  for (i=0,i2=0; i<8192; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
-          (simd_q15_t*)(twa12288+i),(simd_q15_t*)(twb12288+i));
-  }
-
-  if (scale==1) {
-    for (i=0; i<192; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-     LOG_M("idft12288out.m","out",output,6144,1,1);
-  }
-}
-
-int16_t twa18432[12288] __attribute__((aligned(32)));
-int16_t twb18432[12288] __attribute__((aligned(32)));
-// 6144 x 3
-void dft18432(int16_t *input, int16_t *output,int scale) {
-
-  int i,i2,j;
-  uint32_t tmp[3][6144] __attribute__((aligned(32)));
-  uint32_t tmpo[3][6144] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<6144; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft6144((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
-  dft6144((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
-  dft6144((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
-
-  for (i=0,i2=0; i<12288; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+12288+i),(simd_q15_t*)(output+24576+i),
-          (simd_q15_t*)(twa18432+i),(simd_q15_t*)(twb18432+i));
-  }
-  if (scale==1) {
-    for (i=0; i<288; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-}
-
-void idft18432(int16_t *input, int16_t *output,int scale) {
-
-  int i,i2,j;
-  uint32_t tmp[3][6144] __attribute__((aligned(32)));
-  uint32_t tmpo[3][6144] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<6144; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  idft6144((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
-  idft6144((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
-  idft6144((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
-
-  for (i=0,i2=0; i<12288; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-	   (simd_q15_t*)(output+i),(simd_q15_t*)(output+12288+i),(simd_q15_t*)(output+24576+i),
-	   (simd_q15_t*)(twa18432+i),(simd_q15_t*)(twb18432+i));
-  }
-  if (scale==1) {
-    for (i=0; i<288; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-}
-
-
-int16_t twa24576[16384] __attribute__((aligned(32)));
-int16_t twb24576[16384] __attribute__((aligned(32)));
-// 8192 x 3
-void dft24576(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][8192] __attribute__((aligned(32)));
-  uint32_t tmpo[3][8192] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<8192; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  dft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  dft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  dft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-  /*
-  for (i=1; i<8192; i++) {
-    tmpo[0][i] = tmpo[0][i<<1];
-    tmpo[1][i] = tmpo[1][i<<1];
-    tmpo[2][i] = tmpo[2][i<<1];
-    }*/
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1);
-    LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1);
-    LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1);
-  }
-  for (i=0,i2=0; i<16384; i+=8,i2+=4)  {
-    bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
-          (simd_q15_t*)(twa24576+i),(simd_q15_t*)(twb24576+i));
-  }
-
-
-  if (scale==1) {
-    for (i=0; i<384; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-     LOG_M("out.m","out",output,24576,1,1);
-  }
-}
-
-void idft24576(int16_t *input, int16_t *output,int scale)
-{
-  int i,i2,j;
-  uint32_t tmp[3][8192] __attribute__((aligned(32)));
-  uint32_t tmpo[3][8192] __attribute__((aligned(32)));
-  simd_q15_t *y128p=(simd_q15_t*)output;
-  simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
-
-  for (i=0,j=0; i<8192; i++) {
-    tmp[0][i] = ((uint32_t *)input)[j++];
-    tmp[1][i] = ((uint32_t *)input)[j++];
-    tmp[2][i] = ((uint32_t *)input)[j++];
-  }
-
-  idft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
-  idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
-  idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
-  
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("idft24576in.m","in",input,24576,1,1);
-    LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1);
-    LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1);
-    LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1);
-  }
-
-  for (i=0,i2=0; i<16384; i+=8,i2+=4)  {
-    ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
-          (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
-          (simd_q15_t*)(twa24576+i),(simd_q15_t*)(twb24576+i));
-  }
-  if (scale==1) {
-    for (i=0; i<384; i++) {
-      y128p[0]  = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
-      y128p[1]  = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
-      y128p[2]  = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
-      y128p[3]  = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
-      y128p[4]  = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
-      y128p[5]  = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
-      y128p[6]  = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
-      y128p[7]  = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
-      y128p[8]  = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
-      y128p[9]  = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
-      y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
-      y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
-      y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
-      y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
-      y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
-      y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
-      y128p+=16;
-    }
-  }
-  _mm_empty();
-  _m_empty();
-
-  if (LOG_DUMPFLAG(DEBUG_DFT)) {
-    LOG_M("idft24576out.m","out",output,24576,1,1);
-  }
-}
-
-int16_t twa36864[24576] __attribute__((aligned(32)));
-int16_t twb36884[24576] __attribute__((aligned(32)));
-// 12288 x 3
-void dft36864(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-void idft36864(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-int16_t twa49152[32768] __attribute__((aligned(32)));
-int16_t twb49152[32768] __attribute__((aligned(32)));
-// 16384 x 3
-void dft49152(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-void idft49152(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-int16_t twa73728[49152] __attribute__((aligned(32)));
-int16_t twb73728[49152] __attribute__((aligned(32)));
-// 24576 x 3
-void dft73728(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-void idft73728(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-
-int16_t twa98304[49152] __attribute__((aligned(32)));
-int16_t twb98304[49152] __attribute__((aligned(32)));
-// 32768 x 3
-void dft98304(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
-void idft98304(int16_t *input, int16_t *output,int scale) {
-
-  AssertFatal(1==0,"Need to do this ..\n");
-}
-
- 
-///  THIS SECTION IS FOR ALL PUSCH DFTS (i.e. radix 2^a * 3^b * 4^c * 5^d)
-///  They use twiddles for 4-way parallel DFTS (i.e. 4 DFTS with interleaved input/output)
-
-static int16_t W1_12s[8]__attribute__((aligned(32))) = {28377,-16383,28377,-16383,28377,-16383,28377,-16383};
-static int16_t W2_12s[8]__attribute__((aligned(32))) = {16383,-28377,16383,-28377,16383,-28377,16383,-28377};
-static int16_t W3_12s[8]__attribute__((aligned(32))) = {0,-32767,0,-32767,0,-32767,0,-32767};
-static int16_t W4_12s[8]__attribute__((aligned(32))) = {-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377};
-static int16_t W6_12s[8]__attribute__((aligned(32))) = {-32767,0,-32767,0,-32767,0,-32767,0};
-
-simd_q15_t *W1_12=(simd_q15_t *)W1_12s;
-simd_q15_t *W2_12=(simd_q15_t *)W2_12s;
-simd_q15_t *W3_12=(simd_q15_t *)W3_12s;
-simd_q15_t *W4_12=(simd_q15_t *)W4_12s;
-simd_q15_t *W6_12=(simd_q15_t *)W6_12s;
-
-
-static simd_q15_t norm128;
-
-static inline void dft12f(simd_q15_t *x0,
-                          simd_q15_t *x1,
-                          simd_q15_t *x2,
-                          simd_q15_t *x3,
-                          simd_q15_t *x4,
-                          simd_q15_t *x5,
-                          simd_q15_t *x6,
-                          simd_q15_t *x7,
-                          simd_q15_t *x8,
-                          simd_q15_t *x9,
-                          simd_q15_t *x10,
-                          simd_q15_t *x11,
-                          simd_q15_t *y0,
-                          simd_q15_t *y1,
-                          simd_q15_t *y2,
-                          simd_q15_t *y3,
-                          simd_q15_t *y4,
-                          simd_q15_t *y5,
-                          simd_q15_t *y6,
-                          simd_q15_t *y7,
-                          simd_q15_t *y8,
-                          simd_q15_t *y9,
-                          simd_q15_t *y10,
-                          simd_q15_t *y11) __attribute__((always_inline));
-
-static inline void dft12f(simd_q15_t *x0,
-                          simd_q15_t *x1,
-                          simd_q15_t *x2,
-                          simd_q15_t *x3,
-                          simd_q15_t *x4,
-                          simd_q15_t *x5,
-                          simd_q15_t *x6,
-                          simd_q15_t *x7,
-                          simd_q15_t *x8,
-                          simd_q15_t *x9,
-                          simd_q15_t *x10,
-                          simd_q15_t *x11,
-                          simd_q15_t *y0,
-                          simd_q15_t *y1,
-                          simd_q15_t *y2,
-                          simd_q15_t *y3,
-                          simd_q15_t *y4,
-                          simd_q15_t *y5,
-                          simd_q15_t *y6,
-                          simd_q15_t *y7,
-                          simd_q15_t *y8,
-                          simd_q15_t *y9,
-                          simd_q15_t *y10,
-                          simd_q15_t *y11)
-{
-
-
-  simd_q15_t tmp_dft12[12];
-
-  simd_q15_t *tmp_dft12_ptr = &tmp_dft12[0];
-
-  // msg("dft12\n");
-
-  bfly4_tw1(x0,
-            x3,
-            x6,
-            x9,
-            tmp_dft12_ptr,
-            tmp_dft12_ptr+3,
-            tmp_dft12_ptr+6,
-            tmp_dft12_ptr+9);
-
-
-  bfly4_tw1(x1,
-            x4,
-            x7,
-            x10,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+4,
-            tmp_dft12_ptr+7,
-            tmp_dft12_ptr+10);
-
-
-  bfly4_tw1(x2,
-            x5,
-            x8,
-            x11,
-            tmp_dft12_ptr+2,
-            tmp_dft12_ptr+5,
-            tmp_dft12_ptr+8,
-            tmp_dft12_ptr+11);
-
-  //  k2=0;
-  bfly3_tw1(tmp_dft12_ptr,
-            tmp_dft12_ptr+1,
-            tmp_dft12_ptr+2,
-            y0,
-            y4,
-            y8);
-
-
-
-  //  k2=1;
-  bfly3(tmp_dft12_ptr+3,
-        tmp_dft12_ptr+4,
-        tmp_dft12_ptr+5,
-        y1,
-        y5,
-        y9,
-        W1_12,
-        W2_12);
-
-
-
-  //  k2=2;
-  bfly3(tmp_dft12_ptr+6,
-        tmp_dft12_ptr+7,
-        tmp_dft12_ptr+8,
-        y2,
-        y6,
-        y10,
-        W2_12,
-        W4_12);
-
-  //  k2=3;
-  bfly3(tmp_dft12_ptr+9,
-        tmp_dft12_ptr+10,
-        tmp_dft12_ptr+11,
-        y3,
-        y7,
-        y11,
-        W3_12,
-        W6_12);
-
-}
-
-
-
-
-void dft12(int16_t *x,int16_t *y)
-{
-
-  simd_q15_t *x128 = (simd_q15_t *)x,*y128 = (simd_q15_t *)y;
-  dft12f(&x128[0],
-         &x128[1],
-         &x128[2],
-         &x128[3],
-         &x128[4],
-         &x128[5],
-         &x128[6],
-         &x128[7],
-         &x128[8],
-         &x128[9],
-         &x128[10],
-         &x128[11],
-         &y128[0],
-         &y128[1],
-         &y128[2],
-         &y128[3],
-         &y128[4],
-         &y128[5],
-         &y128[6],
-         &y128[7],
-         &y128[8],
-         &y128[9],
-         &y128[10],
-         &y128[11]);
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-#ifdef __AVX2__
-
-static int16_t W1_12s_256[16]__attribute__((aligned(32))) = {28377,-16383,28377,-16383,28377,-16383,28377,-16383,28377,-16383,28377,-16383,28377,-16383,28377,-16383};
-static int16_t W2_12s_256[16]__attribute__((aligned(32))) = {16383,-28377,16383,-28377,16383,-28377,16383,-28377,16383,-28377,16383,-28377,16383,-28377,16383,-28377};
-static int16_t W3_12s_256[16]__attribute__((aligned(32))) = {0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767};
-static int16_t W4_12s_256[16]__attribute__((aligned(32))) = {-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377,-16383,-28377};
-static int16_t W6_12s_256[16]__attribute__((aligned(32))) = {-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0,-32767,0};
-
-simd256_q15_t *W1_12_256=(simd256_q15_t *)W1_12s_256;
-simd256_q15_t *W2_12_256=(simd256_q15_t *)W2_12s_256;
-simd256_q15_t *W3_12_256=(simd256_q15_t *)W3_12s_256;
-simd256_q15_t *W4_12_256=(simd256_q15_t *)W4_12s_256;
-simd256_q15_t *W6_12_256=(simd256_q15_t *)W6_12s_256;
-
-
-
-static inline void dft12f_simd256(simd256_q15_t *x0,
-				  simd256_q15_t *x1,
-				  simd256_q15_t *x2,
-				  simd256_q15_t *x3,
-				  simd256_q15_t *x4,
-				  simd256_q15_t *x5,
-				  simd256_q15_t *x6,
-				  simd256_q15_t *x7,
-				  simd256_q15_t *x8,
-				  simd256_q15_t *x9,
-				  simd256_q15_t *x10,
-				  simd256_q15_t *x11,
-				  simd256_q15_t *y0,
-				  simd256_q15_t *y1,
-				  simd256_q15_t *y2,
-				  simd256_q15_t *y3,
-				  simd256_q15_t *y4,
-				  simd256_q15_t *y5,
-				  simd256_q15_t *y6,
-				  simd256_q15_t *y7,
-				  simd256_q15_t *y8,
-				  simd256_q15_t *y9,
-				  simd256_q15_t *y10,
-				  simd256_q15_t *y11) __attribute__((always_inline));
-
-static inline void dft12f_simd256(simd256_q15_t *x0,
-				  simd256_q15_t *x1,
-				  simd256_q15_t *x2,
-				  simd256_q15_t *x3,
-				  simd256_q15_t *x4,
-				  simd256_q15_t *x5,
-				  simd256_q15_t *x6,
-				  simd256_q15_t *x7,
-				  simd256_q15_t *x8,
-				  simd256_q15_t *x9,
-				  simd256_q15_t *x10,
-				  simd256_q15_t *x11,
-				  simd256_q15_t *y0,
-				  simd256_q15_t *y1,
-				  simd256_q15_t *y2,
-				  simd256_q15_t *y3,
-				  simd256_q15_t *y4,
-				  simd256_q15_t *y5,
-				  simd256_q15_t *y6,
-				  simd256_q15_t *y7,
-				  simd256_q15_t *y8,
-				  simd256_q15_t *y9,
-				  simd256_q15_t *y10,
-				  simd256_q15_t *y11)
-{
-
-
-  simd256_q15_t tmp_dft12[12];
-
-  simd256_q15_t *tmp_dft12_ptr = &tmp_dft12[0];
-
-  // msg("dft12\n");
-
-  bfly4_tw1_256(x0,
-		x3,
-		x6,
-		x9,
-		tmp_dft12_ptr,
-		tmp_dft12_ptr+3,
-		tmp_dft12_ptr+6,
-		tmp_dft12_ptr+9);
-
-
-  bfly4_tw1_256(x1,
-		x4,
-		x7,
-		x10,
-		tmp_dft12_ptr+1,
-		tmp_dft12_ptr+4,
-		tmp_dft12_ptr+7,
-		tmp_dft12_ptr+10);
-  
-
-  bfly4_tw1_256(x2,
-		x5,
-		x8,
-		x11,
-		tmp_dft12_ptr+2,
-		tmp_dft12_ptr+5,
-		tmp_dft12_ptr+8,
-		tmp_dft12_ptr+11);
-  
-  //  k2=0;
-  bfly3_tw1_256(tmp_dft12_ptr,
-		tmp_dft12_ptr+1,
-		tmp_dft12_ptr+2,
-		y0,
-		y4,
-		y8);
-  
-  
-  
-  //  k2=1;
-  bfly3_256(tmp_dft12_ptr+3,
-	    tmp_dft12_ptr+4,
-	    tmp_dft12_ptr+5,
-	    y1,
-	    y5,
-	    y9,
-	    W1_12_256,
-	    W2_12_256);
-  
-  
-  
-  //  k2=2;
-  bfly3_256(tmp_dft12_ptr+6,
-	    tmp_dft12_ptr+7,
-	    tmp_dft12_ptr+8,
-	    y2,
-	    y6,
-	    y10,
-	    W2_12_256,
-	    W4_12_256);
-  
-  //  k2=3;
-  bfly3_256(tmp_dft12_ptr+9,
-	    tmp_dft12_ptr+10,
-	    tmp_dft12_ptr+11,
-	    y3,
-	    y7,
-	    y11,
-	    W3_12_256,
-	    W6_12_256);
-  
-}
-
-
-
-
-void dft12_simd256(int16_t *x,int16_t *y)
-{
-
-  simd256_q15_t *x256 = (simd256_q15_t *)x,*y256 = (simd256_q15_t *)y;
-  dft12f_simd256(&x256[0],
-		 &x256[1],
-		 &x256[2],
-		 &x256[3],
-		 &x256[4],
-		 &x256[5],
-		 &x256[6],
-		 &x256[7],
-		 &x256[8],
-		 &x256[9],
-		 &x256[10],
-		 &x256[11],
-		 &y256[0],
-		 &y256[1],
-		 &y256[2],
-		 &y256[3],
-		 &y256[4],
-		 &y256[5],
-		 &y256[6],
-		 &y256[7],
-		 &y256[8],
-		 &y256[9],
-		 &y256[10],
-		 &y256[11]);
-  
-  _mm_empty();
-  _m_empty();
-
-}
-
-#endif
-
-static int16_t tw24[88]__attribute__((aligned(32)));
-
-void dft24(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *tw128=(simd_q15_t *)&tw24[0];
-  simd_q15_t ytmp128[24];//=&ytmp128array[0];
-  int i,j,k;
-
-  //  msg("dft24\n");
-  dft12f(x128,
-         x128+2,
-         x128+4,
-         x128+6,
-         x128+8,
-         x128+10,
-         x128+12,
-         x128+14,
-         x128+16,
-         x128+18,
-         x128+20,
-         x128+22,
-         ytmp128,
-         ytmp128+2,
-         ytmp128+4,
-         ytmp128+6,
-         ytmp128+8,
-         ytmp128+10,
-         ytmp128+12,
-         ytmp128+14,
-         ytmp128+16,
-         ytmp128+18,
-         ytmp128+20,
-         ytmp128+22);
-  //  msg("dft24b\n");
-
-  dft12f(x128+1,
-         x128+3,
-         x128+5,
-         x128+7,
-         x128+9,
-         x128+11,
-         x128+13,
-         x128+15,
-         x128+17,
-         x128+19,
-         x128+21,
-         x128+23,
-         ytmp128+1,
-         ytmp128+3,
-         ytmp128+5,
-         ytmp128+7,
-         ytmp128+9,
-         ytmp128+11,
-         ytmp128+13,
-         ytmp128+15,
-         ytmp128+17,
-         ytmp128+19,
-         ytmp128+21,
-         ytmp128+23);
-
-  //  msg("dft24c\n");
-
-  bfly2_tw1(ytmp128,
-            ytmp128+1,
-            y128,
-            y128+12);
-
-  //  msg("dft24d\n");
-
-  for (i=2,j=1,k=0; i<24; i+=2,j++,k++) {
-
-    bfly2(ytmp128+i,
-          ytmp128+i+1,
-          y128+j,
-          y128+j+12,
-          tw128+k);
-    //    msg("dft24e\n");
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[1]);
-
-    for (i=0; i<24; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa36[88]__attribute__((aligned(32)));
-static int16_t twb36[88]__attribute__((aligned(32)));
-
-void dft36(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa36[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb36[0];
-  simd_q15_t ytmp128[36];//&ytmp128array[0];
-
-
-  int i,j,k;
-
-  dft12f(x128,
-         x128+3,
-         x128+6,
-         x128+9,
-         x128+12,
-         x128+15,
-         x128+18,
-         x128+21,
-         x128+24,
-         x128+27,
-         x128+30,
-         x128+33,
-         ytmp128,
-         ytmp128+3,
-         ytmp128+6,
-         ytmp128+9,
-         ytmp128+12,
-         ytmp128+15,
-         ytmp128+18,
-         ytmp128+21,
-         ytmp128+24,
-         ytmp128+27,
-         ytmp128+30,
-         ytmp128+33);
-
-  dft12f(x128+1,
-         x128+4,
-         x128+7,
-         x128+10,
-         x128+13,
-         x128+16,
-         x128+19,
-         x128+22,
-         x128+25,
-         x128+28,
-         x128+31,
-         x128+34,
-         ytmp128+1,
-         ytmp128+4,
-         ytmp128+7,
-         ytmp128+10,
-         ytmp128+13,
-         ytmp128+16,
-         ytmp128+19,
-         ytmp128+22,
-         ytmp128+25,
-         ytmp128+28,
-         ytmp128+31,
-         ytmp128+34);
-
-  dft12f(x128+2,
-         x128+5,
-         x128+8,
-         x128+11,
-         x128+14,
-         x128+17,
-         x128+20,
-         x128+23,
-         x128+26,
-         x128+29,
-         x128+32,
-         x128+35,
-         ytmp128+2,
-         ytmp128+5,
-         ytmp128+8,
-         ytmp128+11,
-         ytmp128+14,
-         ytmp128+17,
-         ytmp128+20,
-         ytmp128+23,
-         ytmp128+26,
-         ytmp128+29,
-         ytmp128+32,
-         ytmp128+35);
-
-
-  bfly3_tw1(ytmp128,
-            ytmp128+1,
-            ytmp128+2,
-            y128,
-            y128+12,
-            y128+24);
-
-  for (i=3,j=1,k=0; i<36; i+=3,j++,k++) {
-
-    bfly3(ytmp128+i,
-          ytmp128+i+1,
-          ytmp128+i+2,
-          y128+j,
-          y128+j+12,
-          y128+j+24,
-          twa128+k,
-          twb128+k);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[2]);
-
-    for (i=0; i<36; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa48[88]__attribute__((aligned(32)));
-static int16_t twb48[88]__attribute__((aligned(32)));
-static int16_t twc48[88]__attribute__((aligned(32)));
-
-void dft48(int16_t *x, int16_t *y,unsigned char scale_flag)
-{
-
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa48[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb48[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc48[0];
-  simd_q15_t ytmp128[48];//=&ytmp128array[0];
-  int i,j,k;
-
-
-  dft12f(x128,
-         x128+4,
-         x128+8,
-         x128+12,
-         x128+16,
-         x128+20,
-         x128+24,
-         x128+28,
-         x128+32,
-         x128+36,
-         x128+40,
-         x128+44,
-         ytmp128,
-         ytmp128+4,
-         ytmp128+8,
-         ytmp128+12,
-         ytmp128+16,
-         ytmp128+20,
-         ytmp128+24,
-         ytmp128+28,
-         ytmp128+32,
-         ytmp128+36,
-         ytmp128+40,
-         ytmp128+44);
-
-
-  dft12f(x128+1,
-         x128+5,
-         x128+9,
-         x128+13,
-         x128+17,
-         x128+21,
-         x128+25,
-         x128+29,
-         x128+33,
-         x128+37,
-         x128+41,
-         x128+45,
-         ytmp128+1,
-         ytmp128+5,
-         ytmp128+9,
-         ytmp128+13,
-         ytmp128+17,
-         ytmp128+21,
-         ytmp128+25,
-         ytmp128+29,
-         ytmp128+33,
-         ytmp128+37,
-         ytmp128+41,
-         ytmp128+45);
-
-
-  dft12f(x128+2,
-         x128+6,
-         x128+10,
-         x128+14,
-         x128+18,
-         x128+22,
-         x128+26,
-         x128+30,
-         x128+34,
-         x128+38,
-         x128+42,
-         x128+46,
-         ytmp128+2,
-         ytmp128+6,
-         ytmp128+10,
-         ytmp128+14,
-         ytmp128+18,
-         ytmp128+22,
-         ytmp128+26,
-         ytmp128+30,
-         ytmp128+34,
-         ytmp128+38,
-         ytmp128+42,
-         ytmp128+46);
-
-
-  dft12f(x128+3,
-         x128+7,
-         x128+11,
-         x128+15,
-         x128+19,
-         x128+23,
-         x128+27,
-         x128+31,
-         x128+35,
-         x128+39,
-         x128+43,
-         x128+47,
-         ytmp128+3,
-         ytmp128+7,
-         ytmp128+11,
-         ytmp128+15,
-         ytmp128+19,
-         ytmp128+23,
-         ytmp128+27,
-         ytmp128+31,
-         ytmp128+35,
-         ytmp128+39,
-         ytmp128+43,
-         ytmp128+47);
-
-
-
-  bfly4_tw1(ytmp128,
-            ytmp128+1,
-            ytmp128+2,
-            ytmp128+3,
-            y128,
-            y128+12,
-            y128+24,
-            y128+36);
-
-
-
-  for (i=4,j=1,k=0; i<48; i+=4,j++,k++) {
-
-    bfly4(ytmp128+i,
-          ytmp128+i+1,
-          ytmp128+i+2,
-          ytmp128+i+3,
-          y128+j,
-          y128+j+12,
-          y128+j+24,
-          y128+j+36,
-          twa128+k,
-          twb128+k,
-          twc128+k);
-
-  }
-
-  if (scale_flag == 1) {
-    norm128 = set1_int16(dft_norm_table[3]);
-
-    for (i=0; i<48; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa60[88]__attribute__((aligned(32)));
-static int16_t twb60[88]__attribute__((aligned(32)));
-static int16_t twc60[88]__attribute__((aligned(32)));
-static int16_t twd60[88]__attribute__((aligned(32)));
-
-void dft60(int16_t *x,int16_t *y,unsigned char scale)
-{
-
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa60[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb60[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc60[0];
-  simd_q15_t *twd128=(simd_q15_t *)&twd60[0];
-  simd_q15_t ytmp128[60];//=&ytmp128array[0];
-  int i,j,k;
-
-  dft12f(x128,
-         x128+5,
-         x128+10,
-         x128+15,
-         x128+20,
-         x128+25,
-         x128+30,
-         x128+35,
-         x128+40,
-         x128+45,
-         x128+50,
-         x128+55,
-         ytmp128,
-         ytmp128+5,
-         ytmp128+10,
-         ytmp128+15,
-         ytmp128+20,
-         ytmp128+25,
-         ytmp128+30,
-         ytmp128+35,
-         ytmp128+40,
-         ytmp128+45,
-         ytmp128+50,
-         ytmp128+55);
-
-  dft12f(x128+1,
-         x128+6,
-         x128+11,
-         x128+16,
-         x128+21,
-         x128+26,
-         x128+31,
-         x128+36,
-         x128+41,
-         x128+46,
-         x128+51,
-         x128+56,
-         ytmp128+1,
-         ytmp128+6,
-         ytmp128+11,
-         ytmp128+16,
-         ytmp128+21,
-         ytmp128+26,
-         ytmp128+31,
-         ytmp128+36,
-         ytmp128+41,
-         ytmp128+46,
-         ytmp128+51,
-         ytmp128+56);
-
-  dft12f(x128+2,
-         x128+7,
-         x128+12,
-         x128+17,
-         x128+22,
-         x128+27,
-         x128+32,
-         x128+37,
-         x128+42,
-         x128+47,
-         x128+52,
-         x128+57,
-         ytmp128+2,
-         ytmp128+7,
-         ytmp128+12,
-         ytmp128+17,
-         ytmp128+22,
-         ytmp128+27,
-         ytmp128+32,
-         ytmp128+37,
-         ytmp128+42,
-         ytmp128+47,
-         ytmp128+52,
-         ytmp128+57);
-
-  dft12f(x128+3,
-         x128+8,
-         x128+13,
-         x128+18,
-         x128+23,
-         x128+28,
-         x128+33,
-         x128+38,
-         x128+43,
-         x128+48,
-         x128+53,
-         x128+58,
-         ytmp128+3,
-         ytmp128+8,
-         ytmp128+13,
-         ytmp128+18,
-         ytmp128+23,
-         ytmp128+28,
-         ytmp128+33,
-         ytmp128+38,
-         ytmp128+43,
-         ytmp128+48,
-         ytmp128+53,
-         ytmp128+58);
-
-  dft12f(x128+4,
-         x128+9,
-         x128+14,
-         x128+19,
-         x128+24,
-         x128+29,
-         x128+34,
-         x128+39,
-         x128+44,
-         x128+49,
-         x128+54,
-         x128+59,
-         ytmp128+4,
-         ytmp128+9,
-         ytmp128+14,
-         ytmp128+19,
-         ytmp128+24,
-         ytmp128+29,
-         ytmp128+34,
-         ytmp128+39,
-         ytmp128+44,
-         ytmp128+49,
-         ytmp128+54,
-         ytmp128+59);
-
-  bfly5_tw1(ytmp128,
-            ytmp128+1,
-            ytmp128+2,
-            ytmp128+3,
-            ytmp128+4,
-            y128,
-            y128+12,
-            y128+24,
-            y128+36,
-            y128+48);
-
-  for (i=5,j=1,k=0; i<60; i+=5,j++,k++) {
-
-    bfly5(ytmp128+i,
-          ytmp128+i+1,
-          ytmp128+i+2,
-          ytmp128+i+3,
-          ytmp128+i+4,
-          y128+j,
-          y128+j+12,
-          y128+j+24,
-          y128+j+36,
-          y128+j+48,
-          twa128+k,
-          twb128+k,
-          twc128+k,
-          twd128+k);
-  }
-
-  if (scale == 1) {
-    norm128 = set1_int16(dft_norm_table[4]);
-
-    for (i=0; i<60; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-//      printf("y[%d] = (%d,%d)\n",i,((int16_t*)&y128[i])[0],((int16_t*)&y128[i])[1]);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t tw72[280]__attribute__((aligned(32)));
-
-void dft72(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *tw128=(simd_q15_t *)&tw72[0];
-  simd_q15_t x2128[72];// = (simd_q15_t *)&x2128array[0];
-
-  simd_q15_t ytmp128[72];//=&ytmp128array2[0];
-
-  for (i=0,j=0; i<36; i++,j+=2) {
-    x2128[i]    = x128[j];    // even inputs
-    x2128[i+36] = x128[j+1];  // odd inputs
-  }
-
-  dft36((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft36((int16_t *)(x2128+36),(int16_t *)(ytmp128+36),1);
-
-  bfly2_tw1(ytmp128,ytmp128+36,y128,y128+36);
-
-  for (i=1,j=0; i<36; i++,j++) {
-    bfly2(ytmp128+i,
-          ytmp128+36+i,
-          y128+i,
-          y128+36+i,
-          tw128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[5]);
-
-    for (i=0; i<72; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t tw96[376]__attribute__((aligned(32)));
-
-void dft96(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *tw128=(simd_q15_t *)&tw96[0];
-  simd_q15_t x2128[96];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[96];//=&ytmp128array2[0];
-
-
-  for (i=0,j=0; i<48; i++,j+=2) {
-    x2128[i]    = x128[j];
-    x2128[i+48] = x128[j+1];
-  }
-
-  dft48((int16_t *)x2128,(int16_t *)ytmp128,0);
-  dft48((int16_t *)(x2128+48),(int16_t *)(ytmp128+48),0);
-
-
-  bfly2_tw1(ytmp128,ytmp128+48,y128,y128+48);
-
-  for (i=1,j=0; i<48; i++,j++) {
-    bfly2(ytmp128+i,
-          ytmp128+48+i,
-          y128+i,
-          y128+48+i,
-          tw128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[6]);
-
-    for (i=0; i<96; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa108[280]__attribute__((aligned(32)));
-static int16_t twb108[280]__attribute__((aligned(32)));
-
-void dft108(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa108[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb108[0];
-  simd_q15_t x2128[108];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[108];//=&ytmp128array2[0];
-
-
-  for (i=0,j=0; i<36; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+36] = x128[j+1];
-    x2128[i+72] = x128[j+2];
-  }
-
-  dft36((int16_t *)x2128,(int16_t *)ytmp128,0);
-  dft36((int16_t *)(x2128+36),(int16_t *)(ytmp128+36),0);
-  dft36((int16_t *)(x2128+72),(int16_t *)(ytmp128+72),0);
-
-  bfly3_tw1(ytmp128,ytmp128+36,ytmp128+72,y128,y128+36,y128+72);
-
-  for (i=1,j=0; i<36; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+36+i,
-          ytmp128+72+i,
-          y128+i,
-          y128+36+i,
-          y128+72+i,
-          twa128+j,
-          twb128+j);
-
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[7]);
-
-    for (i=0; i<108; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t tw120[472]__attribute__((aligned(32)));
-void dft120(int16_t *x,int16_t *y, unsigned char scale_flag)
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *tw128=(simd_q15_t *)&tw120[0];
-  simd_q15_t x2128[120];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[120];//=&ytmp128array2[0];
-
-  for (i=0,j=0; i<60; i++,j+=2) {
-    x2128[i]    = x128[j];
-    x2128[i+60] = x128[j+1];
-  }
-
-  dft60((int16_t *)x2128,(int16_t *)ytmp128,0);
-  dft60((int16_t *)(x2128+60),(int16_t *)(ytmp128+60),0);
-
-
-  bfly2_tw1(ytmp128,ytmp128+60,y128,y128+60);
-
-  for (i=1,j=0; i<60; i++,j++) {
-    bfly2(ytmp128+i,
-          ytmp128+60+i,
-          y128+i,
-          y128+60+i,
-          tw128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[8]);
-
-    for (i=0; i<120; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa144[376]__attribute__((aligned(32)));
-static int16_t twb144[376]__attribute__((aligned(32)));
-
-void dft144(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa144[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb144[0];
-  simd_q15_t x2128[144];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[144];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<48; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+48] = x128[j+1];
-    x2128[i+96] = x128[j+2];
-  }
-
-  dft48((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft48((int16_t *)(x2128+48),(int16_t *)(ytmp128+48),1);
-  dft48((int16_t *)(x2128+96),(int16_t *)(ytmp128+96),1);
-
-  bfly3_tw1(ytmp128,ytmp128+48,ytmp128+96,y128,y128+48,y128+96);
-
-  for (i=1,j=0; i<48; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+48+i,
-          ytmp128+96+i,
-          y128+i,
-          y128+48+i,
-          y128+96+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[9]);
-
-    for (i=0; i<144; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa180[472]__attribute__((aligned(32)));
-static int16_t twb180[472]__attribute__((aligned(32)));
-
-void dft180(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa180[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb180[0];
-  simd_q15_t x2128[180];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[180];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<60; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+60] = x128[j+1];
-    x2128[i+120] = x128[j+2];
-  }
-
-  dft60((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft60((int16_t *)(x2128+60),(int16_t *)(ytmp128+60),1);
-  dft60((int16_t *)(x2128+120),(int16_t *)(ytmp128+120),1);
-
-  bfly3_tw1(ytmp128,ytmp128+60,ytmp128+120,y128,y128+60,y128+120);
-
-  for (i=1,j=0; i<60; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+60+i,
-          ytmp128+120+i,
-          y128+i,
-          y128+60+i,
-          y128+120+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[10]);
-
-    for (i=0; i<180; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa192[376]__attribute__((aligned(32)));
-static int16_t twb192[376]__attribute__((aligned(32)));
-static int16_t twc192[376]__attribute__((aligned(32)));
-
-void dft192(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa192[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb192[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc192[0];
-  simd_q15_t x2128[192];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[192];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<48; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+48] = x128[j+1];
-    x2128[i+96] = x128[j+2];
-    x2128[i+144] = x128[j+3];
-  }
-
-  dft48((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft48((int16_t *)(x2128+48),(int16_t *)(ytmp128+48),1);
-  dft48((int16_t *)(x2128+96),(int16_t *)(ytmp128+96),1);
-  dft48((int16_t *)(x2128+144),(int16_t *)(ytmp128+144),1);
-
-  bfly4_tw1(ytmp128,ytmp128+48,ytmp128+96,ytmp128+144,y128,y128+48,y128+96,y128+144);
-
-  for (i=1,j=0; i<48; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+48+i,
-          ytmp128+96+i,
-          ytmp128+144+i,
-          y128+i,
-          y128+48+i,
-          y128+96+i,
-          y128+144+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[11]);
-
-    for (i=0; i<192; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa216[568]__attribute__((aligned(32)));
-static int16_t twb216[568]__attribute__((aligned(32)));
-
-void dft216(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa216[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb216[0];
-  simd_q15_t x2128[216];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[216];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<72; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+72] = x128[j+1];
-    x2128[i+144] = x128[j+2];
-  }
-
-  dft72((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft72((int16_t *)(x2128+72),(int16_t *)(ytmp128+72),1);
-  dft72((int16_t *)(x2128+144),(int16_t *)(ytmp128+144),1);
-
-  bfly3_tw1(ytmp128,ytmp128+72,ytmp128+144,y128,y128+72,y128+144);
-
-  for (i=1,j=0; i<72; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+72+i,
-          ytmp128+144+i,
-          y128+i,
-          y128+72+i,
-          y128+144+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[12]);
-
-    for (i=0; i<216; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa240[472]__attribute__((aligned(32)));
-static int16_t twb240[472]__attribute__((aligned(32)));
-static int16_t twc240[472]__attribute__((aligned(32)));
-
-void dft240(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa240[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb240[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc240[0];
-  simd_q15_t x2128[240];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[240];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<60; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+60] = x128[j+1];
-    x2128[i+120] = x128[j+2];
-    x2128[i+180] = x128[j+3];
-  }
-
-  dft60((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft60((int16_t *)(x2128+60),(int16_t *)(ytmp128+60),1);
-  dft60((int16_t *)(x2128+120),(int16_t *)(ytmp128+120),1);
-  dft60((int16_t *)(x2128+180),(int16_t *)(ytmp128+180),1);
-
-  bfly4_tw1(ytmp128,ytmp128+60,ytmp128+120,ytmp128+180,y128,y128+60,y128+120,y128+180);
-
-  for (i=1,j=0; i<60; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+60+i,
-          ytmp128+120+i,
-          ytmp128+180+i,
-          y128+i,
-          y128+60+i,
-          y128+120+i,
-          y128+180+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[13]);
-
-    for (i=0; i<240; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa288[760]__attribute__((aligned(32)));
-static int16_t twb288[760]__attribute__((aligned(32)));
-
-void dft288(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa288[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb288[0];
-  simd_q15_t x2128[288];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[288];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<96; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+96] = x128[j+1];
-    x2128[i+192] = x128[j+2];
-  }
-
-  dft96((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft96((int16_t *)(x2128+96),(int16_t *)(ytmp128+96),1);
-  dft96((int16_t *)(x2128+192),(int16_t *)(ytmp128+192),1);
-
-  bfly3_tw1(ytmp128,ytmp128+96,ytmp128+192,y128,y128+96,y128+192);
-
-  for (i=1,j=0; i<96; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+96+i,
-          ytmp128+192+i,
-          y128+i,
-          y128+96+i,
-          y128+192+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<288; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa300[472]__attribute__((aligned(32)));
-static int16_t twb300[472]__attribute__((aligned(32)));
-static int16_t twc300[472]__attribute__((aligned(32)));
-static int16_t twd300[472]__attribute__((aligned(32)));
-
-void dft300(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa300[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb300[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc300[0];
-  simd_q15_t *twd128=(simd_q15_t *)&twd300[0];
-  simd_q15_t x2128[300];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[300];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<60; i++,j+=5) {
-    x2128[i]    = x128[j];
-    x2128[i+60] = x128[j+1];
-    x2128[i+120] = x128[j+2];
-    x2128[i+180] = x128[j+3];
-    x2128[i+240] = x128[j+4];
-  }
-
-  dft60((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft60((int16_t *)(x2128+60),(int16_t *)(ytmp128+60),1);
-  dft60((int16_t *)(x2128+120),(int16_t *)(ytmp128+120),1);
-  dft60((int16_t *)(x2128+180),(int16_t *)(ytmp128+180),1);
-  dft60((int16_t *)(x2128+240),(int16_t *)(ytmp128+240),1);
-
-  bfly5_tw1(ytmp128,ytmp128+60,ytmp128+120,ytmp128+180,ytmp128+240,y128,y128+60,y128+120,y128+180,y128+240);
-
-  for (i=1,j=0; i<60; i++,j++) {
-    bfly5(ytmp128+i,
-          ytmp128+60+i,
-          ytmp128+120+i,
-          ytmp128+180+i,
-          ytmp128+240+i,
-          y128+i,
-          y128+60+i,
-          y128+120+i,
-          y128+180+i,
-          y128+240+i,
-          twa128+j,
-          twb128+j,
-          twc128+j,
-          twd128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[15]);
-
-    for (i=0; i<300; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-static int16_t twa324[107*2*4];
-static int16_t twb324[107*2*4];
-
-void dft324(int16_t *x,int16_t *y,unsigned char scale_flag)  // 108 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa324[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb324[0];
-  simd_q15_t x2128[324];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[324];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<108; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+108] = x128[j+1];
-    x2128[i+216] = x128[j+2];
-  }
-
-  dft108((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft108((int16_t *)(x2128+108),(int16_t *)(ytmp128+108),1);
-  dft108((int16_t *)(x2128+216),(int16_t *)(ytmp128+216),1);
-
-  bfly3_tw1(ytmp128,ytmp128+108,ytmp128+216,y128,y128+108,y128+216);
-
-  for (i=1,j=0; i<108; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+108+i,
-          ytmp128+216+i,
-          y128+i,
-          y128+108+i,
-          y128+216+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<324; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa360[119*2*4];
-static int16_t twb360[119*2*4];
-
-void dft360(int16_t *x,int16_t *y,unsigned char scale_flag)  // 120 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa360[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb360[0];
-  simd_q15_t x2128[360];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[360];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<120; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+120] = x128[j+1];
-    x2128[i+240] = x128[j+2];
-  }
-
-  dft120((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft120((int16_t *)(x2128+120),(int16_t *)(ytmp128+120),1);
-  dft120((int16_t *)(x2128+240),(int16_t *)(ytmp128+240),1);
-
-  bfly3_tw1(ytmp128,ytmp128+120,ytmp128+240,y128,y128+120,y128+240);
-
-  for (i=1,j=0; i<120; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+120+i,
-          ytmp128+240+i,
-          y128+i,
-          y128+120+i,
-          y128+240+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<360; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa384[95*2*4];
-static int16_t twb384[95*2*4];
-static int16_t twc384[95*2*4];
-
-void dft384(int16_t *x,int16_t *y,unsigned char scale_flag)  // 96 x 4
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa384[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb384[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc384[0];
-  simd_q15_t x2128[384];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[384];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<96; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+96] = x128[j+1];
-    x2128[i+192] = x128[j+2];
-    x2128[i+288] = x128[j+3];
-  }
-
-  dft96((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft96((int16_t *)(x2128+96),(int16_t *)(ytmp128+96),1);
-  dft96((int16_t *)(x2128+192),(int16_t *)(ytmp128+192),1);
-  dft96((int16_t *)(x2128+288),(int16_t *)(ytmp128+288),1);
-
-  bfly4_tw1(ytmp128,ytmp128+96,ytmp128+192,ytmp128+288,y128,y128+96,y128+192,y128+288);
-
-  for (i=1,j=0; i<96; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+96+i,
-          ytmp128+192+i,
-          ytmp128+288+i,
-          y128+i,
-          y128+96+i,
-          y128+192+i,
-          y128+288+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<384; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa432[107*2*4];
-static int16_t twb432[107*2*4];
-static int16_t twc432[107*2*4];
-
-void dft432(int16_t *x,int16_t *y,unsigned char scale_flag)  // 108 x 4
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa432[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb432[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc432[0];
-  simd_q15_t x2128[432];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[432];//=&ytmp128array2[0];
-
-
-  for (i=0,j=0; i<108; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+108] = x128[j+1];
-    x2128[i+216] = x128[j+2];
-    x2128[i+324] = x128[j+3];
-  }
-
-  dft108((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft108((int16_t *)(x2128+108),(int16_t *)(ytmp128+108),1);
-  dft108((int16_t *)(x2128+216),(int16_t *)(ytmp128+216),1);
-  dft108((int16_t *)(x2128+324),(int16_t *)(ytmp128+324),1);
-
-  bfly4_tw1(ytmp128,ytmp128+108,ytmp128+216,ytmp128+324,y128,y128+108,y128+216,y128+324);
-
-  for (i=1,j=0; i<108; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+108+i,
-          ytmp128+216+i,
-          ytmp128+324+i,
-          y128+i,
-          y128+108+i,
-          y128+216+i,
-          y128+324+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<432; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-static int16_t twa480[119*2*4];
-static int16_t twb480[119*2*4];
-static int16_t twc480[119*2*4];
-
-void dft480(int16_t *x,int16_t *y,unsigned char scale_flag)  // 120 x 4
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa480[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb480[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc480[0];
-  simd_q15_t x2128[480];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[480];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<120; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+120] = x128[j+1];
-    x2128[i+240] = x128[j+2];
-    x2128[i+360] = x128[j+3];
-  }
-
-  dft120((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft120((int16_t *)(x2128+120),(int16_t *)(ytmp128+120),1);
-  dft120((int16_t *)(x2128+240),(int16_t *)(ytmp128+240),1);
-  dft120((int16_t *)(x2128+360),(int16_t *)(ytmp128+360),1);
-
-  bfly4_tw1(ytmp128,ytmp128+120,ytmp128+240,ytmp128+360,y128,y128+120,y128+240,y128+360);
-
-  for (i=1,j=0; i<120; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+120+i,
-          ytmp128+240+i,
-          ytmp128+360+i,
-          y128+i,
-          y128+120+i,
-          y128+240+i,
-          y128+360+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<480; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-
-static int16_t twa540[179*2*4];
-static int16_t twb540[179*2*4];
-
-void dft540(int16_t *x,int16_t *y,unsigned char scale_flag)  // 180 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa540[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb540[0];
-  simd_q15_t x2128[540];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[540];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<180; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+180] = x128[j+1];
-    x2128[i+360] = x128[j+2];
-  }
-
-  dft180((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft180((int16_t *)(x2128+180),(int16_t *)(ytmp128+180),1);
-  dft180((int16_t *)(x2128+360),(int16_t *)(ytmp128+360),1);
-
-  bfly3_tw1(ytmp128,ytmp128+180,ytmp128+360,y128,y128+180,y128+360);
-
-  for (i=1,j=0; i<180; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+180+i,
-          ytmp128+360+i,
-          y128+i,
-          y128+180+i,
-          y128+360+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<540; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa576[191*2*4];
-static int16_t twb576[191*2*4];
-
-void dft576(int16_t *x,int16_t *y,unsigned char scale_flag)  // 192 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa576[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb576[0];
-  simd_q15_t x2128[576];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[576];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<192; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+192] = x128[j+1];
-    x2128[i+384] = x128[j+2];
-  }
-
-
-  dft192((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft192((int16_t *)(x2128+192),(int16_t *)(ytmp128+192),1);
-  dft192((int16_t *)(x2128+384),(int16_t *)(ytmp128+384),1);
-
-  bfly3_tw1(ytmp128,ytmp128+192,ytmp128+384,y128,y128+192,y128+384);
-
-  for (i=1,j=0; i<192; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+192+i,
-          ytmp128+384+i,
-          y128+i,
-          y128+192+i,
-          y128+384+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<576; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-};
-
-
-static int16_t twa600[299*2*4];
-
-void dft600(int16_t *x,int16_t *y,unsigned char scale_flag)  // 300 x 2
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *tw128=(simd_q15_t *)&twa600[0];
-  simd_q15_t x2128[600];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[600];//=&ytmp128array2[0];
-
-
-  for (i=0,j=0; i<300; i++,j+=2) {
-    x2128[i]    = x128[j];
-    x2128[i+300] = x128[j+1];
-  }
-
-  dft300((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1);
-
-
-  bfly2_tw1(ytmp128,ytmp128+300,y128,y128+300);
-
-  for (i=1,j=0; i<300; i++,j++) {
-    bfly2(ytmp128+i,
-          ytmp128+300+i,
-          y128+i,
-          y128+300+i,
-          tw128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(ONE_OVER_SQRT2_Q15);
-
-    for (i=0; i<600; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-};
-
-
-static int16_t twa648[215*2*4];
-static int16_t twb648[215*2*4];
-
-void dft648(int16_t *x,int16_t *y,unsigned char scale_flag)  // 216 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa648[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb648[0];
-  simd_q15_t x2128[648];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[648];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<216; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+216] = x128[j+1];
-    x2128[i+432] = x128[j+2];
-  }
-
-  dft216((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft216((int16_t *)(x2128+216),(int16_t *)(ytmp128+216),1);
-  dft216((int16_t *)(x2128+432),(int16_t *)(ytmp128+432),1);
-
-  bfly3_tw1(ytmp128,ytmp128+216,ytmp128+432,y128,y128+216,y128+432);
-
-  for (i=1,j=0; i<216; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+216+i,
-          ytmp128+432+i,
-          y128+i,
-          y128+216+i,
-          y128+432+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<648; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-
-static int16_t twa720[179*2*4];
-static int16_t twb720[179*2*4];
-static int16_t twc720[179*2*4];
-
-
-void dft720(int16_t *x,int16_t *y,unsigned char scale_flag)  // 180 x 4
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa720[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb720[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc720[0];
-  simd_q15_t x2128[720];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[720];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<180; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+180] = x128[j+1];
-    x2128[i+360] = x128[j+2];
-    x2128[i+540] = x128[j+3];
-  }
-
-  dft180((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft180((int16_t *)(x2128+180),(int16_t *)(ytmp128+180),1);
-  dft180((int16_t *)(x2128+360),(int16_t *)(ytmp128+360),1);
-  dft180((int16_t *)(x2128+540),(int16_t *)(ytmp128+540),1);
-
-  bfly4_tw1(ytmp128,ytmp128+180,ytmp128+360,ytmp128+540,y128,y128+180,y128+360,y128+540);
-
-  for (i=1,j=0; i<180; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+180+i,
-          ytmp128+360+i,
-          ytmp128+540+i,
-          y128+i,
-          y128+180+i,
-          y128+360+i,
-          y128+540+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<720; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa768[191*2*4];
-static int16_t twb768[191*2*4];
-static int16_t twc768[191*2*4];
-
-void dft768(int16_t *x,int16_t *y,unsigned char scale_flag) { // 192x 4;
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa768[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb768[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc768[0];
-  simd_q15_t x2128[768];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[768];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<192; i++,j+=4) {
-    x2128[i]     = x128[j];
-    x2128[i+192] = x128[j+1];
-    x2128[i+384] = x128[j+2];
-    x2128[i+576] = x128[j+3];
-  }
-
-  dft192((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft192((int16_t *)(x2128+192),(int16_t *)(ytmp128+192),1);
-  dft192((int16_t *)(x2128+384),(int16_t *)(ytmp128+384),1);
-  dft192((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1);
-
-  bfly4_tw1(ytmp128,ytmp128+192,ytmp128+384,ytmp128+576,y128,y128+192,y128+384,y128+576);
-
-  for (i=1,j=0; i<192; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+192+i,
-          ytmp128+384+i,
-          ytmp128+576+i,
-          y128+i,
-          y128+192+i,
-          y128+384+i,
-          y128+576+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<768; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-
-}
-
-
-static int16_t twa864[287*2*4];
-static int16_t twb864[287*2*4];
-
-void dft864(int16_t *x,int16_t *y,unsigned char scale_flag)  // 288 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa864[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb864[0];
-  simd_q15_t x2128[864];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[864];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<288; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+288] = x128[j+1];
-    x2128[i+576] = x128[j+2];
-  }
-
-  dft288((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft288((int16_t *)(x2128+288),(int16_t *)(ytmp128+288),1);
-  dft288((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1);
-
-  bfly3_tw1(ytmp128,ytmp128+288,ytmp128+576,y128,y128+288,y128+576);
-
-  for (i=1,j=0; i<288; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+288+i,
-          ytmp128+576+i,
-          y128+i,
-          y128+288+i,
-          y128+576+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<864; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa900[299*2*4];
-static int16_t twb900[299*2*4];
-
-void dft900(int16_t *x,int16_t *y,unsigned char scale_flag)  // 300 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa900[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb900[0];
-  simd_q15_t x2128[900];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[900];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<300; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+300] = x128[j+1];
-    x2128[i+600] = x128[j+2];
-  }
-
-  dft300((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1);
-  dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
-
-  bfly3_tw1(ytmp128,ytmp128+300,ytmp128+600,y128,y128+300,y128+600);
-
-  for (i=1,j=0; i<300; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+300+i,
-          ytmp128+600+i,
-          y128+i,
-          y128+300+i,
-          y128+600+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<900; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-
-static int16_t twa960[239*2*4];
-static int16_t twb960[239*2*4];
-static int16_t twc960[239*2*4];
-
-
-void dft960(int16_t *x,int16_t *y,unsigned char scale_flag)  // 240 x 4
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa960[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb960[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc960[0];
-  simd_q15_t x2128[960];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[960];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<240; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+240] = x128[j+1];
-    x2128[i+480] = x128[j+2];
-    x2128[i+720] = x128[j+3];
-  }
-
-  dft240((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft240((int16_t *)(x2128+240),(int16_t *)(ytmp128+240),1);
-  dft240((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1);
-  dft240((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1);
-
-  bfly4_tw1(ytmp128,ytmp128+240,ytmp128+480,ytmp128+720,y128,y128+240,y128+480,y128+720);
-
-  for (i=1,j=0; i<240; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+240+i,
-          ytmp128+480+i,
-          ytmp128+720+i,
-          y128+i,
-          y128+240+i,
-          y128+480+i,
-          y128+720+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<960; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-
-static int16_t twa972[323*2*4];
-static int16_t twb972[323*2*4];
-
-void dft972(int16_t *x,int16_t *y,unsigned char scale_flag)  // 324 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa972[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb972[0];
-  simd_q15_t x2128[972];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[972];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<324; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+324] = x128[j+1];
-    x2128[i+648] = x128[j+2];
-  }
-
-  dft324((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft324((int16_t *)(x2128+324),(int16_t *)(ytmp128+324),1);
-  dft324((int16_t *)(x2128+648),(int16_t *)(ytmp128+648),1);
-
-  bfly3_tw1(ytmp128,ytmp128+324,ytmp128+648,y128,y128+324,y128+648);
-
-  for (i=1,j=0; i<324; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+324+i,
-          ytmp128+648+i,
-          y128+i,
-          y128+324+i,
-          y128+648+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<972; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa1080[359*2*4];
-static int16_t twb1080[359*2*4];
-
-void dft1080(int16_t *x,int16_t *y,unsigned char scale_flag)  // 360 x 3
-{
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa1080[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb1080[0];
-  simd_q15_t x2128[1080];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[1080];//=&ytmp128array3[0];
-
-
-
-  for (i=0,j=0; i<360; i++,j+=3) {
-    x2128[i]    = x128[j];
-    x2128[i+360] = x128[j+1];
-    x2128[i+720] = x128[j+2];
-  }
-
-  dft360((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft360((int16_t *)(x2128+360),(int16_t *)(ytmp128+360),1);
-  dft360((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1);
-
-  bfly3_tw1(ytmp128,ytmp128+360,ytmp128+720,y128,y128+360,y128+720);
-
-  for (i=1,j=0; i<360; i++,j++) {
-    bfly3(ytmp128+i,
-          ytmp128+360+i,
-          ytmp128+720+i,
-          y128+i,
-          y128+360+i,
-          y128+720+i,
-          twa128+j,
-          twb128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(dft_norm_table[14]);
-
-    for (i=0; i<1080; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-};
-
-static int16_t twa1152[287*2*4];
-static int16_t twb1152[287*2*4];
-static int16_t twc1152[287*2*4];
-
-void dft1152(int16_t *x,int16_t *y,unsigned char scale_flag)  // 288 x 4
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa1152[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb1152[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc1152[0];
-  simd_q15_t x2128[1152];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[1152];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<288; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+288] = x128[j+1];
-    x2128[i+576] = x128[j+2];
-    x2128[i+864] = x128[j+3];
-  }
-
-  dft288((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft288((int16_t *)(x2128+288),(int16_t *)(ytmp128+288),1);
-  dft288((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1);
-  dft288((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1);
-
-  bfly4_tw1(ytmp128,ytmp128+288,ytmp128+576,ytmp128+864,y128,y128+288,y128+576,y128+864);
-
-  for (i=1,j=0; i<288; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+288+i,
-          ytmp128+576+i,
-          ytmp128+864+i,
-          y128+i,
-          y128+288+i,
-          y128+576+i,
-          y128+864+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-
-    for (i=0; i<1152; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-};
-
-int16_t twa1200[4784];
-int16_t twb1200[4784];
-int16_t twc1200[4784];
-
-void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag)
-{
-
-  int i,j;
-  simd_q15_t *x128=(simd_q15_t *)x;
-  simd_q15_t *y128=(simd_q15_t *)y;
-  simd_q15_t *twa128=(simd_q15_t *)&twa1200[0];
-  simd_q15_t *twb128=(simd_q15_t *)&twb1200[0];
-  simd_q15_t *twc128=(simd_q15_t *)&twc1200[0];
-  simd_q15_t x2128[1200];// = (simd_q15_t *)&x2128array[0];
-  simd_q15_t ytmp128[1200];//=&ytmp128array2[0];
-
-
-
-  for (i=0,j=0; i<300; i++,j+=4) {
-    x2128[i]    = x128[j];
-    x2128[i+300] = x128[j+1];
-    x2128[i+600] = x128[j+2];
-    x2128[i+900] = x128[j+3];
-  }
-
-  dft300((int16_t *)x2128,(int16_t *)ytmp128,1);
-  dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1);
-  dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1);
-  dft300((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1);
-
-  bfly4_tw1(ytmp128,ytmp128+300,ytmp128+600,ytmp128+900,y128,y128+300,y128+600,y128+900);
-
-  for (i=1,j=0; i<300; i++,j++) {
-    bfly4(ytmp128+i,
-          ytmp128+300+i,
-          ytmp128+600+i,
-          ytmp128+900+i,
-          y128+i,
-          y128+300+i,
-          y128+600+i,
-          y128+900+i,
-          twa128+j,
-          twb128+j,
-          twc128+j);
-  }
-
-  if (scale_flag==1) {
-    norm128 = set1_int16(16384);//dft_norm_table[13]);
-    for (i=0; i<1200; i++) {
-      y128[i] = mulhi_int16(y128[i],norm128);
-    }
-  }
-
-  _mm_empty();
-  _m_empty();
-
-}
-
-//#define round trunc
-
-void init_rad4(int N,int16_t *tw) {
-
-  int16_t *twa = tw;
-  int16_t *twb = twa+(N/2);
-  int16_t *twc = twb+(N/2);
-  int i;
-
-  for (i=0;i<(N/4);i++) {
-    *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++;
-    *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++;
-    *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++;
-    *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++;
-    *twc = (int16_t)round(32767.0*cos(2*M_PI*3*i/N)); twc++;
-    *twc = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N)); twc++;
-  }
-}
-void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) {
-
-  int i,j;
-
-  for (i=1;i<(N/4);i++) {
-    twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); 
-    twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
-    twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
-    twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
-    twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N));
-    twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N));
-    for (j=1;j<4;j++) {
-      ((int32_t*)twa)[j]=((int32_t*)twa)[0];
-      ((int32_t*)twb)[j]=((int32_t*)twb)[0];
-      ((int32_t*)twc)[j]=((int32_t*)twc)[0];
-    }
-    twa+=8;
-    twb+=8;
-    twc+=8;
-  }
-}
-
-void init_rad2(int N,int16_t *tw) {
-
-  int16_t *twa = tw;
-  int i;
-
-  for (i=0;i<(N>>1);i++) {
-    *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++;
-    *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++;
-  }
-}
-
-void init_rad2_rep(int N,int16_t *twa) {
-
-  int i,j;
-
-  for (i=1;i<(N/2);i++) {
-    twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); 
-    twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
-    for (j=1;j<4;j++) {
-      ((int32_t*)twa)[j]=((int32_t*)twa)[0];
-    }
-    twa+=8;
-  }
-}
-
-void init_rad3(int N,int16_t *twa,int16_t *twb) {
-
-  int i;
-
-  for (i=0;i<(N/3);i++) {
-    *twa = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa++;
-    *twa = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twa++;
-    *twb = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb++;
-    *twb = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); twb++;
-  }
-}
-
-void init_rad3_rep(int N,int16_t *twa,int16_t *twb) {
-
-  int i,j;
-
-  for (i=1;i<(N/3);i++) {
-    twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); 
-    twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
-    twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
-    twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
-    for (j=1;j<4;j++) {
-      ((int32_t*)twa)[j]=((int32_t*)twa)[0];
-      ((int32_t*)twb)[j]=((int32_t*)twb)[0];
-    }
-    twa+=8;
-    twb+=8;
-  }
-}
-
-void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) {
-
-  int i,j;
-
-  for (i=1;i<(N/5);i++) {
-    twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); 
-    twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N));
-    twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N));
-    twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N));
-    twc[0] = (int16_t)round(32767.0*cos(2*M_PI*3*i/N));
-    twc[1] = -(int16_t)round(32767.0*sin(2*M_PI*3*i/N));
-    twd[0] = (int16_t)round(32767.0*cos(2*M_PI*4*i/N));
-    twd[1] = -(int16_t)round(32767.0*sin(2*M_PI*4*i/N));
-    for (j=1;j<4;j++) {
-      ((int32_t*)twa)[j]=((int32_t*)twa)[0];
-      ((int32_t*)twb)[j]=((int32_t*)twb)[0];
-      ((int32_t*)twc)[j]=((int32_t*)twc)[0];
-      ((int32_t*)twd)[j]=((int32_t*)twd)[0];
-    }
-    twa+=8;
-    twb+=8;
-    twc+=8;
-    twd+=8;
-  }
-}
-
-
-void init_dfts(void)
-{
-  init_rad4(1024,tw1024);
-  init_rad2(2048,tw2048);
-  init_rad4(4096,tw4096);
-  init_rad2(8192,tw8192);
-  
-  init_rad3(1536,twa1536,twb1536);
-  init_rad3(3072,twa3072,twb3072);
-  init_rad3(6144,twa6144,twb6144);
-  init_rad3(12288,twa12288,twb12288);
-  init_rad3(18432,twa18432,twb18432);
-  init_rad3(24576,twa24576,twb24576);
-
-  init_rad2_rep(24,tw24);
-  init_rad3_rep(36,twa36,twb36);
-  init_rad4_rep(48,twa48,twb48,twc48);
-  init_rad5_rep(60,twa60,twb60,twc60,twd60);
-  init_rad2_rep(72,tw72);
-  init_rad2_rep(96,tw96);
-  init_rad3_rep(108,twa108,twb108);
-  init_rad2_rep(120,tw120);
-  init_rad3_rep(144,twa144,twb144);
-  init_rad3_rep(180,twa180,twb180);
-  init_rad4_rep(192,twa192,twb192,twc192);
-  init_rad3_rep(216,twa216,twb216);
-  init_rad4_rep(240,twa240,twb240,twc240);
-  init_rad3_rep(288,twa288,twb288);
-  init_rad5_rep(300,twa300,twb300,twc300,twd300);
-  init_rad3_rep(324,twa324,twb324);
-  init_rad3_rep(360,twa360,twb360);
-  init_rad4_rep(384,twa384,twb384,twc384);
-  init_rad4_rep(432,twa432,twb432,twc432);
-  init_rad4_rep(480,twa480,twb480,twc480);
-  init_rad3_rep(540,twa540,twb540);
-  init_rad3_rep(576,twa576,twb576);
-  init_rad2_rep(600,twa600);
-  init_rad3_rep(648,twa648,twb648);
-  init_rad4_rep(720,twa720,twb720,twc720);
-  init_rad4_rep(768,twa768,twb768,twc768);
-  init_rad3_rep(864,twa864,twb864);
-  init_rad3_rep(900,twa900,twb900);
-  init_rad4_rep(960,twa960,twb960,twc960);
-  init_rad3_rep(972,twa972,twb972);
-  init_rad3_rep(1080,twa1080,twb1080);
-  init_rad4_rep(1152,twa1152,twb1152,twc1152);
-  init_rad4_rep(1200,twa1200,twb1200,twc1200);
-}
-
-//#undef round
-
-#ifdef MR_MAIN
-#include <string.h>
-#include <stdio.h>
-
-#define LOG_M write_output
-int write_output(const char *fname,const char *vname,void *data,int length,int dec,char format)
-{
-
-  FILE *fp=NULL;
-  int i;
-
-
-  printf("Writing %d elements of type %d to %s\n",length,format,fname);
-
-
-  if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
-    fp = fopen(fname,"a+");
-  } else if (format != 10 && format !=11  && format != 12 && format != 13 && format != 14) {
-    fp = fopen(fname,"w+");
-  }
-
-
-
-  if (fp== NULL) {
-    printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n",fname);
-    return(-1);
-  }
-
-  if (format != 10 && format !=11  && format != 12 && format != 13 && format != 14)
-    fprintf(fp,"%s = [",vname);
-
-
-  switch (format) {
-  case 0:   // real 16-bit
-
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%d\n",((short *)data)[i]);
-    }
-
-    break;
-
-  case 1:  // complex 16-bit
-  case 13:
-  case 14:
-  case 15:
-
-    for (i=0; i<length<<1; i+=(2*dec)) {
-      fprintf(fp,"%d + j*(%d)\n",((short *)data)[i],((short *)data)[i+1]);
-
-    }
-
-
-    break;
-
-  case 2:  // real 32-bit
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%d\n",((int *)data)[i]);
-    }
-
-    break;
-
-  case 3: // complex 32-bit
-    for (i=0; i<length<<1; i+=(2*dec)) {
-      fprintf(fp,"%d + j*(%d)\n",((int *)data)[i],((int *)data)[i+1]);
-    }
-
-    break;
-
-  case 4: // real 8-bit
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%d\n",((char *)data)[i]);
-    }
-
-    break;
-
-  case 5: // complex 8-bit
-    for (i=0; i<length<<1; i+=(2*dec)) {
-      fprintf(fp,"%d + j*(%d)\n",((char *)data)[i],((char *)data)[i+1]);
-    }
-
-    break;
-
-  case 6:  // real 64-bit
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%lld\n",((long long*)data)[i]);
-    }
-
-    break;
-
-  case 7: // real double
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%g\n",((double *)data)[i]);
-    }
-
-    break;
-
-  case 8: // complex double
-    for (i=0; i<length<<1; i+=2*dec) {
-      fprintf(fp,"%g + j*(%g)\n",((double *)data)[i], ((double *)data)[i+1]);
-    }
-
-    break;
-
-  case 9: // real unsigned 8-bit
-    for (i=0; i<length; i+=dec) {
-      fprintf(fp,"%d\n",((unsigned char *)data)[i]);
-    }
-
-    break;
-
-
-  case 10 : // case eren 16 bit complex :
-
-    for (i=0; i<length<<1; i+=(2*dec)) {
-
-      if((i < 2*(length-1)) && (i > 0))
-        fprintf(fp,"%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
-      else if (i == 2*(length-1))
-        fprintf(fp,"%d + j*(%d);",((short *)data)[i],((short *)data)[i+1]);
-      else if (i == 0)
-        fprintf(fp,"\n%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]);
-
-
-
-    }
-
-    break;
-
-  case 11 : //case eren 16 bit real for channel magnitudes:
-    for (i=0; i<length; i+=dec) {
-
-      if((i <(length-1))&& (i > 0))
-        fprintf(fp,"%d,",((short *)data)[i]);
-      else if (i == (length-1))
-        fprintf(fp,"%d;",((short *)data)[i]);
-      else if (i == 0)
-        fprintf(fp,"\n%d,",((short *)data)[i]);
-    }
-
-    printf("\n erennnnnnnnnnnnnnn: length :%d",length);
-    break;
-
-  case 12 : // case eren for log2_maxh real unsigned 8 bit
-    fprintf(fp,"%d \n",((unsigned char *)&data)[0]);
-    break;
-
-  }
-
-  if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) {
-    fprintf(fp,"];\n");
-    fclose(fp);
-    return(0);
-  } else if (format == 10 || format ==11 || format == 12 || format == 13 || format == 15) {
-    fclose(fp);
-    return(0);
-  }
-
-  return 0;
-}
-
-
-int main(int argc, char**argv)
-{
-
-
-  time_stats_t ts;
-#ifdef __AVX2__
-  simd256_q15_t x[4096],x2[4096],y[4096],tw0,tw1,tw2,tw3;
-#else
-  simd_q15_t x[8192],x2[8192],y[8192],tw0,tw1,tw2,tw3;
-#endif
-  int i;
-  simd_q15_t *x128=(simd_q15_t*)x,*y128=(simd_q15_t*)y;
-
-  init_dfts();
-
-  set_taus_seed(0);
-  opp_enabled = 1;
- /* 
-    ((int16_t *)&tw0)[0] = 32767;
-    ((int16_t *)&tw0)[1] = 0;
-    ((int16_t *)&tw0)[2] = 32767;
-    ((int16_t *)&tw0)[3] = 0;
-    ((int16_t *)&tw0)[4] = 32767;
-    ((int16_t *)&tw0)[5] = 0;
-    ((int16_t *)&tw0)[6] = 32767;
-    ((int16_t *)&tw0)[7] = 0;
-
-    ((int16_t *)&tw1)[0] = 32767;
-    ((int16_t *)&tw1)[1] = 0;
-    ((int16_t *)&tw1)[2] = 32767;
-    ((int16_t *)&tw1)[3] = 0;
-    ((int16_t *)&tw1)[4] = 32767;
-    ((int16_t *)&tw1)[5] = 0;
-    ((int16_t *)&tw1)[6] = 32767;
-    ((int16_t *)&tw1)[7] = 0;
-
-    ((int16_t *)&tw2)[0] = 32767;
-    ((int16_t *)&tw2)[1] = 0;
-    ((int16_t *)&tw2)[2] = 32767;
-    ((int16_t *)&tw2)[3] = 0;
-    ((int16_t *)&tw2)[4] = 32767;
-    ((int16_t *)&tw2)[5] = 0;
-    ((int16_t *)&tw2)[6] = 32767;
-    ((int16_t *)&tw2)[7] = 0;
-
-    ((int16_t *)&tw3)[0] = 32767;
-    ((int16_t *)&tw3)[1] = 0;
-    ((int16_t *)&tw3)[2] = 32767;
-    ((int16_t *)&tw3)[3] = 0;
-    ((int16_t *)&tw3)[4] = 32767;
-    ((int16_t *)&tw3)[5] = 0;
-    ((int16_t *)&tw3)[6] = 32767;
-    ((int16_t *)&tw3)[7] = 0;
- */
-    for (i=0;i<300;i++) {
-#if defined(__x86_64__) || defined(__i386__)
-#ifndef __AVX2__
-      x[i] = _mm_set1_epi32(taus());
-      x[i] = _mm_srai_epi16(x[i],4);
-#else
-      x[i] = _mm256_set1_epi32(taus());
-      x[i] = _mm256_srai_epi16(x[i],4);
-#endif
-#elif defined(__arm__)
-      x[i] = (int16x8_t)vdupq_n_s32(taus());
-      x[i] = vshrq_n_s16(x[i],4);
-#endif
-    }
-      /*
-    bfly2_tw1(x,x+1,y,y+1);
-    printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1]);
-    printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3]);
-    printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[4],((int16_t*)&y[0])[5],((int16_t*)&y[1])[4],((int16_t*)&y[1])[5]);
-    printf("(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[6],((int16_t*)&y[0])[7],((int16_t*)&y[1])[6],((int16_t*)&y[1])[7]);
-    bfly2(x,x+1,y,y+1, &tw0);
-    printf("0(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1]);
-    printf("1(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3]);
-    printf("2(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[4],((int16_t*)&y[0])[5],((int16_t*)&y[1])[4],((int16_t*)&y[1])[5]);
-    printf("3(%d,%d) (%d,%d) => (%d,%d) (%d,%d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&y[0])[6],((int16_t*)&y[0])[7],((int16_t*)&y[1])[6],((int16_t*)&y[1])[7]);
-    bfly2(x,x+1,y,y+1, &tw0);
-
-    bfly3_tw1(x,x+1,x+2,y, y+1,y+2);
-    printf("0(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1],((int16_t*)&y[2])[0],((int16_t*)&y[2])[1]);
-    printf("1(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3],((int16_t*)&y[2])[2],((int16_t*)&y[2])[3]);
-    printf("2(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[4],((int16_t*)&y[0])[5],((int16_t*)&y[1])[4],((int16_t*)&y[1])[5],((int16_t*)&y[2])[4],((int16_t*)&y[2])[5]);
-    printf("3(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[6],((int16_t*)&y[0])[7],((int16_t*)&y[1])[6],((int16_t*)&y[1])[7],((int16_t*)&y[2])[6],((int16_t*)&y[2])[7]);
-    bfly3(x,x+1,x+2,y, y+1,y+2,&tw0,&tw1);
-
-    printf("0(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1],((int16_t*)&y[2])[0],((int16_t*)&y[2])[1]);
-    printf("1(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3],((int16_t*)&y[2])[2],((int16_t*)&y[2])[3]);
-    printf("2(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[4],((int16_t*)&y[0])[5],((int16_t*)&y[1])[4],((int16_t*)&y[1])[5],((int16_t*)&y[2])[4],((int16_t*)&y[2])[5]);
-    printf("3(%d,%d) (%d,%d) (%d %d) => (%d,%d) (%d,%d) (%d %d)\n",((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&y[0])[6],((int16_t*)&y[0])[7],((int16_t*)&y[1])[6],((int16_t*)&y[1])[7],((int16_t*)&y[2])[6],((int16_t*)&y[2])[7]);
-
-
-    bfly4_tw1(x,x+1,x+2,x+3,y, y+1,y+2,y+3);
-    printf("(%d,%d) (%d,%d) (%d %d) (%d,%d) => (%d,%d) (%d,%d) (%d %d) (%d,%d)\n",
-     ((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],
-     ((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&x[3])[0],((int16_t*)&x[3])[1],
-     ((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1],
-     ((int16_t*)&y[2])[0],((int16_t*)&y[2])[1],((int16_t*)&y[3])[0],((int16_t*)&y[3])[1]);
-
-    bfly4(x,x+1,x+2,x+3,y, y+1,y+2,y+3,&tw0,&tw1,&tw2);
-    printf("0(%d,%d) (%d,%d) (%d %d) (%d,%d) => (%d,%d) (%d,%d) (%d %d) (%d,%d)\n",
-     ((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],
-     ((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&x[3])[0],((int16_t*)&x[3])[1],
-     ((int16_t*)&y[0])[0],((int16_t*)&y[0])[1],((int16_t*)&y[1])[0],((int16_t*)&y[1])[1],
-     ((int16_t*)&y[2])[0],((int16_t*)&y[2])[1],((int16_t*)&y[3])[0],((int16_t*)&y[3])[1]);
-    printf("1(%d,%d) (%d,%d) (%d %d) (%d,%d) => (%d,%d) (%d,%d) (%d %d) (%d,%d)\n",
-     ((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],
-     ((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&x[3])[0],((int16_t*)&x[3])[1],
-     ((int16_t*)&y[0])[2],((int16_t*)&y[0])[3],((int16_t*)&y[1])[2],((int16_t*)&y[1])[3],
-     ((int16_t*)&y[2])[2],((int16_t*)&y[2])[3],((int16_t*)&y[3])[2],((int16_t*)&y[3])[3]);
-    printf("2(%d,%d) (%d,%d) (%d %d) (%d,%d) => (%d,%d) (%d,%d) (%d %d) (%d,%d)\n",
-     ((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],
-     ((int16_t*)&x[2])[0],((int16_t*)&x[2])[1],((int16_t*)&x[3])[0],((int16_t*)&x[3])[1],
-     ((int16_t*)&y[0])[4],((int16_t*)&y[0])[5],((int16_t*)&y[1])[4],((int16_t*)&y[1])[5],
-     ((int16_t*)&y[2])[4],((int16_t*)&y[2])[5],((int16_t*)&y[3])[4],((int16_t*)&y[3])[5]);
-    printf("3(%d,%d) (%d,%d) (%d %d) (%d,%d) => (%d,%d) (%d,%d) (%d %d) (%d,%d)\n",
-     ((int16_t*)&x[0])[0],((int16_t*)&x[0])[1],((int16_t*)&x[1])[0],((int16_t*)&x[1])[1],
-     ((int16_t*)&x[2])[6],((int16_t*)&x[2])[7],((int16_t*)&x[3])[6],((int16_t*)&x[3])[7],
-     ((int16_t*)&y[0])[6],((int16_t*)&y[0])[7],((int16_t*)&y[1])[6],((int16_t*)&y[1])[7],
-     ((int16_t*)&y[2])[0],((int16_t*)&y[2])[1],((int16_t*)&y[3])[0],((int16_t*)&y[3])[1]);
-
-    bfly5_tw1(x,x+1,x+2,x+3,x+4,y,y+1,y+2,y+3,y+4);
-
-    for (i=0;i<5;i++)
-      printf("%d,%d,",
-       ((int16_t*)&x[i])[0],((int16_t*)&x[i])[1]);
-    printf("\n");
-    for (i=0;i<5;i++)
-      printf("%d,%d,",
-       ((int16_t*)&y[i])[0],((int16_t*)&y[i])[1]);
-    printf("\n");
-
-    bfly5(x,x+1,x+2,x+3,x+4,y, y+1,y+2,y+3,y+4,&tw0,&tw1,&tw2,&tw3);
-    for (i=0;i<5;i++)
-      printf("%d,%d,",
-       ((int16_t*)&x[i])[0],((int16_t*)&x[i])[1]);
-    printf("\n");
-    for (i=0;i<5;i++)
-      printf("%d,%d,",
-       ((int16_t*)&y[i])[0],((int16_t*)&y[i])[1]);
-    printf("\n");
-
-
-    printf("\n\n12-point\n");
-    dft12f(x,
-     x+1,
-     x+2,
-     x+3,
-     x+4,
-     x+5,
-     x+6,
-     x+7,
-     x+8,
-     x+9,
-     x+10,
-     x+11,
-     y,
-     y+1,
-     y+2,
-     y+3,
-     y+4,
-     y+5,
-     y+6,
-     y+7,
-     y+8,
-     y+9,
-     y+10,
-     y+11);
-
-
-    printf("X: ");
-    for (i=0;i<12;i++)
-      printf("%d,%d,",((int16_t*)(&x[i]))[0],((int16_t *)(&x[i]))[1]);
-    printf("\nY:");
-    for (i=0;i<12;i++)
-      printf("%d,%d,",((int16_t*)(&y[i]))[0],((int16_t *)(&y[i]))[1]);
-    printf("\n");
-
- */
-
-    for (i=0;i<32;i++) {
-      ((int16_t*)x)[i] = (int16_t)((taus()&0xffff))>>5;
-    }
-    memset((void*)&y[0],0,16*4);
-    idft16((int16_t *)x,(int16_t *)y);
-    printf("\n\n16-point\n");
-    printf("X: ");
-    for (i=0;i<4;i++)
-      printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&x[i])[0],((int16_t *)&x[i])[1],((int16_t*)&x[i])[2],((int16_t *)&x[i])[3],((int16_t*)&x[i])[4],((int16_t*)&x[i])[5],((int16_t*)&x[i])[6],((int16_t*)&x[i])[7]);
-    printf("\nY:");
-
-    for (i=0;i<4;i++)
-      printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&y[i])[0],((int16_t *)&y[i])[1],((int16_t*)&y[i])[2],((int16_t *)&y[i])[3],((int16_t*)&y[i])[4],((int16_t *)&y[i])[5],((int16_t*)&y[i])[6],((int16_t *)&y[i])[7]);
-    printf("\n");
- 
-  memset((void*)&x[0],0,2048*4);
-      
-  for (i=0; i<2048; i+=4) {
-     ((int16_t*)x)[i<<1] = 1024;
-     ((int16_t*)x)[1+(i<<1)] = 0;
-     ((int16_t*)x)[2+(i<<1)] = 0;
-     ((int16_t*)x)[3+(i<<1)] = 1024;
-     ((int16_t*)x)[4+(i<<1)] = -1024;
-     ((int16_t*)x)[5+(i<<1)] = 0;
-     ((int16_t*)x)[6+(i<<1)] = 0;
-     ((int16_t*)x)[7+(i<<1)] = -1024;
-     }
-  /*
-  for (i=0; i<2048; i+=2) {
-     ((int16_t*)x)[i<<1] = 1024;
-     ((int16_t*)x)[1+(i<<1)] = 0;
-     ((int16_t*)x)[2+(i<<1)] = -1024;
-     ((int16_t*)x)[3+(i<<1)] = 0;
-     }
-       
-  for (i=0;i<2048*2;i++) {
-    ((int16_t*)x)[i] = i/2;//(int16_t)((taus()&0xffff))>>5;
-  }
-     */
-  memset((void*)&x[0],0,64*sizeof(int32_t));
-  for (i=2;i<36;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=(128-36);i<128;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  idft64((int16_t *)x,(int16_t *)y,1);
-  
-
-  printf("64-point\n");
-  printf("X: ");
-  for (i=0;i<8;i++)
-    print_shorts256("",((int16_t *)x)+(i*16));
-
-  printf("\nY:");
-
-  for (i=0;i<8;i++)
-    print_shorts256("",((int16_t *)y)+(i*16));
-  printf("\n");
-
-  
-
-
-  idft64((int16_t *)x,(int16_t *)y,1);
-  idft64((int16_t *)x,(int16_t *)y,1);
-  idft64((int16_t *)x,(int16_t *)y,1);
-  reset_meas(&ts);
-
-  for (i=0; i<10000000; i++) {
-    start_meas(&ts);
-    idft64((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-
-  }
-  /*
-  printf("\n\n64-point (%f cycles, #trials %d)\n",(double)ts.diff/(double)ts.trials,ts.trials);
-  //  LOG_M("x64.m","x64",x,64,1,1);
-  LOG_M("y64.m","y64",y,64,1,1);
-  LOG_M("x64.m","x64",x,64,1,1);
-  */
-/*
-  printf("X: ");
-  for (i=0;i<16;i++)
-    printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&x[i])[0],((int16_t *)&x[i])[1],((int16_t*)&x[i])[2],((int16_t *)&x[i])[3],((int16_t*)&x[i])[4],((int16_t*)&x[i])[5],((int16_t*)&x[i])[6],((int16_t*)&x[i])[7]);
-  printf("\nY:");
-
-  for (i=0;i<16;i++)
-    printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&y[i])[0],((int16_t *)&y[i])[1],((int16_t*)&y[i])[2],((int16_t *)&y[i])[3],((int16_t*)&y[i])[4],((int16_t *)&y[i])[5],((int16_t*)&y[i])[6],((int16_t *)&y[i])[7]);
-  printf("\n");
-
-  idft64((int16_t*)y,(int16_t*)x,1);
-  printf("X: ");
-  for (i=0;i<16;i++)
-    printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&x[i])[0],((int16_t *)&x[i])[1],((int16_t*)&x[i])[2],((int16_t *)&x[i])[3],((int16_t*)&x[i])[4],((int16_t*)&x[i])[5],((int16_t*)&x[i])[6],((int16_t*)&x[i])[7]);
- 
-  for (i=0; i<256; i++) {
-    ((int16_t*)x)[i] = (int16_t)((taus()&0xffff))>>5;
-  }
-*/
-  
-  memset((void*)&x[0],0,128*4);
-  for (i=2;i<72;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=(256-72);i<256;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft128((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n128-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y128.m","y128",y,128,1,1);
-  LOG_M("x128.m","x128",x,128,1,1);
-/*
-  printf("X: ");
-   for (i=0;i<32;i++)
-     printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&x[i])[0],((int16_t *)&x[i])[1],((int16_t*)&x[i])[2],((int16_t *)&x[i])[3],((int16_t*)&x[i])[4],((int16_t*)&x[i])[5],((int16_t*)&x[i])[6],((int16_t*)&x[i])[7]);
-   printf("\nY:");
-
-   for (i=0;i<32;i++)
-     printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&y[i])[0],((int16_t *)&y[i])[1],((int16_t*)&y[i])[2],((int16_t *)&y[i])[3],((int16_t*)&y[i])[4],((int16_t *)&y[i])[5],((int16_t*)&y[i])[6],((int16_t *)&y[i])[7]);
-   printf("\n");
-*/
-
-  /*
-  for (i=0; i<512; i++) {
-    ((int16_t*)x)[i] = (int16_t)((taus()&0xffff))>>5;
-  }
-  
-  memset((void*)&y[0],0,256*4);
-  */
-  memset((void*)&x[0],0,256*sizeof(int32_t));
-  for (i=2;i<144;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=(512-144);i<512;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft256((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n256-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y256.m","y256",y,256,1,1);
-  LOG_M("x256.m","x256",x,256,1,1);
-
-  memset((void*)&x[0],0,512*sizeof(int32_t));
-  for (i=2;i<302;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=(1024-300);i<1024;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft512((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n512-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y512.m","y512",y,512,1,1);
-  LOG_M("x512.m","x512",x,512,1,1);
-  /*
-  printf("X: ");
-  for (i=0;i<64;i++)
-    printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&x[i])[0],((int16_t *)&x[i])[1],((int16_t*)&x[i])[2],((int16_t *)&x[i])[3],((int16_t*)&x[i])[4],((int16_t*)&x[i])[5],((int16_t*)&x[i])[6],((int16_t*)&x[i])[7]);
-  printf("\nY:");
-
-  for (i=0;i<64;i++)
-    printf("%d,%d,%d,%d,%d,%d,%d,%d,",((int16_t*)&y[i])[0],((int16_t *)&y[i])[1],((int16_t*)&y[i])[2],((int16_t *)&y[i])[3],((int16_t*)&y[i])[4],((int16_t *)&y[i])[5],((int16_t*)&y[i])[6],((int16_t *)&y[i])[7]);
-  printf("\n");
-  */
-
-  memset((void*)x,0,1024*sizeof(int32_t));
-  for (i=2;i<602;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*724;i<2048;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft1024((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n1024-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y1024.m","y1024",y,1024,1,1);
-  LOG_M("x1024.m","x1024",x,1024,1,1);
-
-
-  memset((void*)x,0,1536*sizeof(int32_t));
-  for (i=2;i<1202;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(1536-600);i<3072;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft1536((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n1536-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  write_output("y1536.m","y1536",y,1536,1,1);
-  write_output("x1536.m","x1536",x,1536,1,1);
-
-
-  memset((void*)x,0,2048*sizeof(int32_t));
-  for (i=2;i<1202;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(2048-600);i<4096;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    dft2048((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n2048-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y2048.m","y2048",y,2048,1,1);
-  LOG_M("x2048.m","x2048",x,2048,1,1);
-
-// NR 80Mhz, 217 PRB, 3/4 sampling
-  memset((void*)x, 0, 3072*sizeof(int32_t));
-  for (i=2;i<2506;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(3072-1252);i<6144;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft3072((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n3072-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  write_output("y3072.m","y3072",y,3072,1,1);
-  write_output("x3072.m","x3072",x,3072,1,1);
-
-
-  memset((void*)x,0,4096*sizeof(int32_t));
-  for (i=0;i<2400;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(4096-1200);i<8192;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft4096((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n4096-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y4096.m","y4096",y,4096,1,1);
-  LOG_M("x4096.m","x4096",x,4096,1,1);
-
-  dft4096((int16_t *)y,(int16_t *)x2,1);
-  LOG_M("x4096_2.m","x4096_2",x2,4096,1,1);
-
-// NR 160Mhz, 434 PRB, 3/4 sampling
-  memset((void*)x, 0, 6144*sizeof(int32_t));
-  for (i=2;i<5010;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(6144-2504);i<12288;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-
-  reset_meas(&ts);
-
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft6144((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n6144-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  write_output("y6144.m","y6144",y,6144,1,1);
-  write_output("x6144.m","x6144",x,6144,1,1);
-
-  memset((void*)x,0,8192*sizeof(int32_t));
-  for (i=2;i<4802;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(8192-2400);i<16384;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft8192((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n1536-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y8192.m","y8192",y,8192,1,1);
-  LOG_M("x8192.m","x8192",x,8192,1,1);
-
-  memset((void*)x,0,1536*sizeof(int32_t));
-  for (i=2;i<1202;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(1536-600);i<3072;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft1536((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n1536-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y1536.m","y1536",y,1536,1,1);
-  LOG_M("x1536.m","x1536",x,1536,1,1);
-
-  printf("\n\n1536-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y8192.m","y8192",y,8192,1,1);
-  LOG_M("x8192.m","x8192",x,8192,1,1);
-
-  memset((void*)x,0,3072*sizeof(int32_t));
-  for (i=2;i<1202;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(3072-600);i<3072;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft3072((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n3072-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y3072.m","y3072",y,3072,1,1);
-  LOG_M("x3072.m","x3072",x,3072,1,1);
-
-  memset((void*)x,0,6144*sizeof(int32_t));
-  for (i=2;i<4802;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(6144-2400);i<12288;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft6144((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n6144-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y6144.m","y6144",y,6144,1,1);
-  LOG_M("x6144.m","x6144",x,6144,1,1);
-
-  memset((void*)x,0,12288*sizeof(int32_t));
-  for (i=2;i<9602;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(12288-4800);i<24576;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft12288((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n12288-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y12288.m","y12288",y,12288,1,1);
-  LOG_M("x12288.m","x12288",x,12288,1,1);
-
-  memset((void*)x,0,18432*sizeof(int32_t));
-  for (i=2;i<14402;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(18432-7200);i<36864;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft18432((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n18432-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y18432.m","y18432",y,18432,1,1);
-  LOG_M("x18432.m","x18432",x,18432,1,1);
-
-  memset((void*)x,0,24576*sizeof(int32_t));
-  for (i=2;i<19202;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  for (i=2*(24576-19200);i<49152;i++) {
-    if ((taus() & 1)==0)
-      ((int16_t*)x)[i] = 364;
-    else
-      ((int16_t*)x)[i] = -364;
-  }
-  reset_meas(&ts);
-  for (i=0; i<10000; i++) {
-    start_meas(&ts);
-    idft24576((int16_t *)x,(int16_t *)y,1);
-    stop_meas(&ts);
-  }
-
-  printf("\n\n24576-point(%f cycles)\n",(double)ts.diff/(double)ts.trials);
-  LOG_M("y24576.m","y24576",y,24576,1,1);
-  LOG_M("x24576.m","x24576",x,24576,1,1);
-
-  int dftsizes[33]={24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,768,864,900,960,972,1080,1152,1200};
-  void (*dft)(int16_t *x,int16_t *y,uint8_t scale)[33] = {dft24,dft36,dft48,dft60,dft72,dft96,dft108,dft120,dft144,dft180,dft192,dft216,dft240,dft288,dft300,dft324,dft360,dft384,dft432,dft480,dft540,dft576,dft600,dft648,dft720,dft768,dft864,dft900,dft960,dft972,dft1080,dft1152,dft1200};
-  for (int n=0;n<33;n++) {
-    // 4xN-point DFT
-    memset((void*)x,0,dftsizes[n]*8*sizeof(int16_t));
-    for (i=0;i<dftsizes[n]*8;i+=8) {
-      if ((taus() & 1)==0)
-	((int16_t*)x)[i]   = 364;
-      else
-	((int16_t*)x)[i]   = -364;
-      if ((taus() & 1)==0)
-	((int16_t*)x)[i+1] = 364;
-      else
-	((int16_t*)x)[i+1] = -364;
-    }
-    
-    reset_meas(&ts);
-    for (i=0; i<10000; i++) {
-      start_meas(&ts);
-      (dft[n])((int16_t *)x,(int16_t *)y,1);
-      stop_meas(&ts);
-    }
-    
-    printf("\n\n4x%d-point(%f cycles)\n",dftsizes[n],(double)ts.diff/(double)ts.trials);
-    char ystr[5],xstr[5],ystr2[5],xstr2[5];
-    sprintf(ystr,"y%d.m",dftsizes[n]);
-    sprintf(xstr,"x%d.m",dftsizes[n]);
-    sprintf(ystr2,"y%d",dftsizes[n]);
-    sprintf(xstr2,"x%d",dftsizes[n]);
-    LOG_M(ystr,ystr2,y,dftsizes[n]*4,1,1);
-    LOG_M(xstr,xstr2,x,dftsizes[n]*4,1,1);
-  }
-
-
-  return(0);
-}
-
-
-#endif
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index dbcd9540be3..8621898d9d4 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -325,12 +325,18 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   // PUSCH I/Q of MF Output
   if (pusch_comp!=NULL) {
     ind=0;
+    int range=80*1000*1000;
 
     for (k=0; k<frame_parms->symbols_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++;
+        if ( pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] > -range &&
+             pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] < range  &&
+             pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] > -range &&
+             pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] < range ) {
+           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++;
+        }
       }
     }
 
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 40803c30f4f..67ec027a9d7 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -157,9 +157,9 @@ void phy_scope_gNB(FD_phy_scope_gnb *form,
 {
   int i, arx; //int i,i2,arx,atx,ind,k;
   NR_DL_FRAME_PARMS *frame_parms = &phy_vars_gnb->frame_parms;
-  int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti;
+  //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
+  //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, **rxsig_f;
   // int16_t **chest_t=NULL;
   // int16_t **chest_f=NULL;
@@ -182,7 +182,7 @@ void phy_scope_gNB(FD_phy_scope_gnb *form,
   int Qm = 2;
 
   /*
-  if (!RC.nrmac[0]->UE_list.active[UE_id])
+  if (!RC.nrmac[0]->UE_info.active[UE_id])
     return;
   
   // choose max MCS to compute coded_bits_per_codeword
@@ -966,7 +966,7 @@ FD_stats_form * create_form_stats_form( void ) {
 }
 
 void startScope(scopeParms_t * p) {
-  FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
+  //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
   char title[255];
   fl_initialize (p->argc, p->argv, NULL, 0, 0);
   /*
diff --git a/openair1/PHY/TOOLS/smbv.h b/openair1/PHY/TOOLS/smbv.h
index ef40a9ed7d0..f8fab67d014 100644
--- a/openair1/PHY/TOOLS/smbv.h
+++ b/openair1/PHY/TOOLS/smbv.h
@@ -23,6 +23,8 @@
   This library offers some functions to remotely program the R&S SMBV100A.
 */
 
+#ifndef __PHY_TOOLS_SMBV__H__
+#define __PHY_TOOLS_SMBV__H__
 
 #include <string.h>
 #include <stdio.h>
@@ -93,3 +95,4 @@ int smbv_configure_common_dci(const char* fname, uint8_t subframe, const char* t
 // item is the row in the DCI table
 int smbv_configure_ue_spec_dci(const char* fname, uint8_t subframe, uint8_t user, DCI_ALLOC_t *dci_alloc, uint8_t item);
 #endif
+#endif
diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h
index b9777686eac..2deab40f27f 100644
--- a/openair1/PHY/TOOLS/time_meas.h
+++ b/openair1/PHY/TOOLS/time_meas.h
@@ -33,7 +33,7 @@
 #include <linux/types.h>
 // global var to enable openair performance profiler
 extern int opp_enabled;
-double cpu_freq_GHz;
+double cpu_freq_GHz  __attribute__ ((aligned(32)));;
 
 #if defined(__x86_64__) || defined(__i386__)
 typedef struct {
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index d753b501b6e..61ea785db82 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -36,6 +36,8 @@ extern "C" {
 #include <stdint.h>
 #include "PHY/sse_intrin.h"
 
+#define CEILIDIV(a,b) ((a+b-1)/b)
+#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
 
 struct complex {
   double x;
@@ -179,44 +181,144 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
         );
 */
 
-void idft1536(int16_t *sigF,int16_t *sig,int scale);
 
-void idft6144(int16_t *sigF,int16_t *sig,int scale);
 
-void idft12288(int16_t *sigF,int16_t *sig,int scale);
 
-void idft18432(int16_t *sigF,int16_t *sig,int scale);
 
-void idft3072(int16_t *sigF,int16_t *sig,int scale);
 
-void idft24576(int16_t *sigF,int16_t *sig,int scale);
 
-void dft1536(int16_t *sigF,int16_t *sig,int scale);
+#ifdef OAIDFTS_MAIN
+typedef  void(*adftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
+typedef  void(*aidftfunc_t)(int16_t *sigF,int16_t *sig,unsigned char scale_flag);     
 
-void dft3072(int16_t *sigF,int16_t *sig,int scale);
-
-void dft6144(int16_t *sigF,int16_t *sig,int scale);
-
-void dft12288(int16_t *sigF,int16_t *sig,int scale);
-
-void dft18432(int16_t *sigF,int16_t *sig,int scale);
-
-void dft24576(int16_t *sigF,int16_t *sig,int scale);
-
-void dft49152(int16_t *sigF,int16_t *sig,int scale);
-void idft49152(int16_t *sigF,int16_t *sig,int scale);
-
-void dft9216(int16_t *sigF,int16_t *sig,int scale);
-void idft9216(int16_t *sigF,int16_t *sig,int scale);
+void dft12(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft48(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft60(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft64(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft72(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft96(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft108(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft120(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft128(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft144(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft180(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft192(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft216(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft240(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft256(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft288(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft300(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft324(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft360(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft384(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft432(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft480(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft512(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft540(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft576(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft600(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft648(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft720(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft768(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft864(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft900(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft960(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft972(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
+void dft12288(int16_t *x,int16_t *y,uint8_t scale_flag);  
+void dft18432(int16_t *x,int16_t *y,uint8_t scale_flag); 
+void dft24576(int16_t *x,int16_t *y,uint8_t scale_flag); 
+void dft36864(int16_t *x,int16_t *y,uint8_t scale_flag); 
+void dft49152(int16_t *x,int16_t *y,uint8_t scale_flag); 
+void dft73728(int16_t *x,int16_t *y,uint8_t scale_flag); 
+void dft98304(int16_t *x,int16_t *y,uint8_t scale_flag);
+
+
+void idft64(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft128(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft256(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft512(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft1024(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft2048(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft4096(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft8192(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft9216(int16_t *x,int16_t *y,uint8_t scale_flag);
+void idft12288(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft18432(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft24576(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft36864(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft49152(int16_t *sigF,int16_t *sig,uint8_t scale_flag); 
+void idft73728(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+void idft98304(int16_t *sigF,int16_t *sig,uint8_t scale_flag);
+
+
+
+
+#else
+  typedef  void(*dftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
+  typedef  void(*idftfunc_t)(uint8_t sizeidx,int16_t *sigF,int16_t *sig,unsigned char scale_flag);  
+#  ifdef OAIDFTS_LOADER
+  dftfunc_t dft;
+  idftfunc_t idft;
+#  else
+  extern dftfunc_t dft;
+  extern idftfunc_t idft;
+  extern int load_dftslib(void);
+#  endif
+#endif
 
-void dft36864(int16_t *sigF,int16_t *sig,int scale);
-void idft36864(int16_t *sigF,int16_t *sig,int scale);
+typedef enum DFT_size_idx {
+	DFT_12,    DFT_24,    DFT_36,   DFT_48,     DFT_60,   DFT_72,   DFT_96,
+	DFT_108,   DFT_120,   DFT_128,  DFT_144,    DFT_180,  DFT_192,  DFT_216,   DFT_240,
+	DFT_256,   DFT_288,   DFT_300,  DFT_324,    DFT_360,  DFT_384,  DFT_432,   DFT_480,
+	DFT_512,   DFT_540,   DFT_576,  DFT_600,    DFT_648,  DFT_720,  DFT_768,   DFT_864,
+	DFT_900,   DFT_960,   DFT_972,  DFT_1024,   DFT_1080, DFT_1152, DFT_1200,  DFT_1536,
+	DFT_2048,  DFT_3072,  DFT_4096, DFT_6144,   DFT_8192, DFT_9216, DFT_12288, DFT_18432, 
+	DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304,
+	DFT_SIZE_IDXTABLESIZE
+} dft_size_idx_t;
+
+#ifdef OAIDFTS_MAIN
+adftfunc_t dft_ftab[]={
+	dft12,    dft24,    dft36,    dft48,    dft60,   dft72,   dft96,
+	dft108,   dft120,   dft128,   dft144,   dft180,  dft192,  dft216,   dft240,   
+	dft256,   dft288,   dft300,   dft324,   dft360,  dft384,  dft432,   dft480,
+	dft512,   dft540,   dft576,   dft600,   dft648,  dft720,  dft768,   dft864,
+	dft900,   dft960,   dft972,   dft1024,  dft1080, dft1152, dft1200,  dft1536,
+	dft2048,  dft3072,  dft4096,  dft6144,  dft8192, dft9216, dft12288, dft18432, 
+	dft24576, dft36864, dft49152, dft73728, dft98304
+};
+#endif
 
-void dft98304(int16_t *sigF,int16_t *sig,int scale);
-void idft98304(int16_t *sigF,int16_t *sig,int scale);
+typedef enum idft_size_idx {
+	IDFT_128,   IDFT_256,  IDFT_512,   IDFT_1024,  IDFT_1536,  IDFT_2048,  IDFT_3072,  IDFT_4096,
+	IDFT_6144,  IDFT_8192, IDFT_9216,  IDFT_12288, IDFT_18432, IDFT_24576, IDFT_36864, IDFT_49152, 
+	IDFT_73728, IDFT_98304, 
+	IDFT_SIZE_IDXTABLESIZE
+} idft_size_idx_t;
+#ifdef OAIDFTS_MAIN
+aidftfunc_t idft_ftab[]={
+        idft128,   idft256,  idft512,   idft1024,  idft1536,  idft2048,  idft3072,  idft4096,
+	    idft6144,  idft8192, idft9216,  idft12288, idft18432, idft24576, idft36864, idft49152, 
+	    idft73728, idft98304
+};
+#endif
 
-void dft73728(int16_t *sigF,int16_t *sig,int scale);
-void idft73728(int16_t *sigF,int16_t *sig,int scale);
 
 
 /*!\fn int32_t rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift)
@@ -387,57 +489,7 @@ int64_t dot_product64(int16_t *x,
                       uint32_t N, //must be a multiple of 8
                       uint8_t output_shift);
 
-void dft12(int16_t *x,int16_t *y);
-void dft24(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft36(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft48(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft60(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft72(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft96(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft108(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft120(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft144(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft180(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft192(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft216(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft240(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft288(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft300(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft324(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft360(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft384(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft432(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft480(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft540(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft576(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft600(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft648(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft720(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft768(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft864(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft900(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft960(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft972(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag);
-void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag);
 
-void dft64(int16_t *x,int16_t *y,int scale);
-void dft128(int16_t *x,int16_t *y,int scale);
-void dft256(int16_t *x,int16_t *y,int scale);
-void dft512(int16_t *x,int16_t *y,int scale);
-void dft1024(int16_t *x,int16_t *y,int scale);
-void dft2048(int16_t *x,int16_t *y,int scale);
-void dft4096(int16_t *x,int16_t *y,int scale);
-void dft8192(int16_t *x,int16_t *y,int scale);
-void idft64(int16_t *x,int16_t *y,int scale);
-void idft128(int16_t *x,int16_t *y,int scale);
-void idft256(int16_t *x,int16_t *y,int scale);
-void idft512(int16_t *x,int16_t *y,int scale);
-void idft1024(int16_t *x,int16_t *y,int scale);
-void idft2048(int16_t *x,int16_t *y,int scale);
-void idft4096(int16_t *x,int16_t *y,int scale);
-void idft8192(int16_t *x,int16_t *y,int scale);
 /** @} */
 
 
diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h
index f0fd7661c71..1f8c0b8eeec 100644
--- a/openair1/PHY/defs_L1_NB_IoT.h
+++ b/openair1/PHY/defs_L1_NB_IoT.h
@@ -148,11 +148,7 @@ static inline void* malloc16_clear( size_t size )
 #define NB_BANDS_MAX_NB_IoT 8
 
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
 typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t;
-#endif
 /*
 enum transmission_access_mode {
   NO_ACCESS=0,
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index 10496ced20d..ce808eddf9f 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -38,15 +38,13 @@
 #include "openairinterface5g_limits.h"
 #include "PHY/TOOLS/time_meas.h"
 #include "defs_common.h"
+#include <openair2/PHY_INTERFACE/IF_Module.h>
 
 
 #define MAX_BANDS_PER_RRU 4
 #define MAX_RRU_CONFIG_SIZE 1024
 
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
 
 typedef enum {
   normal_txrx=0,
@@ -92,7 +90,6 @@ typedef enum {
   synch_to_other,          // synch to another source_(timer, other RU)
   synch_to_mobipass_standalone  // special case for mobipass in standalone mode
 } node_timing_t;
-#endif
 
 
 typedef struct {
@@ -540,6 +537,8 @@ typedef struct RU_t_s {
   void (*wakeup_prach_gNB)(struct PHY_VARS_gNB_s *gNB, struct RU_t_s *ru, int frame, int subframe);
   /// function pointer to wakeup routine in lte-enb.
   void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru, int frame, int subframe);
+  /// function pointer to start a thread of tx write for USRP.
+  int (*start_write_thread)(struct RU_t_s *ru);
 
   /// function pointer to NB entry routine
   void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru);
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index f52558b6320..75b2d54dc69 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -99,9 +99,6 @@
 
 #define NB_RX_ANTENNAS_MAX 64
 
-#ifdef OCP_FRAMEWORK
-#include "enums.h"
-#else
 
 typedef enum {TDD=1,FDD=0} lte_frame_type_t;
 
@@ -122,7 +119,6 @@ typedef enum {
   one=6,
   two=12
 } PHICH_RESOURCE_t;
-#endif
 /// PHICH-Config from 36.331 RRC spec
 typedef struct {
   /// Parameter: PHICH-Duration, see TS 36.211 (Table 6.9.3-1).
@@ -250,12 +246,10 @@ typedef struct {
 } UL_REFERENCE_SIGNALS_PUSCH_t;
 
 /// Enumeration for parameter Hopping-mode \ref PUSCH_CONFIG_COMMON::hoppingMode.
-#ifndef OCP_FRAMEWORK
 typedef enum {
   interSubFrame=0,
   intraAndInterSubFrame=1
 } PUSCH_HOPPING_t;
-#endif
 
 /// PUSCH-ConfigCommon from 36.331 RRC spec.
 typedef struct {
@@ -434,7 +428,6 @@ typedef struct {
   uint8_t filterCoefficient;
 } UL_POWER_CONTROL_DEDICATED;
 
-#ifndef OCP_FRAMEWORK
 /// Enumeration for parameter \f$\alpha\f$ \ref UL_POWER_CONTROL_CONFIG_COMMON::alpha.
 typedef enum {
   al0=0,
@@ -446,7 +439,6 @@ typedef enum {
   al09=6,
   al1=7
 } PUSCH_alpha_t;
-#endif
 
 /// \note UNUSED
 typedef enum {
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index 7b06f6c8c70..557b8bfc30e 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -201,41 +201,11 @@ typedef struct {
   int repetition_number[4];
 } LTE_eNB_PRACH;
 
-/// Context data structure for RX/TX portion of subframe processing
-typedef struct {
-  /// Component Carrier index
-  uint8_t CC_id;
-  /// timestamp transmitted to HW
-  openair0_timestamp timestamp_tx;
-  /// subframe to act upon for transmission
-  int subframe_tx;
-  /// subframe to act upon for reception
-  int subframe_rx;
-  /// frame to act upon for transmission
-  int frame_tx;
-  /// frame to act upon for reception
-  int frame_rx;
-  /// \brief Instance count for RXn-TXnp4 processing thread.
-  /// \internal This variable is protected by \ref mutex_rxtx.
-  int instance_cnt;
-  /// pthread structure for RXn-TXnp4 processing thread
-  pthread_t pthread;
-  /// pthread attributes for RXn-TXnp4 processing thread
-  pthread_attr_t attr;
-  /// condition variable for tx processing thread
-  pthread_cond_t cond;
-  /// mutex for RXn-TXnp4 processing thread
-  pthread_mutex_t mutex;
-  /// scheduling parameters for RXn-TXnp4 thread
-  struct sched_param sched_param_rxtx;
-
-  /// \internal This variable is protected by \ref mutex_RUs.
-  int instance_cnt_RUs;
-  /// condition variable for tx processing thread
-  pthread_cond_t cond_RUs;
-  /// mutex for RXn-TXnp4 processing thread
-  pthread_mutex_t mutex_RUs;
-} L1_rxtx_proc_t;
+#include "PHY/TOOLS/time_meas.h"
+#include "PHY/CODING/coding_defs.h"
+#include "PHY/TOOLS/tools_defs.h"
+#include "PHY/LTE_TRANSPORT/transport_eNB.h"
+
 
 typedef struct {
   struct PHY_VARS_eNB_s *eNB;
@@ -694,6 +664,57 @@ 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];
+  uint8_t *FS6bufferZone;
 } PHY_VARS_eNB;
 
+
+struct turboReqId {
+    uint16_t rnti;
+    uint16_t frame;
+    uint8_t  subframe;
+    uint8_t  codeblock;
+    uint16_t spare;
+} __attribute__((packed));
+
+union turboReqUnion {
+    struct turboReqId s;
+    uint64_t p;
+};
+
+typedef struct TurboDecode_s {
+    PHY_VARS_eNB *eNB;
+    decoder_if_t *function;
+    uint8_t decoded_bytes[3+1768] __attribute__((aligned(32)));
+    int UEid;
+    int harq_pid;
+    int frame;
+    int subframe;
+    int Fbits;
+    int Kr;
+    LTE_UL_eNB_HARQ_t *ulsch_harq;
+    int nbSegments;
+    int segment_r;
+    int r_offset;
+    int offset;
+    int maxIterations;
+    int decodeIterations;
+} turboDecode_t;
+
+#define TURBO_SIMD_SOFTBITS   96+12+3+3*6144
+typedef struct turboEncode_s {
+  uint8_t * input;
+  int Kr_bytes;
+  int filler;
+  unsigned int G;
+  int r;
+  int harq_pid;
+  int round;
+  int r_offset;
+  LTE_eNB_DLSCH_t *dlsch;
+  time_stats_t *rm_stats;
+  time_stats_t *te_stats;
+  time_stats_t *i_stats;
+} turboEncode_t;
+
+
 #endif /* __PHY_DEFS_ENB__H__ */
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index b5a24ca7938..aa794da818c 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -44,6 +44,13 @@
 #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
 
 #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
+#define MAX_PUCCH0_NID 8
+
+typedef struct {
+  int nb_id;
+  int Nid[MAX_PUCCH0_NID];
+  int lut[MAX_PUCCH0_NID][160][14];
+} NR_gNB_PUCCH0_LUT_t;
 
 typedef struct {
   uint32_t pbch_a;
@@ -561,13 +568,13 @@ typedef struct {
   //! estimated avg noise power (dB)
   short n0_power_tot_dBm;
   //! estimated avg noise power per RB per RX ant (lin)
-  unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][100];
+  unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][275];
   //! estimated avg noise power per RB per RX ant (dB)
-  unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][100];
+  unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][275];
   //! estimated avg noise power per RB (dB)
-  short n0_subband_power_tot_dB[100];
+  short n0_subband_power_tot_dB[275];
   //! estimated avg noise power per RB (dBm)
-  short n0_subband_power_tot_dBm[100];
+  short n0_subband_power_tot_dBm[275];
   // gNB measurements (per user)
   //! estimated received spatial signal power (linear)
   unsigned int   rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2];
@@ -587,17 +594,23 @@ typedef struct {
   /// Wideband CQI (sum of all RX antennas, in dB)
   char           wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX];
   /// Subband CQI per RX antenna and RB (= SINR)
-  int            subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100];
+  int            subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275];
   /// Total Subband CQI and RB (= SINR)
-  int            subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][100];
+  int            subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][275];
   /// Subband CQI in dB and RB (= SINR dB)
-  int            subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100];
+  int            subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275];
   /// Total Subband CQI and RB
-  int            subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][100];
+  int            subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][275];
   /// PRACH background noise level
   int            prach_I0;
 } PHY_MEASUREMENTS_gNB;
 
+#define MAX_NUM_NR_RX_RACH_PDUS 4
+#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4
+#define MAX_UL_PDUS_PER_SLOT 100
+#define MAX_NUM_NR_SRS_PDUS 100
+#define MAX_NUM_NR_UCI_PDUS 100
+
 /// Top-level PHY Data Structure for gNB
 typedef struct PHY_VARS_gNB_s {
   /// Module ID indicator for this instance
@@ -624,22 +637,21 @@ typedef struct PHY_VARS_gNB_s {
   pthread_mutex_t      UL_INFO_mutex;
 
   /// NFAPI RX ULSCH information
-  nfapi_rx_indication_pdu_t  rx_pdu_list[NFAPI_RX_IND_MAX_PDU];
+  nfapi_nr_rx_data_pdu_t  rx_pdu_list[MAX_UL_PDUS_PER_SLOT];
   /// NFAPI RX ULSCH CRC information
-  nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU];
-  /// NFAPI HARQ information
-  nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU];
-  /// NFAPI SR information
-  nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU];
-  /// NFAPI CQI information
-  nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU];
-  /// NFAPI CQI information (raw component)
-  nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU];
+  nfapi_nr_crc_t crc_pdu_list[MAX_UL_PDUS_PER_SLOT];
+  /// NFAPI SRS information
+  nfapi_nr_srs_indication_pdu_t srs_pdu_list[MAX_NUM_NR_SRS_PDUS];
+  /// NFAPI UCI information
+  nfapi_nr_uci_t uci_pdu_list[MAX_NUM_NR_UCI_PDUS];
+  /// NFAPI PRACH information
+  nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS];
   /// NFAPI PRACH information
-  nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES];
+  nfapi_nr_prach_indication_preamble_t preamble_list[MAX_NUM_NR_RX_PRACH_PREAMBLES];
 
   //Sched_Rsp_t         Sched_INFO;
   nfapi_nr_ul_tti_request_t     UL_tti_req;
+  nfapi_nr_uci_indication_t uci_indication;
   
   nfapi_nr_dl_tti_pdcch_pdu    *pdcch_pdu;
   nfapi_nr_ul_dci_request_pdus_t  *ul_dci_pdu;
@@ -658,6 +670,8 @@ typedef struct PHY_VARS_gNB_s {
   uint8_t pbch_configured;
   char gNB_generate_rar;
 
+  // PUCCH0 Look-up table for cyclic-shifts
+  NR_gNB_PUCCH0_LUT_t pucch0_lut;
   /// NR synchronization sequences
   int16_t d_pss[NR_PSS_LENGTH];
   int16_t d_sss[NR_SSS_LENGTH];
@@ -709,13 +723,12 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
+  int pucch0_thres;
   /*
   time_stats_t phy_proc;
   */
   time_stats_t phy_proc_tx;
-  /*
   time_stats_t phy_proc_rx;
-  */
   time_stats_t rx_prach;
   /*
   time_stats_t ofdm_mod_stats;
@@ -731,18 +744,21 @@ typedef struct PHY_VARS_gNB_s {
   time_stats_t dlsch_rate_matching_stats;
   time_stats_t dlsch_interleaving_stats;
   time_stats_t dlsch_segmentation_stats;
-  /*
-  time_stats_t rx_dft_stats;
-  time_stats_t ulsch_channel_estimation_stats;
-  time_stats_t ulsch_freq_offset_estimation_stats;
+
   time_stats_t ulsch_decoding_stats;
-  time_stats_t ulsch_demodulation_stats;
   time_stats_t ulsch_rate_unmatching_stats;
-  time_stats_t ulsch_turbo_decoding_stats;
+  time_stats_t ulsch_ldpc_decoding_stats;
   time_stats_t ulsch_deinterleaving_stats;
-  time_stats_t ulsch_demultiplexing_stats;
+  time_stats_t ulsch_unscrambling_stats;
+  time_stats_t ulsch_channel_estimation_stats;
+  time_stats_t ulsch_channel_compensation_stats;
+  time_stats_t ulsch_rbs_extraction_stats;
   time_stats_t ulsch_llr_stats;
+  /*
+  time_stats_t rx_dft_stats;
+  time_stats_t ulsch_freq_offset_estimation_stats;
   */
+
 } PHY_VARS_gNB;
 
 #endif
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 6f6c5ac8e9a..b2d6a75265e 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -954,9 +954,6 @@ typedef struct {
   /// PUSCH DMRS sequence
   uint32_t ****nr_gold_pusch_dmrs;
 
-  /// flag to indicate if PTRS is configured
-  uint8_t ptrs_configured;
-
   uint32_t X_u[64][839];
 
   uint32_t high_speed_flag;
diff --git a/openair1/PHY/phy_extern.h b/openair1/PHY/phy_extern.h
index deb7087c8cf..165ed961b30 100644
--- a/openair1/PHY/phy_extern.h
+++ b/openair1/PHY/phy_extern.h
@@ -38,7 +38,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
 extern unsigned int DAQ_MBOX;
 extern int number_of_cards;
 
-extern short conjugate[8],conjugate2[8];
+extern const short conjugate[8],conjugate2[8];
 
 extern RAN_CONTEXT_t RC;
 
@@ -73,8 +73,8 @@ extern int flag_LA;
 extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
 extern double sinr_bler_map_up[MCS_COUNT][2][16];
 extern int table_length[MCS_COUNT];
-extern double sinr_to_cqi[4][16];
-extern int cqi_to_mcs[16];
+extern const double sinr_to_cqi[4][16];
+extern const int cqi_to_mcs[16];
 
 //for MU-MIMO abstraction using MIESM
 //this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
@@ -82,23 +82,22 @@ extern double MI_map_4qam[3][162];
 extern double MI_map_16qam[3][197];
 extern double MI_map_64qam[3][227];
 
-extern double beta1_dlsch_MI[6][MCS_COUNT];
-extern double beta2_dlsch_MI[6][MCS_COUNT];
+extern const double beta1_dlsch_MI[6][MCS_COUNT];
+extern const double beta2_dlsch_MI[6][MCS_COUNT];
 
-extern double q_qpsk[8];
-extern double q_qam16[8];
-extern double q_qam64[8];
+extern const double q_qpsk[8];
+extern const double q_qam16[8];
+extern const double q_qam64[8];
+extern const double p_qpsk[8];
+extern const double p_qam16[8];
+extern const double p_qam64[8];
 
-extern double p_qpsk[8];
-extern double p_qam16[8];
-extern double p_qam64[8];
+extern const double beta1_dlsch[6][MCS_COUNT];
+extern const double beta2_dlsch[6][MCS_COUNT];
 
-extern double beta1_dlsch[6][MCS_COUNT];
-extern double beta2_dlsch[6][MCS_COUNT];
-
-extern char NB_functions[7][20];
-extern char NB_timing[2][20];
-extern char ru_if_types[MAX_RU_IF_TYPES][20];
+extern const char NB_functions[7][20];
+extern const char NB_timing[2][20];
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
 
 extern int16_t unscrambling_lut[65536*16];
 extern uint8_t scrambling_lut[65536*16];
diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h
index 569bec68515..2f2a0427f41 100644
--- a/openair1/PHY/phy_extern_nr_ue.h
+++ b/openair1/PHY/phy_extern_nr_ue.h
@@ -34,7 +34,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
 
 //#include "PHY/LTE_TRANSPORT/transport_extern.h"
 
-extern short conjugate[8],conjugate2[8];
+extern const short conjugate[8],conjugate2[8];
 extern int number_of_cards;
 
 
@@ -70,8 +70,8 @@ extern int flag_LA;
 extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
 extern double sinr_bler_map_up[MCS_COUNT][2][16];
 extern int table_length[MCS_COUNT];
-extern double sinr_to_cqi[4][16];
-extern int cqi_to_mcs[16];
+extern const double sinr_to_cqi[4][16];
+extern const int cqi_to_mcs[16];
 
 //for MU-MIMO abstraction using MIESM
 //this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
@@ -79,23 +79,19 @@ extern double MI_map_4qam[3][162];
 extern double MI_map_16qam[3][197];
 extern double MI_map_64qam[3][227];
 
-extern double beta1_dlsch_MI[6][MCS_COUNT];
-extern double beta2_dlsch_MI[6][MCS_COUNT];
+extern const double beta1_dlsch_MI[6][MCS_COUNT];
+extern const double beta2_dlsch_MI[6][MCS_COUNT];
 
-extern double q_qpsk[8];
-extern double q_qam16[8];
-extern double q_qam64[8];
+extern const double q_qpsk[8];
+extern const double q_qam16[8];
+extern const double q_qam64[8];
 
-extern double p_qpsk[8];
-extern double p_qam16[8];
-extern double p_qam64[8];
+extern const double beta1_dlsch[6][MCS_COUNT];
+extern const double beta2_dlsch[6][MCS_COUNT];
 
-extern double beta1_dlsch[6][MCS_COUNT];
-extern double beta2_dlsch[6][MCS_COUNT];
-
-extern char NB_functions[7][20];
-extern char NB_timing[2][20];
-extern char ru_if_types[MAX_RU_IF_TYPES][20];
+extern const char NB_functions[7][20];
+extern const char NB_timing[2][20];
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
 
 extern int16_t unscrambling_lut[65536*16];
 extern uint8_t scrambling_lut[65536*16];
diff --git a/openair1/PHY/phy_extern_ue.h b/openair1/PHY/phy_extern_ue.h
index 4f9ed0f26be..622551c2fe9 100644
--- a/openair1/PHY/phy_extern_ue.h
+++ b/openair1/PHY/phy_extern_ue.h
@@ -36,7 +36,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
 
 extern int number_of_cards;
 
-extern short conjugate[8],conjugate2[8];
+extern const short conjugate[8],conjugate2[8];
 
 
 extern PHY_VARS_UE ***PHY_vars_UE_g;
@@ -70,8 +70,8 @@ extern int flag_LA;
 extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
 extern double sinr_bler_map_up[MCS_COUNT][2][16];
 extern int table_length[MCS_COUNT];
-extern double sinr_to_cqi[4][16];
-extern int cqi_to_mcs[16];
+extern const double sinr_to_cqi[4][16];
+extern const int cqi_to_mcs[16];
 
 //for MU-MIMO abstraction using MIESM
 //this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
@@ -79,23 +79,23 @@ extern double MI_map_4qam[3][162];
 extern double MI_map_16qam[3][197];
 extern double MI_map_64qam[3][227];
 
-extern double beta1_dlsch_MI[6][MCS_COUNT];
-extern double beta2_dlsch_MI[6][MCS_COUNT];
+extern const double beta1_dlsch_MI[6][MCS_COUNT];
+extern const double beta2_dlsch_MI[6][MCS_COUNT];
 
-extern double q_qpsk[8];
-extern double q_qam16[8];
-extern double q_qam64[8];
+extern const double q_qpsk[8];
+extern const double q_qam16[8];
+extern const double q_qam64[8];
 
-extern double p_qpsk[8];
-extern double p_qam16[8];
-extern double p_qam64[8];
+extern const double p_qpsk[8];
+extern const double p_qam16[8];
+extern const double p_qam64[8];
 
-extern double beta1_dlsch[6][MCS_COUNT];
-extern double beta2_dlsch[6][MCS_COUNT];
+extern const double beta1_dlsch[6][MCS_COUNT];
+extern const double beta2_dlsch[6][MCS_COUNT];
 
-extern char NB_functions[7][20];
-extern char NB_timing[2][20];
-extern char ru_if_types[MAX_RU_IF_TYPES][20];
+extern const char NB_functions[7][20];
+extern const char NB_timing[2][20];
+extern const char ru_if_types[MAX_RU_IF_TYPES][20];
 
 extern int16_t unscrambling_lut[65536*16];
 extern uint8_t scrambling_lut[65536*16];
diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h
index 26540f6fc88..a74d148479d 100644
--- a/openair1/PHY/phy_vars.h
+++ b/openair1/PHY/phy_vars.h
@@ -50,8 +50,8 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
 unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
 
 
-short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
-short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 
 #include "SIMULATION/ETH_TRANSPORT/vars.h"
@@ -84,29 +84,29 @@ double MI_map_16qam[3][197];
 double MI_map_64qam[3][227];
 
 // here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs
-double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
+const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
   {-2.2360, -2.2360, -1.3919, -0.0218, 1.5319,  2.9574,  4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572},
   {-1, -1.0000, -0.4198, -0.0140, 1.0362,  2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392},
   { -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
 };
 
 //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
-int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
+const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
 
 //for SNR to MI conversion 7 th order Polynomial coeff
-double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
-double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
-double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
+const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
+const double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
+const double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
 
 //for MI to SNR conversion 7 th order Polynomial coeff
-double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
-double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
-double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
+const double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
+const double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
+const double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
 
 // ideal CE MIESM
 
-double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
-double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
+const double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
+const double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
 
 //real CE MIESM
 /*
@@ -116,8 +116,8 @@ double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.8
 //ideal channel estimation values
 //double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
 //double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
-double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
-double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
+const double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
+const double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
 
 //real channel estimation valus
 /*
@@ -126,13 +126,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
 
 */
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
-char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
-char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
-char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
-#endif
+const char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
+const char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
+const char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
 
 /// lookup table for unscrambling in RX
 int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h
index bd077b5b0c7..1843d8d5bcd 100644
--- a/openair1/PHY/phy_vars_nr_ue.h
+++ b/openair1/PHY/phy_vars_nr_ue.h
@@ -49,8 +49,8 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
 unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
 
 
-short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
-short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 
 #include "SIMULATION/ETH_TRANSPORT/vars.h"
@@ -84,29 +84,29 @@ double MI_map_16qam[3][197];
 double MI_map_64qam[3][227];
 
 // here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs
-double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
+const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
   {-2.2360, -2.2360, -1.3919, -0.0218, 1.5319,  2.9574,  4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572},
   {-1, -1.0000, -0.4198, -0.0140, 1.0362,  2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392},
   { -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
 };
 
 //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
-int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
+const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
 
 //for SNR to MI conversion 7 th order Polynomial coeff
-double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
-double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
-double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
+const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
+const double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
+const double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
 
 //for MI to SNR conversion 7 th order Polynomial coeff
-double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
-double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
-double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
+const double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
+const double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
+const double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
 
 // ideal CE MIESM
 
-double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
-double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
+const double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
+const double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
 
 //real CE MIESM
 /*
@@ -116,8 +116,8 @@ double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.8
 //ideal channel estimation values
 //double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
 //double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
-double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
-double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
+const double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
+const double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
 
 //real channel estimation valus
 /*
@@ -126,13 +126,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
 
 */
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
-char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
-char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
-char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
-#endif
+const char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
+const char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
+const char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
 
 /// lookup table for unscrambling in RX
 int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h
index 05f2e1b8f19..e90c2641aa7 100644
--- a/openair1/PHY/phy_vars_ue.h
+++ b/openair1/PHY/phy_vars_ue.h
@@ -19,8 +19,8 @@
  *      contact@openairinterface.org
  */
 
-#ifndef __PHY_VARS_H__
-#define __PHY_VARS_H__
+#ifndef __PHY_VARS_UE__H__
+#define __PHY_VARS_UE__H__
 
 #include "PHY/types.h"
 #include "PHY/defs_UE.h"
@@ -43,8 +43,8 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
 unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
 
 
-short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
-short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
+const short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 
 #include "SIMULATION/ETH_TRANSPORT/vars.h"
@@ -77,29 +77,29 @@ double MI_map_16qam[3][197];
 double MI_map_64qam[3][227];
 
 // here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs
-double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
+const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281,  17.2424,  17.2424, 17.2424},
   {-2.2360, -2.2360, -1.3919, -0.0218, 1.5319,  2.9574,  4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572},
   {-1, -1.0000, -0.4198, -0.0140, 1.0362,  2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392},
   { -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
 };
 
 //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
-int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
+const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
 
 //for SNR to MI conversion 7 th order Polynomial coeff
-double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
-double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
-double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
+const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
+const double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
+const double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
 
 //for MI to SNR conversion 7 th order Polynomial coeff
-double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
-double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
-double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
+const double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
+const double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
+const double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
 
 // ideal CE MIESM
 
-double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
-double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
+const double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
+const double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},  {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
 
 //real CE MIESM
 /*
@@ -109,8 +109,8 @@ double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.8
 //ideal channel estimation values
 //double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
 //double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
-double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
-double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
+const double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
+const double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
 
 //real channel estimation valus
 /*
@@ -119,13 +119,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
 
 */
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
-char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
-char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
-char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
-#endif
+const char NB_functions[7][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5","gNodeB_3GPP",};
+const char NB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
+const char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
 
 /// lookup table for unscrambling in RX
 int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
@@ -133,4 +129,4 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
 uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
 
 uint8_t max_turbo_iterations=4;
-#endif /*__PHY_VARS_H__ */
+#endif /* __PHY_VARS_UE__H__ */
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 8105877bc34..96a073fbb8c 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -596,7 +596,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,
   uci->frame               = frame;
   uci->subframe            = subframe;
   uci->rnti                = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
-  uci->ue_id               = find_dlsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
+  uci->ue_id               = find_ulsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
   uci->type                = SR;
   uci->pucch_fmt           = pucch_format1;
   uci->num_antenna_ports   = 1;
@@ -622,7 +622,7 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_
   uci->frame               = frame;
   uci->subframe            = subframe;
   uci->rnti                = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
-  uci->ue_id               = find_dlsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
+  uci->ue_id               = find_ulsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
   uci->type                = HARQ_SR;
   uci->num_antenna_ports   = 1;
   uci->num_pucch_resources = 1;
@@ -644,7 +644,7 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
   uci->frame             = frame;
   uci->subframe          = subframe;
   uci->rnti              = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
-  uci->ue_id             = find_dlsch(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
+  uci->ue_id             = find_ulsch(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
   uci->type              = HARQ;
   uci->srs_active        = srs_active;
   uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports;
@@ -732,7 +732,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
   } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) {
     AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n");
   } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) {
-    AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,
+  AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,
                                   proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0,
                 "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti);
     handle_uci_sr_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present);
@@ -745,9 +745,8 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
   }
 }
 
-void schedule_response(Sched_Rsp_t *Sched_INFO) {
+void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
   PHY_VARS_eNB *eNB;
-  L1_rxtx_proc_t *proc;
   // copy data from L2 interface into L1 structures
   module_id_t               Mod_id       = Sched_INFO->module_id;
   uint8_t                   CC_id        = Sched_INFO->CC_id;
@@ -767,7 +766,6 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id);
   eNB         = RC.eNB[Mod_id][CC_id];
   fp          = &eNB->frame_parms;
-  proc        = &eNB->proc.L1_proc;
   /* TODO: check that following line is correct - in the meantime it is disabled */
   //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
   ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
@@ -1020,11 +1018,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 
 /*Dummy functions*/
 
-int memcpy_dl_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
+int memcpy_dl_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
   return 0;
 }
 
-int memcpy_ul_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
+int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
   return 0;
 }
 
diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h
index 05ec813917b..4da1fa63ec5 100644
--- a/openair1/SCHED/fapi_l1.h
+++ b/openair1/SCHED/fapi_l1.h
@@ -37,10 +37,10 @@
 #include "SCHED/sched_common.h"
 #include "nfapi_interface.h"
 
-void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
+void fill_uci_harq_indication(int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
 void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
 void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
-void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
+void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
 void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
 void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
 void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
@@ -81,4 +81,4 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
 
 void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
 
-void schedule_response(Sched_Rsp_t *Sched_INFO);
+void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 34d5a015900..ba03e79e624 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -47,6 +47,7 @@
 #include <time.h>
 
 #include "intertask_interface.h"
+#include <executables/split_headers.h> 
 
 #define MBMS_NFAPI_SCHEDULER
 
@@ -303,6 +304,7 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
 
     start_meas(&eNB->dlsch_encoding_stats);
     dlsch_encoding_all(eNB,
+		       proc,
                        dlsch_harq->pdu,
                        dlsch_harq->pdsch_start,
                        dlsch,
@@ -317,6 +319,14 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
                        &eNB->dlsch_interleaving_stats);
     stop_meas(&eNB->dlsch_encoding_stats);
 
+    if ( proc->threadPool->activated ) {
+    // Wait all other threads finish to process
+    while (proc->nbEncode) {
+      delNotifiedFIFO_elt(pullTpool(proc->respEncode, proc->threadPool));
+      proc->nbEncode--;
+    }
+  }
+
     if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
       print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
     }
@@ -431,6 +441,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here
     for (i=0; i<NUMBER_OF_UE_MAX; i++) {
       if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0;
+
       else
         harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
 
@@ -591,7 +602,12 @@ void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
   }
 }
 
-void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
+void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
+  if ( split73 == SPLIT73_DU ) {
+    sendFs6Ulharq(fs6ULindicationSr, UEid, eNB, NULL, frame, subframe, NULL,0,0, rnti, stat);
+    return;
+  }
+
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   nfapi_sr_indication_t       *sr_ind =         &eNB->UL_INFO.sr_ind;
   nfapi_sr_indication_body_t  *sr_ind_body =    &sr_ind->sr_indication_body;
@@ -604,6 +620,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u
   pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
   pdu->rx_ue_information.rnti                         = rnti;
   int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
+  LOG_D(PHY,"stat %d subbandpower %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10);
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
 
   if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
@@ -640,6 +657,10 @@ uci_procedures(PHY_VARS_eNB *eNB,
     uci = &(eNB->uci_vars[i]);
 
     if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) {
+      if (uci->ue_id > MAX_MOBILES_PER_ENB) {
+        LOG_W(PHY, "UCI for UE %d and/or but is not active in MAC\n", uci->ue_id);
+        continue;
+      }
       LOG_D(PHY,"Frame %d, subframe %d: Running uci procedures (type %d) for %d \n",
             frame,
             subframe,
@@ -710,7 +731,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
 
           if (uci->type == SR) {
             if (SR_payload == 1) {
-              fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
+              fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
               break;
             } else {
               break;
@@ -744,7 +765,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
 
             /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */
             if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
-            else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
+            else if (SR_payload == 1) fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
 
             if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
               /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
@@ -769,7 +790,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
                   frame,subframe,
                   pucch_b0b1[0][0],metric[0]);
             uci->stat = metric[0];
-            fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
+            fill_uci_harq_indication(i, eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
           } else { // frame_type == TDD
             LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
                   frame,subframe,i,
@@ -791,7 +812,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
                                 );
 
             if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
-            else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
+            else if (SR_payload == 1) fill_sr_indication(i, eNB,uci->rnti,frame,subframe,metric_SR);
 
             if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
               SR_payload = 1;
@@ -873,7 +894,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
               }
 
               uci->stat = metric[0];
-              fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
+              fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
             } else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)) { // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
               if (pucch_b0b1[0][0] == 4 ||
                   pucch_b0b1[1][0] == 4) { // there isn't a likely transmission
@@ -909,7 +930,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
               }
 
               uci->stat = max(metric[0],metric[1]);
-              fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+              fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
             } //else if ((uci->tdd_bundling == 0) && (res==2))
             else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)) { // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
               if (harq_ack[0] == 4 ||
@@ -980,7 +1001,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
                 }
 
                 uci->stat = max_metric;
-                fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+                fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
               }
             } //else if ((uci->tdd_bundling == 0) && (res==3))
             else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)) { // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
@@ -1102,14 +1123,14 @@ uci_procedures(PHY_VARS_eNB *eNB,
               }
 
               uci->stat = max_metric;
-              fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
+              fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
             } // else if ((uci->tdd_bundling == 0) && (res==4))
             else { // bundling
               harq_ack[0] = pucch_b0b1[0][0];
               harq_ack[1] = pucch_b0b1[0][1];
               uci->stat = metric[0];
               LOG_D(PHY,"bundling: (%d,%d), metric %d\n",harq_ack[0],harq_ack[1],uci->stat);
-              fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
+              fill_uci_harq_indication(i, eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
             }
 
 #ifdef DEBUG_PHY_PROC
@@ -1140,8 +1161,93 @@ uci_procedures(PHY_VARS_eNB *eNB,
   } // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
 }
 
+void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
+  turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
+
+  LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid];
+  LTE_UL_eNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
+  PHY_VARS_eNB *eNB=rdata->eNB;
+    
+  bool decodeSucess=rdata->decodeIterations <= rdata->maxIterations;
+  ulsch_harq->processedSegments++;
+  LOG_D(PHY, "processing result of segment: %d, ue %d, processed %d/%d\n",
+	rdata->segment_r, rdata->UEid, ulsch_harq->processedSegments, rdata->nbSegments);
+  proc->nbDecode--;
+  LOG_D(PHY,"remain to decoded in subframe: %d\n", proc->nbDecode);
+  if (decodeSucess)  {
+    int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0;
+    int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0);
+    memcpy(ulsch_harq->decodedBytes+rdata->offset,
+	   rdata->decoded_bytes+Fbytes,
+	   sz);
+  } else {
+    if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
+      int nb=abortTpool(proc->threadPool, req->key);
+      nb+=abortNotifiedFIFO(proc->respDecode, req->key);
+      proc->nbDecode-=nb;
+      LOG_I(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
+      AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
+		  ulsch_harq->processedSegments, nb, rdata->nbSegments);
+      ulsch_harq->processedSegments=rdata->nbSegments;
+    }
+  }
+
+  // if this UE segments are all done
+  if ( rdata->nbSegments == ulsch_harq->processedSegments) {
+      //compute the expected ULSCH RX power (for the stats)
+      int i=rdata->UEid;
+      ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,rdata->harq_pid, 0); // 0 means bw_factor is not considered
+      if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */
+	if (ulsch_harq->cqi_crc_status == 1) {
+	  fill_ulsch_cqi_indication(eNB,rdata->frame,rdata->subframe,ulsch_harq,ulsch->rnti);
+	  RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe));
+	} else {
+	  if(RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag & (1 << rdata->subframe) ) {
+	    RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << rdata->subframe));
+	    RC.mac[eNB->Mod_id]->UE_info.UE_sched_ctrl[i].cqi_req_timer=30;
+	    LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",rdata->frame,rdata->subframe);
+	  }
+	}
+      }
+	
+      if (!decodeSucess) {
+	fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC
+	fill_rx_indication(eNB,i,rdata->frame,rdata->subframe);  // indicate SDU to MAC
+	LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
+	      eNB->Mod_id,rdata->harq_pid,
+	      rdata->frame,rdata->subframe, i,
+	      ulsch_harq->round,
+	      ulsch->Mlimit,
+	      ulsch_harq->o_ACK[0],
+	      ulsch_harq->o_ACK[1]);
+	  
+	if (ulsch_harq->round >= 3)  {
+	  ulsch_harq->status  = SCH_IDLE;
+	  ulsch_harq->handled = 0;
+	  ulsch->harq_mask   &= ~(1 << rdata->harq_pid);
+	  ulsch_harq->round   = 0;
+	}
+	/* Mark the HARQ process to release it later if max transmission reached
+	 * (see below).
+	 * MAC does not send the max transmission count, we have to deal with it
+	 * locally in PHY.
+	 */
+	ulsch_harq->handled = 1;
+      }  // ulsch in error
+      else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
+	fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,0); // indicate ACK to MAC
+	fill_rx_indication(eNB,i,rdata->frame,rdata->subframe);  // indicate SDU to MAC
+	ulsch_harq->status = SCH_IDLE;
+	ulsch->harq_mask &= ~(1 << rdata->harq_pid);
+      }  // ulsch not in error
+	
+      if (ulsch_harq->O_ACK>0)
+	fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling);
+  } 
+}
+
 void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
-  uint32_t ret=0,i;
+  uint32_t i;
   uint32_t harq_pid;
   uint8_t nPRS;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
@@ -1150,7 +1256,6 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
   const int subframe = proc->subframe_rx;
   const int frame    = proc->frame_rx;
   uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
-  int   rvidx_tab[4] = {0,2,3,1};
 
   for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
     ulsch = eNB->ulsch[i];
@@ -1204,127 +1309,13 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
       rx_ulsch(eNB,proc, i);
       stop_meas(&eNB->ulsch_demodulation_stats);
       start_meas(&eNB->ulsch_decoding_stats);
-      ret = ulsch_decoding(eNB,proc,
+      ulsch_decoding(eNB,proc,
                            i,
                            0, // control_only_flag
                            ulsch_harq->V_UL_DAI,
                            ulsch_harq->nb_rb>20 ? 1 : 0);
       stop_meas(&eNB->ulsch_decoding_stats);
-      LOG_D(PHY,
-            "[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n",
-            eNB->Mod_id,harq_pid,
-            frame,subframe,
-            ulsch->rnti,
-            dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
-            dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
-            30,//eNB->measurements.n0_power_dB[0],
-            30,//eNB->measurements.n0_power_dB[1],
-            ulsch_harq->o_ACK[0],
-            ulsch_harq->o_ACK[1],
-            ret,
-            ulsch_harq->cqi_crc_status,
-            ulsch_harq->O_ACK,
-            eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max);
-      if (ulsch_harq->repetition_number < ulsch_harq->total_number_of_repetitions){
-    	  ulsch_harq->rvidx = rvidx_tab[(ulsch_harq->repetition_number%4)] ;  			// Set the correct rvidx for the next emtc repetitions
-    	  ulsch_harq->repetition_number +=1  ; 							// Increment repetition_number for the next ULSCH allocation
-      }
-      //compute the expected ULSCH RX power (for the stats)
-      ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
-
-      if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */
-        if (ulsch_harq->cqi_crc_status == 1) {
-#ifdef DEBUG_PHY_PROC
-          //if (((frame%10) == 0) || (frame < 50))
-          print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL);
-#endif
-          fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti);
-          RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
-        } else {
-          if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ) {
-            RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
-            RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30;
-            LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe);
-          }
-        }
-      }
-
-      if (ret == (1+MAX_TURBO_ITERATIONS)) {
-        T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti),
-          T_INT(harq_pid));
-        fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
-        fill_rx_indication(eNB,i,frame,subframe);  // indicate SDU to MAC
-        LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
-              eNB->Mod_id,harq_pid,
-              frame,subframe, i,
-              ulsch_harq->round,
-              ulsch->Mlimit,
-              ulsch_harq->o_ACK[0],
-              ulsch_harq->o_ACK[1]);
-
-        if (ulsch_harq->round >= 3)  {
-          ulsch_harq->status  = SCH_IDLE;
-          ulsch_harq->handled = 0;
-          ulsch->harq_mask   &= ~(1 << harq_pid);
-          ulsch_harq->round   = 0;
-        }
-
-        MSC_LOG_RX_DISCARDED_MESSAGE(
-          MSC_PHY_ENB,MSC_PHY_UE,
-          NULL,0,
-          "%05u:%02u ULSCH received rnti %x harq id %u round %d",
-          frame,subframe,
-          ulsch->rnti,harq_pid,
-          ulsch_harq->round-1
-        );
-        /* Mark the HARQ process to release it later if max transmission reached
-         * (see below).
-         * MAC does not send the max transmission count, we have to deal with it
-         * locally in PHY.
-         */
-        ulsch_harq->handled = 1;
-      }                         // ulsch in error
-      else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
-        fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
-        fill_rx_indication(eNB,i,frame,subframe);  // indicate SDU to MAC
-        ulsch_harq->status = SCH_IDLE;
-        ulsch->harq_mask &= ~(1 << harq_pid);
-        T (T_ENB_PHY_ULSCH_UE_ACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid));
-        MSC_LOG_RX_MESSAGE(
-          MSC_PHY_ENB,MSC_PHY_UE,
-          NULL,0,
-          "%05u:%02u ULSCH received rnti %x harq id %u",
-          frame,subframe,
-          ulsch->rnti,harq_pid
-        );
-#ifdef DEBUG_PHY_PROC
-#ifdef DEBUG_ULSCH
-        LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe,
-              harq_pid,ulsch_harq->TBS>>3);
-
-        for (j=0; j<ulsch_harq->TBS>>3; j++)
-          LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]);
-
-        LOG_T(PHY,"\n");
-#endif
-#endif
-      }  // ulsch not in error
-
-      if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling);
-
-      LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n",
-            eNB->Mod_id,frame,subframe,
-            harq_pid,
-            i,
-            ret,
-            ulsch_harq->cqi_crc_status,
-            ulsch_harq->o_ACK[0],
-            ulsch_harq->o_ACK[1],
-            eNB->UE_stats[i].ulsch_errors[harq_pid],
-            eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
-    } //     if ((ulsch) &&
-    //         (ulsch->rnti>0) &&
-    //         (ulsch_harq->status == ACTIVE))
+    }
     else if ((ulsch) &&
              (ulsch->rnti>0) &&
              (ulsch_harq->status == ACTIVE) &&
@@ -1338,6 +1329,12 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
       LOG_W (PHY, "Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n", ulsch->rnti, harq_pid, ulsch->harq_mask);
     }
   }   //   for (i=0; i<NUMBER_OF_UE_MAX; i++)
+  
+  while (proc->nbDecode > 0) {
+    notifiedFIFO_elt_t *req=pullTpool(proc->respDecode, proc->threadPool);
+    postDecode(proc, req);
+    delNotifiedFIFO_elt(req);
+  }
 }
 
 extern int      oai_exit;
@@ -1345,24 +1342,29 @@ extern int      oai_exit;
 extern void    *td_thread (void *);
 
 void init_td_thread(PHY_VARS_eNB *eNB) {
+	/*
   L1_proc_t *proc = &eNB->proc;
   proc->tdp.eNB = eNB;
   proc->instance_cnt_td = -1;
   threadCreate(&proc->pthread_td, td_thread, (void *)&proc->tdp, "TD", -1, OAI_PRIORITY_RT);
+  */
 }
 
 void kill_td_thread(PHY_VARS_eNB *eNB) {
+	/*
   L1_proc_t *proc = &eNB->proc;
   proc->instance_cnt_td         = 0;
   pthread_cond_signal(&proc->cond_td);
   pthread_join(proc->pthread_td, NULL);
   pthread_mutex_destroy( &proc->mutex_td );
   pthread_cond_destroy( &proc->cond_td );
+  */
 }
 
 extern void    *te_thread (void *);
 
 void init_te_thread(PHY_VARS_eNB *eNB) {
+	/*
   L1_proc_t *proc = &eNB->proc;
 
   for(int i=0; i<3 ; i++) {
@@ -1373,9 +1375,11 @@ void init_te_thread(PHY_VARS_eNB *eNB) {
     sprintf(txt,"TE_%d", i);
     threadCreate(&proc->tep[i].pthread_te, te_thread, (void *)&proc->tep[i], txt, -1, OAI_PRIORITY_RT);
   }
+  */
 }
 
 void kill_te_thread(PHY_VARS_eNB *eNB) {
+	/*
   L1_proc_t *proc = &eNB->proc;
 
   for(int i=0; i<3 ; i++) {
@@ -1385,6 +1389,7 @@ void kill_te_thread(PHY_VARS_eNB *eNB) {
     pthread_mutex_destroy( &proc->tep[i].mutex_te);
     pthread_cond_destroy( &proc->tep[i].cond_te);
   }
+  */
 }
 
 void fill_rx_indication(PHY_VARS_eNB *eNB,
@@ -1412,7 +1417,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,
   pdu->rx_indication_rel8.tl.tag         = NFAPI_RX_INDICATION_REL8_TAG;
   pdu->rx_indication_rel8.length         = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3;
   pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
-  pdu->data                              = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b;
+  pdu->data                              = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes;
   // estimate timing advance for MAC
   sync_pos                               = lte_est_timing_advance_pusch(eNB,UE_id);
   timing_advance_update                  = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check
@@ -1745,7 +1750,12 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void fill_uci_harq_indication (PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) {
+void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) {
+  if ( split73 == SPLIT73_DU ) {
+    sendFs6Ulharq(fs6ULindicationHarq, UEid, eNB, uci, frame, subframe, harq_ack, tdd_mapping_mode, tdd_multiplexing_mask, 0, 0);
+    return;
+  }
+  
   int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
 
   //AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti);
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 6d392b04378..8846b77af9f 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -321,7 +321,7 @@ void feptx_ofdm(RU_t *ru,
                      fp->nb_prefix_samples,
                      CYCLIC_PREFIX);
       } else {
-       if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)/*subframe==1*/){
+       if(is_pmch_subframe(frame,subframe,fp)/*subframe==1*/){
         normal_prefix_mod(&ru->common.txdataF_BF[aa][0],
                           dummy_tx_b,
                           2,
@@ -426,7 +426,7 @@ void feptx_ofdm(RU_t *ru,
 
      stop_meas(&ru->ofdm_mod_stats);
      LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
-	   ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
+	   frame,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
 	   dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
     }
   }
diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h
index e9af869b055..f3e43d516ec 100644
--- a/openair1/SCHED/sched_common.h
+++ b/openair1/SCHED/sched_common.h
@@ -311,7 +311,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id);
 
 int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
 
-void schedule_response(Sched_Rsp_t *Sched_INFO);
+void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
 
 LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index e74b9a312fd..f04bec2e5c4 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -128,8 +128,8 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc);
   @param br_flag indicator for eMTC PRACH
 */
 
-void prach_procedures(PHY_VARS_eNB *eNB,
-                      int br_flag);
+void prach_procedures(PHY_VARS_eNB *eNB, 
+		      int br_flag);
 
 
 /*! \brief Function to compute timing of Msg3 transmission on UL-SCH (first UE transmission in RA procedure). This implements the timing in paragraph a) from Section 6.1.1 in 36.213 (p. 17 in version 8.6).  Used by eNB upon transmission of random-access response (RA_RNTI) to program corresponding ULSCH reception procedure.  Used by UE upon reception of random-access response (RA_RNTI) to program corresponding ULSCH transmission procedure.  This does not support the UL_delay field in RAR (always assumed to be 0).
@@ -193,7 +193,7 @@ int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 
 
 
-void schedule_response(Sched_Rsp_t *Sched_INFO);
+void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
 
 LTE_eNB_UE_stats *get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 
@@ -218,8 +218,6 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf
 void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
 
 void release_rnti_of_phy(module_id_t mod_id);
-
-void ru_fep_full_2thread(RU_t *ru, int subframe);
 /*@}*/
 
 
diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h
index 07509b3bb7b..d66d6e7b242 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.h
+++ b/openair1/SCHED_NR/fapi_nr_l1.h
@@ -46,6 +46,5 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
 			       nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
                             uint8_t *sdu);
 
-void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid);
 
-void nr_fill_crc_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t crc_flag);
+void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid, uint8_t crc_flag);
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index b9a8ba94f1e..9054ddbae5b 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -32,7 +32,7 @@
 
 #include "PHY/defs_gNB.h"
 #include "PHY/phy_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport.h"
 #include "nfapi_nr_interface_scf.h"
 #include "fapi_nr_l1.h"
 #include "nfapi_pnf.h"
@@ -47,17 +47,19 @@
 
 #include "intertask_interface.h"
 
-extern uint32_t nfapi_mode;
+extern uint8_t nfapi_mode;
 
 extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind);
 
 
-void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) {
-  uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4];
+void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
+			    nfapi_nr_prach_pdu_t *prach_pdu) {
+
+  uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0};
   uint16_t i;
 
 
-  gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0;
+  gNB->UL_INFO.rach_ind.number_of_pdus=0;
 
   RU_t *ru;
   int aa=0;
@@ -75,16 +77,18 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) {
     }
   }
 
-  rx_nr_prach(gNB,
+
+ /* rx_nr_prach(gNB,
+	      prach_pdu,
 	      frame,
-	      subframe,
+	      slot,
 	      &max_preamble[0],
 	      &max_preamble_energy[0],
 	      &max_preamble_delay[0]
-	      );
+	      );*/
 
-  LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
-        frame,subframe,
+  LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
+        frame,slot,
         max_preamble[0],
         max_preamble_energy[0]/10,
         max_preamble_delay[0],
@@ -93,49 +97,43 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) {
   if ((gNB->prach_energy_counter == 100) && 
       (max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
     
-    LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
+    LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
 	  gNB->Mod_id,
 	  frame,
-	  subframe,
+	  slot,
 	  max_preamble[0],
 	  max_preamble_energy[0]/10,
 	  max_preamble_energy[0]%10,
 	  max_preamble_delay[0]);
     
-    T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(subframe),
+    T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
       T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
     
     
-    gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles  = 1;
-    gNB->UL_INFO.rach_ind.rach_indication_body.preamble_list        = &gNB->preamble_list[0];
-    gNB->UL_INFO.rach_ind.rach_indication_body.tl.tag               = NFAPI_RACH_INDICATION_BODY_TAG;
-    gNB->UL_INFO.rach_ind.header.message_id                         = NFAPI_RACH_INDICATION;
-    gNB->UL_INFO.rach_ind.sfn_sf                                    = frame<<4 | subframe;
-    
-    gNB->preamble_list[0].preamble_rel8.tl.tag                = NFAPI_PREAMBLE_REL8_TAG;
-    gNB->preamble_list[0].preamble_rel8.timing_advance        = max_preamble_delay[0];
-    gNB->preamble_list[0].preamble_rel8.preamble              = max_preamble[0];
-    gNB->preamble_list[0].preamble_rel8.rnti                  = 1+subframe;  // note: fid is implicitly 0 here
-    gNB->preamble_list[0].instance_length                     = 0; //don't know exactly what this is
+    gNB->UL_INFO.rach_ind.number_of_pdus  = 1;
+    gNB->UL_INFO.rach_ind.pdu_list        = &gNB->prach_pdu_indication_list[0];
+    gNB->UL_INFO.rach_ind.sfn                                    = frame;
+    gNB->UL_INFO.rach_ind.slot            = slot;
     
-    if (nfapi_mode == 1) {  // If NFAPI PNF then we need to send the message to the VNF
-      
-      LOG_D(PHY,"Filling NFAPI indication for NR RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x\n",
-	    NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf),
-	    gNB->preamble_list[0].preamble_rel8.timing_advance,
-	    gNB->preamble_list[0].preamble_rel8.preamble,
-	    gNB->preamble_list[0].preamble_rel8.rnti);
-      AssertFatal(1==0,"shouldn't be here yet..\n"); 
-      //oai_nfapi_nr_rach_ind(&gNB->UL_INFO.rach_ind);
-      
-      gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0;
-    }
-  } // max_preamble_energy > prach_I0 + 100 
-  else {
-    gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); 
-    if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
-    if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
-  }
+    gNB->prach_pdu_indication_list[0].phy_cell_id  = gNB->gNB_config.cell_config.phy_cell_id.value;
+    gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol;  // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion)
+    gNB->prach_pdu_indication_list[0].slot_index   = slot;
+    gNB->prach_pdu_indication_list[0].freq_index   = prach_pdu->num_ra;
+    gNB->prach_pdu_indication_list[0].avg_rssi     = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
+    gNB->prach_pdu_indication_list[0].avg_snr      = 0xff; // invalid for now
+
+
+    gNB->prach_pdu_indication_list[0].num_preamble                        = 1;
+    gNB->prach_pdu_indication_list[0].preamble_list                       = gNB->preamble_list;
+    gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index     = max_preamble[0];
+    gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance     = max_preamble_delay[0];
+    gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr       = 0xffffffff;
+  }    
+  gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); 
+  if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
+  if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
+  
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
 }
+
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index fa22e43661f..a36cebd6aee 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -202,7 +202,7 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg,
 
 void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex, int nrofDownlinkSymbols, int nrofUplinkSymbols) {
   TDD_UL_DL_SlotConfig_t *p_TDD_UL_DL_ConfigDedicated = frame_parms->p_TDD_UL_DL_ConfigDedicated;
-  TDD_UL_DL_SlotConfig_t *p_previous_TDD_UL_DL_ConfigDedicated;
+  TDD_UL_DL_SlotConfig_t *p_previous_TDD_UL_DL_ConfigDedicated=NULL;
   int next = 0;
 
   while (p_TDD_UL_DL_ConfigDedicated != NULL) {
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index d9a7ee3c69a..60f9d4747af 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -28,6 +28,7 @@
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
+#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
 #include "SCHED/sched_eNB.h"
 #include "sched_nr.h"
 #include "SCHED/sched_common_extern.h"
@@ -242,16 +243,18 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
   //------------------- ULSCH unscrambling -------------------
   //----------------------------------------------------------
 
+  start_meas(&gNB->ulsch_unscrambling_stats);
   nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
                         G,
                         0,
                         pusch_pdu->data_scrambling_id,
                         pusch_pdu->rnti);
-
+  stop_meas(&gNB->ulsch_unscrambling_stats);
   //----------------------------------------------------------
   //--------------------- ULSCH decoding ---------------------
   //----------------------------------------------------------
 
+  start_meas(&gNB->ulsch_decoding_stats);
   ret = nr_ulsch_decoding(gNB,
                           ULSCH_id,
                           gNB->pusch_vars[ULSCH_id]->llr,
@@ -261,57 +264,30 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
                           slot_rx,
                           harq_pid,
                           G);
+  stop_meas(&gNB->ulsch_decoding_stats);
 
-        
-  if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations)
+  if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
     LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id);
-  //gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b
+    nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
+  }
   else if(gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->b!=NULL){
-	  LOG_I(PHY, "ULSCH received ok \n");
-	  if(IS_SOFTMODEM_NOS1){ //&& gNB->ulsch[ULSCH_id][0]->rnti == 0x1234
-	    nr_fill_crc_indication(gNB,frame_rx, slot_rx, ULSCH_id, 0);
-	    nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
-	  }
+    LOG_I(PHY, "ULSCH received ok \n");
+    nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 0);
   }
-
 }
 
 
-void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid)
-{
-  // --------------------
-  // [hna] TO BE CLEANED
-  // --------------------
+void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag) {
 
-  nfapi_rx_indication_pdu_t *pdu;
+  pthread_mutex_lock(&gNB->UL_INFO_mutex);
 
-  int timing_advance_update;
+  int timing_advance_update, cqi;
   int sync_pos;
-
   uint16_t mu = gNB->frame_parms.numerology_index;
-  // pthread_mutex_lock(&gNB->UL_INFO_mutex);
   NR_gNB_ULSCH_t                       *ulsch                 = gNB->ulsch[ULSCH_id][0];
   NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
 
- pthread_mutex_lock(&gNB->UL_INFO_mutex);
-
- gNB->UL_INFO.rx_ind.sfn_sf                    = frame<<4| slot_rx;
- gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
- gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->TBS;
-
- pdu                                    = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus];
-
- //pdu->rx_ue_information.handle          = gNB->ulsch[ULSCH_id+1][0]->handle;
- pdu->rx_ue_information.tl.tag          = NFAPI_RX_UE_INFORMATION_TAG;
- pdu->rx_ue_information.rnti            = gNB->ulsch[ULSCH_id][0]->rnti;
- pdu->rx_indication_rel8.tl.tag         = NFAPI_RX_INDICATION_REL8_TAG;
- pdu->rx_indication_rel8.offset         = 1;   // DJP - I dont understand - but broken unless 1 ????  0;  // filled in at the end of the UL_INFO formation
- pdu->data                              = harq_process->b;//gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b;
-  // estimate timing advance for MAC
-  sync_pos                               = nr_est_timing_advance_pusch(gNB, ULSCH_id);
-  timing_advance_update                  = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check
-  // printf("\x1B[33m" "timing_advance_update = %d\n" "\x1B[0m", timing_advance_update);
-
+  nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
 
   //  pdu->data                              = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b;
   sync_pos                               = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
@@ -335,39 +311,50 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_
 
   LOG_D(PHY, "Estimated timing advance PUSCH is  = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
 
-  pdu->rx_indication_rel8.timing_advance = timing_advance_update;
-
   // estimate UL_CQI for MAC (from antenna port 0 only)
   int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]);
 
-  if      (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0;
-  else if (SNRtimes10 >  635) pdu->rx_indication_rel8.ul_cqi=255;
-  else                        pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5;
-
-  // LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
-  // harq_pid,frame,slot_rx,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
-  // timing_advance_update);
-
-  gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
-  gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx;
+  if      (SNRtimes10 < -640) cqi=0;
+  else if (SNRtimes10 >  635) cqi=255;
+  else                        cqi=(640+SNRtimes10)/5;
+
+  // crc indication
+  uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs;
+  gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0];
+  gNB->UL_INFO.crc_ind.sfn = frame;
+  gNB->UL_INFO.crc_ind.slot = slot_rx;
+
+  gNB->crc_pdu_list[num_crc].handle = pusch_pdu->handle;
+  gNB->crc_pdu_list[num_crc].rnti = pusch_pdu->rnti;
+  gNB->crc_pdu_list[num_crc].harq_id = harq_pid;
+  gNB->crc_pdu_list[num_crc].tb_crc_status = crc_flag;
+  gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
+  gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
+  gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
+  gNB->crc_pdu_list[num_crc].rssi = 0xffff; // invalid value as this is not yet computed
+
+  gNB->UL_INFO.crc_ind.number_crcs++;
+
+  // rx indication
+  uint16_t num_rx = gNB->UL_INFO.rx_ind.number_of_pdus;
+  gNB->UL_INFO.rx_ind.pdu_list = &gNB->rx_pdu_list[0];
+  gNB->UL_INFO.rx_ind.sfn = frame;
+  gNB->UL_INFO.rx_ind.slot = slot_rx;
+  gNB->rx_pdu_list[num_rx].handle = pusch_pdu->handle;
+  gNB->rx_pdu_list[num_rx].rnti = pusch_pdu->rnti;
+  gNB->rx_pdu_list[num_rx].harq_id = harq_pid;
+  gNB->rx_pdu_list[num_rx].ul_cqi = cqi;
+  gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update;
+  gNB->rx_pdu_list[num_rx].rssi = 0xffff; // invalid value as this is not yet computed
+  if (crc_flag)
+    gNB->rx_pdu_list[num_rx].pdu_length = 0;
+  else {
+    gNB->rx_pdu_list[num_rx].pdu_length = harq_process->TBS;
+    gNB->rx_pdu_list[num_rx].pdu = harq_process->b;
+  }
 
-  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
-}
+  gNB->UL_INFO.rx_ind.number_of_pdus++;
 
-void nr_fill_crc_indication (PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,  uint8_t crc_flag) {
-  pthread_mutex_lock(&gNB->UL_INFO_mutex);
-  nfapi_crc_indication_pdu_t *pdu =   &gNB->UL_INFO. crc_ind.crc_indication_body.crc_pdu_list[gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs];
-  gNB->UL_INFO.crc_ind.sfn_sf                         = frame<<4 | slot_rx;
-  gNB->UL_INFO.crc_ind.header.message_id              = NFAPI_CRC_INDICATION;
-  gNB->UL_INFO.crc_ind.crc_indication_body.tl.tag     = NFAPI_CRC_INDICATION_BODY_TAG;
-  pdu->instance_length = 0;     // don't know what to do with this
-  //  pdu->rx_ue_information.handle                       = handle;
-  pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
-  pdu->rx_ue_information.rnti                         = gNB->ulsch[ULSCH_id][0]->rnti;
-  pdu->crc_indication_rel8.tl.tag                     = NFAPI_CRC_INDICATION_REL8_TAG;
-  pdu->crc_indication_rel8.crc_flag                   = crc_flag;
-  gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs++;
-  //LOG_D(PHY, "%s() rnti:%04x crcs:%d crc_flag:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, crc_flag);
   pthread_mutex_unlock(&gNB->UL_INFO_mutex);
 }
 
@@ -393,34 +380,67 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
 
 void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
 
-  nfapi_nr_ul_tti_request_t     *UL_tti_req  = &gNB->UL_tti_req;
-  int num_pusch_pdu = UL_tti_req->n_pdus;
+  nfapi_nr_ul_tti_request_t *UL_tti_req  = &gNB->UL_tti_req;
+  int num_pdus = UL_tti_req->n_pdus;
 
-  LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pusch_pdu %d\n",frame_rx,slot_rx,num_pusch_pdu);
+  nfapi_nr_uci_indication_t *uci_indication = &gNB->uci_indication;
+  uci_indication->sfn = frame_rx;
+  uci_indication->slot = slot_rx;
+  uci_indication->num_ucis = 0;
 
-  gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus  = 0;
 
-  for (int i = 0; i < num_pusch_pdu; i++) {
-    switch (UL_tti_req->pdus_list[i].pdu_type) {
-    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:{
-      LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx);
+  LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus);
 
-      nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
-      nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu);
-      
-      uint8_t ULSCH_id =  find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST);
-      uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id;
-      uint8_t symbol_start = pusch_pdu->start_symbol_index;
-      uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols;
-      
-      for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
-        nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
+  gNB->UL_INFO.rx_ind.number_of_pdus = 0;
+  gNB->UL_INFO.crc_ind.number_crcs = 0;
+
+  for (int i = 0; i < num_pdus; i++) {
+    switch (UL_tti_req->pdus_list[i].pdu_type) {
+    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+      {
+	LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx);
+	
+	nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
+	nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu);
+	
+	uint8_t ULSCH_id =  find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST);
+	uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id;
+	uint8_t symbol_start = pusch_pdu->start_symbol_index;
+	uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols;
+	
+	for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
+	  nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
+	}
+	//LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
+	//LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
+	nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
       }
-      //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
-      //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
-      nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
-      nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);  // indicate SDU to MAC
-      nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0);
+      break;
+    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+      {
+	LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx);
+	
+	nfapi_nr_pucch_pdu_t  *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu;
+	switch (pucch_pdu->format_type) {
+	case 0:
+	  uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
+	  uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
+	  nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1;
+	  
+	  nr_decode_pucch0(gNB,
+			   slot_rx,
+			   uci_pdu_format0,
+			   pucch_pdu);
+	  
+	  uci_indication->num_ucis += 1;
+	  break;
+	case 1:
+	  break;
+	case 2:
+	  break;
+	default:
+	  AssertFatal(1==0,"Only PUCCH format 0,1 and 2 are currently supported\n");
+	}
       }
     }
   }
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 69876159d63..7439c26eb74 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -116,16 +116,12 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
       for(i=0; i<ul_config->number_pdus; ++i){
 	if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){
 	  // pusch config pdu
-	  fapi_nr_ul_config_pusch_pdu_rel15_t *pusch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15;
-	  uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr;
-	  ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs;
-	  ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb;
-	  ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols;
-	  ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol;
-	  ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs;
-	  ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi;
-	  ulsch0->harq_processes[current_harq_pid]->rvidx = pusch_config_pdu->rv;
-	  ulsch0->harq_processes[current_harq_pid]->Nl = pusch_config_pdu->n_layers;
+	  nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
+	  uint8_t current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
+	  nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
+
+	  memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
+
 	  ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
 	}
 	if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUCCH){
diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index 31dcfcacbe9..3c3017d6587 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -296,7 +296,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
   /* 38.321 5.4.2.1  2>  if the uplink grant was received on PDCCH for the C-RNTI and the HARQ buffer of the identified process is empty */
   if ((ulsch->harq_processes[harq_pid]->first_tx == 1) && (rnti_type == _C_RNTI_)) {  /* no transmission yet on this process so consider its harq buffer as empty */
     ulsch->harq_processes[harq_pid]->first_tx = 0;
-    ulsch->harq_processes[harq_pid]->DCINdi = ndi;             /* store first value of ndi */
+    ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi;             /* store first value of ndi */
     ulsch->harq_processes[harq_pid]->round = 0;
     ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
 
@@ -306,8 +306,8 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
   }
   /* 38.321 5.4.2.1  2> if the received grant was not addressed to a Temporary C-RNTI on PDCCH, and the NDI provided in the associated HARQ */
   /* information has been toggled compared to the value in the previous transmission of this TB of this HARQ process */
-  else if ((ulsch->harq_processes[harq_pid]->DCINdi != ndi) && (rnti_type != _TC_RNTI_)) {   /* is ndi toogled so this is a new grant ? */
-    ulsch->harq_processes[harq_pid]->DCINdi = ndi;             /* store first value of ndi */
+  else if ((ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator != ndi) && (rnti_type != _TC_RNTI_)) {   /* is ndi toogled so this is a new grant ? */
+    ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi;             /* store first value of ndi */
     ulsch->harq_processes[harq_pid]->round = 0;
     ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
 
@@ -317,7 +317,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
    }
    /* 38.321 5.4.2.1 2> else (i.e. retransmission): */
    else {
-     ulsch->harq_processes[harq_pid]->DCINdi = ndi;             /* ndi has not toggled si this is a retransmission */
+     ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi;             /* ndi has not toggled si this is a retransmission */
      ulsch->harq_processes[harq_pid]->round++;                  /* increment number of retransmission */
 
      result_harq = RETRANSMISSION_HARQ;
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
index a939584584b..81b6d373dfb 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
@@ -29,8 +29,8 @@
 *
 ************************************************************************/
 
-#ifndef PHY_FRAME_CONFIG_NR_H
-#define PHY_FRAME_CONFIG_NR_H
+#ifndef PHY_FRAME_CONFIG_NR_UE_H
+#define PHY_FRAME_CONFIG_NR_UE_H
 
 /************** DEFINE ********************************************/
 
@@ -78,5 +78,6 @@ void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms);
 
 void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
 
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mod);
 #endif  /* PHY_FRAME_CONFIG_NR_H */
 
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 509f4b60213..e5e48ee0edc 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -86,17 +86,6 @@ char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
 
 extern double cpuf;
 
-
-
-int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
-                    uint32_t frame,
-                    uint32_t slot);
-
-uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
-				  int frame,
-				  int nr_tti_rx,
-				  fapi_nr_dci_indication_t *dci_ind);
-
 /*
 int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
 					    uint8_t eNB_id,
@@ -2460,7 +2449,7 @@ ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
     ue->tx_total_RE[nr_tti_tx] = 96;
 
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
-    ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
+    ue->prach_vars[eNB_id]->amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
 					     ue->tx_power_max_dBm,
 					     ue->frame_parms.N_RB_UL,
 					     6);
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 326c617dfb5..1b62ff81bff 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -186,6 +186,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
   int       pucch_resource_id = MAX_NB_OF_PUCCH_RESOURCES;
   int       pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR;
   int       n_HARQ_ACK;
+  uint16_t crnti=0x1234;
+  int dmrs_scrambling_id=0,data_scrambling_id=0;
 
   /* update current context */
 
@@ -591,7 +593,9 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
     case pucch_format2_nr:
     {
       nr_generate_pucch2(ue,
-                         0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti,
+                         crnti,
+			 dmrs_scrambling_id,
+			 data_scrambling_id,
                          ue->common_vars.txdataF,
                          &ue->frame_parms,
                          &ue->pucch_config_dedicated[gNB_id],
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/socket.h b/openair1/SIMULATION/ETH_TRANSPORT/socket.h
index c7a2224375e..e9ca36bee2a 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/socket.h
+++ b/openair1/SIMULATION/ETH_TRANSPORT/socket.h
@@ -28,8 +28,9 @@
 * \email: lionel.gauthier@eurecom.fr
 */
 
-#ifndef __SOCKET_H__
-#    define __SOCKET_H__
+#ifndef __SIMULATION_ETH_TRANSPORT_SOCKET__H__
+#define __SIMULATION_ETH_TRANSPORT_SOCKET__H__
+
 #    ifdef SOCKET_C
 #        define private_socket(x) x
 #        define public_socket(x) x
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 6706b0f9123..f65e1f9633f 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -59,6 +59,7 @@
 #include "unitary_defs.h"
 #include "dummy_functions.c"
 #include "executables/thread-common.h"
+#include "executables/split_headers.h"
 
 void feptx_ofdm(RU_t *ru, int frame, int subframe);
 void feptx_prec(RU_t *ru, int frame, int subframe);
@@ -78,6 +79,13 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
 int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
 
 int emulate_rf = 0;
+int split73=0;
+void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
 
 void handler(int sig) {
   void *array[10];
@@ -515,7 +523,7 @@ int main(int argc, char **argv) {
   char fname[32],vname[32];
   FILE *bler_fd;
   char bler_fname[256];
-  FILE *time_meas_fd;
+  FILE *time_meas_fd=NULL;
   char time_meas_fname[256];
   //  FILE *tikz_fd;
   //  char tikz_fname[256];
@@ -1266,6 +1274,13 @@ int main(int argc, char **argv) {
   }
 
   L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
+  proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
+  proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  initTpool("n", proc_eNB->threadPool, true);
+  initNotifiedFIFO(proc_eNB->respEncode);
+  initNotifiedFIFO(proc_eNB->respDecode);
+
   proc_eNB->frame_tx=0;
 
   if (input_fd==NULL) {
@@ -1446,7 +1461,7 @@ int main(int argc, char **argv) {
             sched_resp.subframe=subframe;
             sched_resp.frame=proc_eNB->frame_tx;
             eNB->abstraction_flag=0;
-            schedule_response(&sched_resp);
+            schedule_response(&sched_resp, proc_eNB);
             phy_procedures_eNB_TX(eNB,proc_eNB,1);
 
             if (uncoded_ber_bit == NULL) {
@@ -1480,7 +1495,7 @@ int main(int argc, char **argv) {
             TX_req.tx_request_body.number_of_pdus=0;
             proc_eNB->subframe_tx = subframe+1;
             sched_resp.subframe=subframe+1;
-            schedule_response(&sched_resp);
+            schedule_response(&sched_resp, proc_eNB);
             phy_procedures_eNB_TX(eNB,proc_eNB,0);
             ru->proc.tti_tx=(subframe+1)%10;
             feptx_prec(ru,proc_eNB->frame_tx,subframe+1);
@@ -1583,11 +1598,11 @@ int main(int argc, char **argv) {
                                subframe<<1);
 
             for (i=0; i<coded_bits_per_codeword; i++)
-              if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
-                  (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
+              if ((eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
+                  (eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
                 uncoded_ber_bit[bit_errors++] = 1;
                 printf("error in pos %d : %d => %d\n",i,
-                       eNB->dlsch[0][0]->harq_processes[0]->e[i],
+                       eNB->dlsch[0][0]->harq_processes[0]->eDL[i],
                        UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
               } else {
                 /*
@@ -1634,7 +1649,7 @@ int main(int argc, char **argv) {
             //pdsch_vars
             printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword);
             dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
-            LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+            LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->eDL,coded_bits_per_codeword,1,4);
             //pdcch_vars
             LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
             LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index db97240ed55..c950d6f4da2 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -54,6 +54,7 @@
 #include "common/config/config_load_configmodule.h"
 #include "executables/thread-common.h"
 #include "targets/RT/USER/lte-softmodem.h"
+#include "executables/split_headers.h"
 
 double cpuf;
 #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
@@ -81,6 +82,14 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
 int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
 
 
+int split73=0;
+void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+
 extern void fep_full(RU_t *ru, int subframe);
 extern void ru_fep_full_2thread(RU_t *ru, int subframe);
 //extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
@@ -793,6 +802,13 @@ int main(int argc, char **argv) {
   proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
   proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
   proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
+  proc_rxtx->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
+  proc_rxtx->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+  initTpool("n",proc_rxtx->threadPool, true);
+  initNotifiedFIFO(proc_rxtx->respEncode);
+  initNotifiedFIFO(proc_rxtx->respDecode);
+
   printf("Init UL hopping UE\n");
   init_ul_hopping(&UE->frame_parms);
   printf("Init UL hopping eNB\n");
@@ -995,7 +1011,7 @@ int main(int argc, char **argv) {
                                             srs_flag);
           sched_resp.subframe=(subframe+6)%10;
           sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023;
-          schedule_response(&sched_resp);
+          schedule_response(&sched_resp, proc_rxtx);
 
           /////////////////////
           if (abstx) {
@@ -1270,7 +1286,7 @@ int main(int argc, char **argv) {
         LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n");
       }
 
-      printf("\n**********rb: %d ***mcs : %d  *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n",
+      printf("\n**********rb: %d ***mcs : %d  *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %u dB, delta_IF %d [ (%d,%d) dB / (%u,%u) dB ]**************************\n",
              nb_rb,mcs,SNR,SNR2,
              tx_lev_dB,
              20*log10(tx_gain),
@@ -1352,7 +1368,7 @@ int main(int argc, char **argv) {
         printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" );
         printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" );
         printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" );
-        printf("|__ turbo_decoder(%d bits), avg iterations: %.1f       %.2f us (%d cycles, %d trials)\n",
+        printf("    |__ turbo_decoder(%d bits), avg iterations: %.1f       %.2f us (%d cycles, %d trials)\n",
                eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ?
                eNB->ulsch[0]->harq_processes[harq_pid]->Kminus :
                eNB->ulsch[0]->harq_processes[harq_pid]->Kplus,
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index ebcedbaeb09..0b51901b059 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -171,6 +171,7 @@ int main(int argc, char **argv)
   //int pbch_tx_ant;
   int N_RB_DL=106,mu=1;
   nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config;
+  NR_sched_pucch pucch_sched;
 
   //unsigned char frame_type = 0;
 
@@ -412,6 +413,7 @@ int main(int argc, char **argv)
       printf("-c Start symbol for PDSCH (fixed for now)\n");
       printf("-j Number of symbols for PDSCH (fixed for now)\n");
       printf("-e MSC index\n");
+      printf("-P Print DLSCH performances\n");
       exit (-1);
       break;
     }
@@ -706,7 +708,7 @@ int main(int argc, char **argv)
 
       memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
       clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
-      if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&dlsch_config);
+      if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
       else               nr_schedule_css_dlsch_phytest(0,frame,slot);
       
       
@@ -867,7 +869,7 @@ int main(int argc, char **argv)
       
       if (errors_scrambling > 0) {
 	if (n_trials == 1)
-	  printf("errors_scrambling = %d/%d (trial %d)\n", errors_scrambling, available_bits,trial);
+	  printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial);
       }
       
       if (errors_bit > 0) {
@@ -901,7 +903,6 @@ int main(int argc, char **argv)
       break;
     }
 
-
     if (print_perf==1) {
       printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
 	     1000>>*scc->ssbSubcarrierSpacing,dlsch_config.rbSize,dlsch_config.mcsIndex[0],
@@ -976,6 +977,8 @@ int main(int argc, char **argv)
   if (input_fd)
     fclose(input_fd);
 
+  if (scg_fd)
+    fclose(scg_fd);
   return(n_errors);
   
 }
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 99ca466fee4..9d14391f713 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -410,7 +410,7 @@ int main(int argc, char **argv)
   uint8_t n_hf = 0;
   int cyclic_prefix_type = NFAPI_CP_NORMAL;
 
-  double fs, eps;
+  double fs=0, eps;
   double scs = 30000;
   double bw = 100e6;
   
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 5c003525158..2ad89ce897c 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -108,7 +108,7 @@ int main(int argc, char **argv)
   uint8_t hs_flag=0;
   int n_frames=1;
   channel_desc_t *UE2gNB;
-  uint32_t nsymb,tx_lev; //,tx_lev_dB;
+  uint32_t tx_lev=0; //,tx_lev_dB;
   //  int8_t interf1=-19,interf2=-19;
   NR_DL_FRAME_PARMS *frame_parms;
 
@@ -120,7 +120,6 @@ int main(int argc, char **argv)
   uint32_t prach_errors=0;
   uint8_t subframe=9;
   uint16_t preamble_energy_list[64],preamble_tx=50,preamble_delay_list[64];
-  uint16_t preamble_max,preamble_energy_max;
   PRACH_RESOURCES_t prach_resources;
   //uint8_t prach_fmt;
   //int N_ZC;
@@ -189,21 +188,27 @@ int main(int argc, char **argv)
 
       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=Rayleigh1_800;
@@ -397,7 +402,7 @@ int main(int argc, char **argv)
   frame_parms->frame_type = TDD;
   frame_parms->freq_range = nr_FR1;
 
-  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
+  //nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
 
   printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS,
          frame_parms->Ncp,frame_parms->samples_per_subframe,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
@@ -434,7 +439,7 @@ int main(int argc, char **argv)
 
 
   bw = N_RB_UL*(180e3)*(1<<gNB->frame_parms.numerology_index);
-  AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n",gNB->frame_parms.numerology_index,N_RB_UL);
+  AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n",bw, gNB->frame_parms.numerology_index,N_RB_UL);
   if (bw <= 30.72e6)       fs = 30.72e6;
   else if (bw <= 61.44e6)  fs = 61.44e6;
   else if (bw <= 122.88e6) fs = 122.88e6;
@@ -629,7 +634,7 @@ int main(int argc, char **argv)
         }
       }
 
-      printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
+      printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
       //printf("(%f,%f)\n",ue_speed,(double)prach_errors/(double)n_frames);
     } // UE Speed loop
 
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 445c45693ed..a754df47632 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -66,7 +66,7 @@ int main(int argc, char **argv)
   double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
   double cfo=0;
   uint8_t snr1set=0;
-  int **txdata;
+  int **txdataF,**rxdataF;
   double **s_re,**s_im,**r_re,**r_im;
   //int sync_pos, sync_pos_slot;
   //FILE *rx_frame_file;
@@ -87,22 +87,24 @@ int main(int argc, char **argv)
   uint8_t nacktoack_flag=0;
   int16_t amp=0x7FFF;
   int nr_tti_tx=0; 
-  uint64_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 for pucch format 0 
+  uint64_t actual_payload=0,payload_received;
   int nr_bit=1; // maximum value possible is 2
   uint8_t m0=0;// higher layer paramater initial cyclic shift
   uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1
   uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided
   uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided
+  uint16_t nrofPRB=2;
   uint8_t timeDomainOCC=0;
   SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
   
   int N_RB_DL=273,mu=1;
-  float target_error_rate=0.01;
+  float target_error_rate=0.001;
   int frame_length_complex_samples;
   //int frame_length_complex_samples_no_prefix;
   NR_DL_FRAME_PARMS *frame_parms;
   //unsigned char frame_type = 0;
   int loglvl=OAILOG_WARNING;
+  int sr_flag = 0;
 
   cpuf = get_cpu_freq_GHz();
 
@@ -112,9 +114,8 @@ int main(int argc, char **argv)
 
   randominit(0);
   logInit();
-  set_glog(loglvl);
 
-  while ((c = getopt (argc, argv, "f:hA:f:g:i:P:b:T:n:o:s:S:x:y:z:N:F:GR:IL")) != -1) {
+  while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:c")) != -1) {
     switch (c) {
     case 'f':
       //write_output_file=1;
@@ -257,12 +258,30 @@ int main(int argc, char **argv)
     case 'i':
       nrofSymbols=(uint8_t)atoi(optarg);
       break;
+    case 'I':
+      startingSymbolIndex=(uint8_t)atoi(optarg);
+      break;
+    case 'r':
+      startingPRB=atoi(optarg);
+      break;
+    case 'q':
+      nrofPRB=atoi(optarg);
+      break;
     case 'P':
       format=atoi(optarg);
       break;
+    case 'm':
+      m0=atoi(optarg);
+      break;
     case 'b':
       nr_bit=atoi(optarg);
       break;
+    case 'c':
+      sr_flag=1;
+      break;
+    case 'B':
+      actual_payload=atoi(optarg);
+      break;
     case 'T':
       nacktoack_flag=(uint8_t)atoi(optarg);
       target_error_rate=0.001;
@@ -292,23 +311,42 @@ int main(int argc, char **argv)
       printf("-f Output filename (.txt format) for Pe/SNR results\n");
       printf("-F Input filename (.txt format) for RX conformance testing\n");
       printf("-i Enter number of ofdm symbols for pucch\n");
+      printf("-I Starting symbol index for pucch\n");
+      printf("-r PUCCH starting PRB\n");
+      printf("-q PUCCH number of PRB\n");
       printf("-P Enter the format of PUCCH\n");
       printf("-b number of HARQ bits (1-2)\n");
+      printf("-B payload to be transmitted on PUCCH\n");
+      printf("-m initial cyclic shift m0\n");
       printf("-T to check nacktoack miss for format 1");
       exit (-1);
       break;
     }
   }
 
+  set_glog(loglvl);
+
   if (snr1set==0) snr1 = snr0+10;
 
   printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL);
 
+  if((format!=0) && (format!=1) && (format!=2)){
+    printf("PUCCH format %d not supported\n",format);
+    exit(0); 
+  }
+
+  AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<4)) ||
+	      ((format == 2)&&(nr_bit>2)&&(nr_bit<12)),"illegal combination format %d, nr_bit %d\n",
+	      format,nr_bit);
+
+  actual_payload &= ((1<<nr_bit)-1);
+
+  printf("Transmitted payload is %ld\n",actual_payload);
 
   RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
   RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
   gNB = RC.gNB[0];
-
+  memset((void*)gNB,0,sizeof(*gNB));
   frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
@@ -374,8 +412,10 @@ int main(int argc, char **argv)
   s_im = malloc(2*sizeof(double*));
   r_re = malloc(2*sizeof(double*));
   r_im = malloc(2*sizeof(double*));
-  txdata = malloc(2*sizeof(int*));
-
+  txdataF = malloc(2*sizeof(int*));
+  rxdataF = malloc(2*sizeof(int*));
+  gNB->common_vars.rxdataF=rxdataF;
+  memcpy((void*)&gNB->frame_parms,(void*)frame_parms,sizeof(frame_parms));
   for (i=0; i<2; i++) {
 
     s_re[i] = malloc(frame_length_complex_samples*sizeof(double));
@@ -388,16 +428,18 @@ int main(int argc, char **argv)
     r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
     bzero(r_im[i],frame_length_complex_samples*sizeof(double));
 
-    printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
-    txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
-    bzero(r_re[i],frame_length_complex_samples*sizeof(int));
-  
+    printf("Allocating %d samples for txdataF/rxdataF\n",14*frame_parms->ofdm_symbol_size);
+    txdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int));
+    bzero(txdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
+    rxdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int));
+    bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
   }
 
 
   //configure UE
   UE = malloc(sizeof(PHY_VARS_NR_UE));
   memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
+  UE->pucch_config_common_nr->hoppingId = Nid_cell;
   //phy_init_nr_top(UE); //called from init_nr_ue_signal
                       
   UE->perfect_ce = 0;
@@ -413,83 +455,110 @@ int main(int argc, char **argv)
   uint8_t mcs=0;
   startingPRB_intraSlotHopping=N_RB_DL-1;
   pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping;
-  uint32_t n_id=UE->pucch_config_common_nr->hoppingId;
-  if((format!=0) && (format!=1)){
-    printf("format not supported\n");
-    exit(0); 
+  uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
+  uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
+  if(format==0){
+  // for now we are not considering SR just HARQ-ACK
+    if (nr_bit ==0) 
+      mcs=table1_mcs[0];
+    else if(nr_bit==1)
+      mcs=table1_mcs[actual_payload];
+    else if(nr_bit==2)
+      mcs=table2_mcs[actual_payload];
+    else AssertFatal(1==0,"Either nr_bit %d or sr_flag %d must be non-zero\n", nr_bit, sr_flag);
   }
-  if(nacktoack_flag==0){ 
-    if(format==0){
-      if(nr_bit==1){
-        actual_payload=2;
-        mcs=table1_mcs[actual_payload];
-      }
-      else if(nr_bit==2){
-        actual_payload=6;
-        mcs=table2_mcs[actual_payload];
-      }
-      else{
-        printf("Number of HARQ bits possible is 1-2\n");
-        exit(0);
-      }
-    }
-    else {
-      if(nr_bit==1)
-        actual_payload=1;
-      else if(nr_bit==2)
-        actual_payload=3;
-      else{
-        printf("number of bits carried by PUCCH format1 is 1-2\n");
-      }
-    }
-  }   
+
   for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
     ack_nack_errors=0;
     n_errors = 0;
-    sigma2_dB = 20*log10((double)amp/32767)-SNR;
-    sigma2 = pow(10,sigma2_dB/10);
     for (trial=0; trial<n_trials; trial++) {
-      bzero(txdata[0],frame_length_complex_samples*sizeof(int));
+      bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
       if(format==0){
-        nr_generate_pucch0(UE,txdata,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
+        nr_generate_pucch0(UE,txdataF,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
       }
-      else{
-        nr_generate_pucch1(UE,txdata,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);	
+      else if (format == 1){
+        nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);	
       }
-      for(i=0; i<frame_length_complex_samples; i++) {
-        r_re[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)])/32767 + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
-        r_im[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)+1])/32767+ sqrt(sigma2/2)*gaussdouble(0.0,1.0));
-        r_re[aa][i]=r_re[0][i]/(sqrt(sigma2/2)+1);
-        r_im[aa][i]=r_im[0][i]/(sqrt(sigma2/2)+1);
-        if(r_re[aa][i]<-1)
-          r_re[aa][i]=-1; 
-        else if(r_re[aa][i]>1)
-          r_re[aa][i]=1;
-        if(r_im[aa][i]<-1)
-          r_im[aa][i]=-1;
-        else if(r_im[aa][i]>1)
-          r_im[aa][i]=1;	
-        ((int16_t *)txdata[aa])[(i<<1)]  = (int16_t)round(r_re[aa][i]*32767);
-        ((int16_t *)txdata[aa])[(i<<1)+1] =(int16_t)round(r_im[aa][i]*32767);
+      else {
+	nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit);	
       }
+      
+      int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
+				frame_parms->ofdm_symbol_size);
+      //      printf("txlev %d (%d dB), offset %d\n",txlev,dB_fixed(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size);
+	    
+      // note : this scaling
+      int nb_re = (format == 0 || format == 1)? 12 : 12*nrofPRB;
+      sigma2_dB = 10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/nb_re)-SNR;
+      sigma2 = pow(10,sigma2_dB/10);
+      
+      for(i=startingSymbolIndex*frame_parms->ofdm_symbol_size; i<(startingSymbolIndex+1)*frame_parms->ofdm_symbol_size; i++) {
+        ((int16_t*)rxdataF[aa])[i<<1] = (int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev));
+        ((int16_t*)rxdataF[aa])[1+(i<<1)]=(int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)+1])+ sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev));
+      }
+      int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
+				frame_parms->ofdm_symbol_size);
+      //      printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
       if(format==0){
-        nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit);
+	nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
+	nfapi_nr_pucch_pdu_t pucch_pdu;
+	pucch_pdu.subcarrier_spacing    = 1;
+	pucch_pdu.group_hop_flag        = PUCCH_GroupHopping&1;
+	pucch_pdu.sequence_hop_flag     = (PUCCH_GroupHopping>>1)&1;
+	pucch_pdu.bit_len_harq          = nr_bit;
+	pucch_pdu.sr_flag               = sr_flag;
+	pucch_pdu.nr_of_symbols         = nrofSymbols;
+	pucch_pdu.hopping_id            = hopping_id;
+	pucch_pdu.initial_cyclic_shift  = 0;
+	pucch_pdu.start_symbol_index    = startingSymbolIndex;
+	pucch_pdu.prb_start             = startingPRB;
+        nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
         if(nr_bit==1)
-          ack_nack_errors+=(((actual_payload^payload_received)&2)>>1);
+          ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
         else
-          ack_nack_errors+=(((actual_payload^payload_received)&2)>>1) + (((actual_payload^payload_received)&4)>>2);
+          ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
+	free(uci_pdu.harq->harq_list);
       }
-      else{
-        nr_decode_pucch1(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
+      else if (format==1) {
+	
+        nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
         if(nr_bit==1)
           ack_nack_errors+=((actual_payload^payload_received)&1);
         else
           ack_nack_errors+=((actual_payload^payload_received)&1) + (((actual_payload^payload_received)&2)>>1);
       }
+      else if (format==2) {
+	nfapi_nr_uci_pucch_pdu_format_2_3_4_t uci_pdu;
+	nfapi_nr_pucch_pdu_t pucch_pdu;
+	pucch_pdu.rnti = 0x1234;
+	pucch_pdu.subcarrier_spacing    = 1;
+	pucch_pdu.group_hop_flag        = PUCCH_GroupHopping&1;
+	pucch_pdu.sequence_hop_flag     = (PUCCH_GroupHopping>>1)&1;
+	pucch_pdu.bit_len_harq          = nr_bit;
+	pucch_pdu.sr_flag               = 0;
+	pucch_pdu.nr_of_symbols         = nrofSymbols;
+	pucch_pdu.hopping_id            = hopping_id;
+	pucch_pdu.initial_cyclic_shift  = 0;
+	pucch_pdu.start_symbol_index    = startingSymbolIndex;
+	pucch_pdu.prb_size              = nrofPRB;
+	pucch_pdu.prb_start             = startingPRB;
+	pucch_pdu.dmrs_scrambling_id    = dmrs_scrambling_id;
+	pucch_pdu.data_scrambling_id    = data_scrambling_id;
+        nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
+	int harq_bytes=pucch_pdu.bit_len_harq>>3;
+	if ((pucch_pdu.bit_len_harq&7) > 0) harq_bytes++;
+	for (int i=0;i<harq_bytes;i++)
+	  if (uci_pdu.harq.harq_payload[i] != ((int8_t*)&actual_payload)[i]) {
+	    ack_nack_errors++;
+	    break;
+	  }
+	free(uci_pdu.harq.harq_payload);
+
+      }
       n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
     }
-    printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors);
-    if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){
+    printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
+    if((float)ack_nack_errors/(float)(n_trials)<=target_error_rate){
       printf("PUCCH test OK\n");
       break;
     }
@@ -500,13 +569,15 @@ int main(int argc, char **argv)
     free(s_im[i]);
     free(r_re[i]);
     free(r_im[i]);
-    free(txdata[i]);
+    free(txdataF[i]);
+    free(rxdataF[i]);
   }
   free(s_re);
   free(s_im);
   free(r_re);
   free(r_im);
-  free(txdata);
+  free(txdataF);
+  free(rxdataF);
 
   if (output_fd) fclose(output_fd);
   if (input_fd)  fclose(input_fd);
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 48ea26da8f0..5881b21b5fe 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -402,7 +402,6 @@ int main(int argc, char **argv)
   rel15_ul->mcs_index           = Imcs;
   rel15_ul->pusch_data.rv_index = rvidx;
   rel15_ul->nrOfLayers          = Nl;
-  //rel15_ul->length_dmrs       = length_dmrs;
   rel15_ul->target_code_rate    = code_rate;
   rel15_ul->pusch_data.tb_size  = TBS>>3;
   ///////////////////////////////////////////////////
@@ -424,15 +423,6 @@ int main(int argc, char **argv)
   for (i = 0; i < TBS / 8; i++)
     test_input[i] = (unsigned char) rand();
 
-
-  /////////////////////////[adk] preparing NR_UE_ULSCH_t parameters///////////////////////// A HOT FIX until creating nfapi_nr_ul_config_ulsch_pdu_rel15_t
-  ///////////
-  ulsch_ue->nb_re_dmrs = nb_re_dmrs;
-  ulsch_ue->length_dmrs =  length_dmrs;
-  ulsch_ue->rnti = n_rnti;
-  ///////////
-  ////////////////////////////////////////////////////////////////////////////////////////////
-
   /////////////////////////[adk] preparing UL harq_process parameters/////////////////////////
   ///////////
   NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
@@ -442,13 +432,14 @@ int main(int argc, char **argv)
 
   if (harq_process_ul_ue) {
 
-    harq_process_ul_ue->mcs = Imcs;
-    harq_process_ul_ue->Nl = Nl;
-    harq_process_ul_ue->nb_rb = nb_rb;
-    harq_process_ul_ue->number_of_symbols = nb_symb_sch;
+    harq_process_ul_ue->pusch_pdu.rnti = n_rnti;
+    harq_process_ul_ue->pusch_pdu.mcs_index = Imcs;
+    harq_process_ul_ue->pusch_pdu.nrOfLayers = Nl;
+    harq_process_ul_ue->pusch_pdu.rb_size = nb_rb;
+    harq_process_ul_ue->pusch_pdu.nr_of_symbols = nb_symb_sch;
     harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
-    harq_process_ul_ue->rvidx = rvidx;
-    harq_process_ul_ue->TBS = TBS;
+    harq_process_ul_ue->pusch_pdu.pusch_data.rv_index = rvidx;
+    harq_process_ul_ue->pusch_pdu.pusch_data.tb_size  = TBS;
     harq_process_ul_ue->a = &test_input[0];
 
   }
@@ -461,9 +452,10 @@ int main(int argc, char **argv)
 
   /////////////////////////ULSCH coding/////////////////////////
   ///////////
+  unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl);
 
   if (input_fd == NULL) {
-    nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid);
+    nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
   }
   
   printf("\n");
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 2adc67501a5..169b82bf8d7 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -55,7 +55,8 @@
 #include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
 #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
 #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
-
+#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#include "SIMULATION/LTE_PHY/common_sim.h"
 //#define DEBUG_ULSIM
 
 PHY_VARS_gNB *gNB;
@@ -104,7 +105,7 @@ openair0_config_t openair0_cfg[MAX_CARDS];
 int main(int argc, char **argv)
 {
   char c;
-  int i,sf;
+  int i;
   double SNR, snr0 = -2.0, snr1 = 2.0;
   double sigma, sigma_dB;
   double snr_step = 1;
@@ -128,7 +129,7 @@ int main(int argc, char **argv)
   int loglvl = OAILOG_WARNING;
   uint64_t SSB_positions=0x01;
   uint16_t nb_symb_sch = 12;
-  int start_symbol = 0;
+  int start_symbol = 2;
   uint16_t nb_rb = 50;
   uint8_t Imcs = 9;
   uint8_t precod_nbr_layers = 1;
@@ -140,7 +141,7 @@ int main(int argc, char **argv)
   int start_rb = 0;
   int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
   float target_error_rate = 0.01;
-  
+  int print_perf = 0;
   cpuf = get_cpu_freq_GHz();
 
 
@@ -155,7 +156,7 @@ int main(int argc, char **argv)
   //logInit();
   randominit(0);
 
-  while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:L:")) != -1) {
+  while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:PR:S:L:")) != -1) {
     switch (c) {
 
       /*case 'd':
@@ -309,9 +310,14 @@ int main(int argc, char **argv)
         printf("Setting SNR1 to %f\n", snr1);
         break;
 
-    case 'L':
-      loglvl = atoi(optarg);
-      break;	
+      case 'P':
+        print_perf=1;
+        opp_enabled=1;
+        break;
+
+      case 'L':
+        loglvl = atoi(optarg);
+        break;
 
       default:
         case 'h':
@@ -340,6 +346,7 @@ int main(int argc, char **argv)
           printf("-O oversampling factor (1,2,4,8,16)\n");
           printf("-R N_RB_DL\n");
           printf("-S Ending SNR, runs from SNR0 to SNR1\n");
+          printf("-P Print ULSCH performances\n");
           exit(-1);
           break;
     }
@@ -370,10 +377,10 @@ int main(int argc, char **argv)
   //gNB_config = &gNB->gNB_config;
 
   //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
-  gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t));
-  gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t));
-  gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
-  gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0;
+  gNB->UL_INFO.rx_ind.pdu_list = (nfapi_nr_rx_data_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_rx_data_pdu_t));
+  gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t));
+  gNB->UL_INFO.rx_ind.number_of_pdus = 0;
+  gNB->UL_INFO.crc_ind.number_crcs = 0;
   frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
   frame_parms->nb_antennas_tx = n_tx;
   frame_parms->nb_antennas_rx = n_rx;
@@ -386,7 +393,7 @@ int main(int argc, char **argv)
   for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
     RC.nb_nr_mac_CC[i] = 1;
   mac_top_init_gNB();
-  gNB_MAC_INST* gNB_mac = RC.nrmac[0];
+  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
   gNB_RRC_INST rrc;
   memset((void*)&rrc,0,sizeof(rrc));
 
@@ -442,7 +449,7 @@ int main(int argc, char **argv)
   init_nr_ue_transport(UE, 0);
 
   /*
-  for (sf = 0; sf < 2; sf++) {
+  for (int sf = 0; sf < 2; sf++) {
     for (i = 0; i < 2; i++) {
 
         UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0);
@@ -499,31 +506,47 @@ int main(int argc, char **argv)
   uint16_t number_dmrs_symbols = 0;
   unsigned int available_bits;
   uint8_t nb_re_dmrs;
-  uint8_t length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
   unsigned char mod_order;
   uint16_t code_rate;
-
-  for (i = start_symbol; i < nb_symb_sch; i++)
-      number_dmrs_symbols += is_dmrs_symbol(i,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            0,
-                                            nb_symb_sch,
-                                            UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
-                                            frame_parms->ofdm_symbol_size);
+  uint8_t ptrs_mcs1 = 2;
+  uint8_t ptrs_mcs2 = 4;
+  uint8_t ptrs_mcs3 = 10;
+  uint16_t n_rb0 = 25;
+  uint16_t n_rb1 = 75;
+  uint8_t mcs_table = 0;
+  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
+
+  uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct
+  uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs);  // [hna] remove dmrs struct
+  uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
+  uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
+
+  if(1<<ptrs_time_density >= nb_symb_sch)
+    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+
+  for (i = 0; i < nb_symb_sch; i++) {
+    number_dmrs_symbols += (l_prime_mask >> i) & 0x01;
+  }
 
   mod_order      = nr_get_Qm_ul(Imcs, 0);
-  nb_re_dmrs     = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols;
   code_rate      = nr_get_code_rate_ul(Imcs, 0);
-  available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
-  TBS            = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers);
 
   printf("\n");
 
   for (SNR = snr0; SNR < snr1; SNR += snr_step) {
 
+      varArray_t *table_rx=initVarArray(1000,sizeof(double));
+      reset_meas(&gNB->phy_proc_rx);
+      reset_meas(&gNB->ulsch_decoding_stats);
+      reset_meas(&gNB->ulsch_deinterleaving_stats);
+      reset_meas(&gNB->ulsch_rate_unmatching_stats);
+      reset_meas(&gNB->ulsch_ldpc_decoding_stats);
+      reset_meas(&gNB->ulsch_unscrambling_stats);
+      reset_meas(&gNB->ulsch_channel_estimation_stats);
+      reset_meas(&gNB->ulsch_llr_stats);
+      reset_meas(&gNB->ulsch_channel_compensation_stats);
+      reset_meas(&gNB->ulsch_rbs_extraction_stats);
+
       UE_proc.nr_tti_tx = slot;
       UE_proc.frame_tx = frame;
 
@@ -551,16 +574,16 @@ int main(int argc, char **argv)
       UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
       memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
       
-      pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;  
+      pusch_pdu->pdu_bit_map = pdu_bit_map;
       pusch_pdu->rnti = n_rnti;
       pusch_pdu->mcs_index = Imcs;
-      pusch_pdu->mcs_table = 0; 
+      pusch_pdu->mcs_table = mcs_table;
       pusch_pdu->target_code_rate = code_rate;
       pusch_pdu->qam_mod_order = mod_order;
       pusch_pdu->transform_precoding = 0;
       pusch_pdu->data_scrambling_id = 0;
       pusch_pdu->nrOfLayers = 1;
-      pusch_pdu->ul_dmrs_symb_pos = 1;
+      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
       pusch_pdu->dmrs_config_type = 0;
       pusch_pdu->ul_dmrs_scrambling_id =  0;
       pusch_pdu->scid = 0;
@@ -575,9 +598,11 @@ int main(int argc, char **argv)
       pusch_pdu->pusch_data.rv_index = 0;
       pusch_pdu->pusch_data.harq_process_id = 0;
       pusch_pdu->pusch_data.new_data_indicator = 0;
-      pusch_pdu->pusch_data.tb_size = TBS>>3;
       pusch_pdu->pusch_data.num_cb = 0;
-
+      pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
+      pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
+      pusch_pdu->pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
+      pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
 
       // --------- setting parameters for UE --------
 
@@ -592,19 +617,33 @@ int main(int argc, char **argv)
       ul_config.slot = slot;
       ul_config.number_pdus = 1;
       ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-      ul_config.ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
-      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
+      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
+      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
+      ul_config.ul_config_list[0].pusch_config_pdu.rb_size = nb_rb;
+      ul_config.ul_config_list[0].pusch_config_pdu.rb_start = start_rb;
+      ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
+      ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
+      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
+      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = 0;
+      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
+      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = 0;
+      ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
       //there are plenty of other parameters that we don't seem to be using for now. e.g.
-      //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0;
+      ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
 
+      nb_re_dmrs     = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
+      available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
+      TBS            = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, precod_nbr_layers);
+
+      pusch_pdu->pusch_data.tb_size = TBS>>3;
+      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
       // set FAPI parameters for UE, put them in the scheduled response and call
       nr_ue_scheduled_response(&scheduled_response);
 
@@ -651,15 +690,17 @@ int main(int argc, char **argv)
         //----------------------------------------------------------
         //------------------- gNB phy procedures -------------------
         //----------------------------------------------------------
-        gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
-        gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0;
+        gNB->UL_INFO.rx_ind.number_of_pdus = 0;
+        gNB->UL_INFO.crc_ind.number_crcs = 0;
 
+        start_meas(&gNB->phy_proc_rx);
         phy_procedures_gNB_common_RX(gNB, frame, slot);
 
 	if (n_trials==1)
 	  LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1);
 
         phy_procedures_gNB_uespec_RX(gNB, frame, slot);
+        start_meas(&gNB->phy_proc_rx);
         ////////////////////////////////////////////////////////////
 
 	if (gNB->ulsch[0][0]->last_iteration_cnt >= 
@@ -683,7 +724,7 @@ int main(int argc, char **argv)
 
         if (errors_scrambling > 0) {
 	  if (n_trials==1)
-	    printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling);
+	    printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling);
         }
 
         for (i = 0; i < TBS; i++) {
@@ -701,18 +742,32 @@ int main(int argc, char **argv)
         if (errors_decoding > 0) {
           n_false_positive++;
 	  if (n_trials==1)
-	    printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding     = %d\n" "\x1B[0m", frame, trial, errors_decoding);
+	    printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding     = %u\n" "\x1B[0m", frame, trial, errors_decoding);
         } 
 
       } // trial loop
 
       printf("*****************************************\n");
-      printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %d/%d\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, n_trials);
+      printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %u/%d\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, n_trials);
       printf("\n");
       printf("SNR %f: Channel BLER %e, Channel BER %e\n", SNR,(double)n_errors/n_trials,(double)errors_scrambling/available_bits/n_trials);
       printf("*****************************************\n");
       printf("\n");
 
+      if (print_perf==1) {
+        printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
+        printStatIndent(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
+        printStatIndent(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
+        printStatIndent(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
+        printStatIndent(&gNB->ulsch_llr_stats,"ULSCH llr computation");
+        printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
+        printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
+        printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
+        printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
+        printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
+        printf("\n");
+      }
+
       if(n_trials==1)
 	break;
 
@@ -736,5 +791,8 @@ int main(int argc, char **argv)
   if (input_fd)
     fclose(input_fd);
 
+  if (scg_fd)
+    fclose(scg_fd);
+
   return (n_errors);
 }
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index 7a7e984aca0..1eb58b16b20 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -73,7 +73,9 @@
   #ifdef UESIM_EXPANSION
     #define MAX_MOBILES_PER_ENB         256
     #define MAX_MOBILES_PER_ENB_NB_IoT  256
+    #define MAX_MOBILES_PER_GNB         256
     #define MAX_eNB                      2
+    #define MAX_gNB                      2
   #else
     #ifdef LARGE_SCALE
       #define MAX_MOBILES_PER_ENB         128
diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h
index 1d0c2dfdb85..cde24978808 100644
--- a/openair2/COMMON/rrc_messages_def.h
+++ b/openair2/COMMON/rrc_messages_def.h
@@ -76,3 +76,6 @@ MESSAGE_DEF(NAS_DOWNLINK_DATA_IND,      MESSAGE_PRIORITY_MED,       NasDlDataInd
 
 // eNB: realtime -> RRC messages
 MESSAGE_DEF(RRC_SUBFRAME_PROCESS,       MESSAGE_PRIORITY_MED,       RrcSubframeProcess,         rrc_subframe_process)
+
+// eNB: RLC -> RRC messages
+MESSAGE_DEF(RLC_SDU_INDICATION,         MESSAGE_PRIORITY_MED,       RlcSduIndication,           rlc_sdu_indication)
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 68e1753448b..7582de65ba4 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -87,6 +87,8 @@
 
 #define RRC_SUBFRAME_PROCESS(mSGpTR)    (mSGpTR)->ittiMsg.rrc_subframe_process
 
+#define RLC_SDU_INDICATION(mSGpTR)      (mSGpTR)->ittiMsg.rlc_sdu_indication
+
 //-------------------------------------------------------------------------------------------//
 typedef struct RrcStateInd_s {
   Rrc_State_t     state;
@@ -429,4 +431,12 @@ typedef struct rrc_subframe_process_s {
   int             CC_id;
 } RrcSubframeProcess;
 
+// eNB: RLC -> RRC messages
+typedef struct rlc_sdu_indication_s {
+  int rnti;
+  int is_successful;
+  int srb_id;
+  int message_id;
+} RlcSduIndication;
+
 #endif /* RRC_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index aa718dbcf88..8e13e35d654 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -78,7 +78,6 @@
  * the key length is 32 bytes (256 bits)
  */
 #define SECURITY_KEY_LENGTH 32
-#ifndef OCP_FRAMEWORK
 typedef enum cell_type_e {
   CELL_MACRO_ENB,
   CELL_HOME_ENB,
@@ -110,7 +109,6 @@ typedef enum cn_domain_s {
   CN_DOMAIN_PS = 1,
   CN_DOMAIN_CS = 2
 } cn_domain_t;
-#endif
 
 typedef struct net_ip_address_s {
   unsigned ipv4:1;
@@ -126,7 +124,6 @@ typedef struct ambr_s {
   bitrate_t br_dl;
 } ambr_t;
 
-#ifndef OCP_FRAMEWORK
 typedef enum priority_level_s {
   PRIORITY_LEVEL_SPARE       = 0,
   PRIORITY_LEVEL_HIGHEST     = 1,
@@ -145,7 +142,6 @@ typedef enum pre_emp_vulnerability_e {
   PRE_EMPTION_VULNERABILITY_DISABLED = 1,
   PRE_EMPTION_VULNERABILITY_MAX,
 } pre_emp_vulnerability_t;
-#endif
 
 typedef struct allocation_retention_priority_s {
   priority_level_t        priority_level;
diff --git a/openair2/DOCS/TEMPLATES/CODE/example_doxy.h b/openair2/DOCS/TEMPLATES/CODE/example_doxy.h
index c51bdbccabc..30d8ddb6009 100644
--- a/openair2/DOCS/TEMPLATES/CODE/example_doxy.h
+++ b/openair2/DOCS/TEMPLATES/CODE/example_doxy.h
@@ -31,6 +31,9 @@
 * \warning  this is a warning
 */
 
+#ifndef __DOCS_TEMPLATES_CODE_EXAMPLE_DOXY__H__
+#define __DOCS_TEMPLATES_CODE_EXAMPLE_DOXY__H__
+
 //-----------------------------------begin group-----------------------------
 
 
@@ -138,3 +141,4 @@ struct frame {
 int init(int src, int dst);
 
 //-----------------------end func proto-------------------
+#endif
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
index c489f10dae1..975ac4e96ff 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c
@@ -939,7 +939,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
 
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
     for (j = 0; j < 8; j++) {
-      if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) {
+      if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_info.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) {
 	available_harq[i] = j;
 	break;
       }
@@ -977,13 +977,13 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
 
       dl_info[i]->harq_process_id = available_harq[UE_id];
       if (RC.mac && RC.mac[mod_id])
-        RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id, UE_id)][UE_id].harq_pid = 0;
+        RC.mac[mod_id]->UE_info.eNB_UE_stats[UE_PCCID(mod_id, UE_id)][UE_id].harq_pid = 0;
       dl_info[i]->has_harq_process_id = 1;
       /* Fill in the status of the HARQ process (2 TBs)*/
       dl_info[i]->n_harq_status = 2;
       dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status);
       for (j = 0; j < dl_info[i]->n_harq_status; j++) {
-        dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[UE_id].round[UE_PCCID(mod_id, UE_id)][j];
+        dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_info.UE_sched_ctrl[UE_id].round[UE_PCCID(mod_id, UE_id)][j];
         // TODO: This should be different per TB
       }
       //      LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]);
@@ -1357,7 +1357,7 @@ void flexran_agent_init_mac_agent(mid_t mod_id) {
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
     for (j = 0; j < 8; j++) {
       if (RC.mac && RC.mac[mod_id])
-        RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0;
+        RC.mac[mod_id]->UE_info.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0;
     }
   }
 }
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
index 30c10940c99..a85cbac5439 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c
@@ -290,7 +290,7 @@ Protocol__FlexUlCqiReport * copy_ul_cqi_report(Protocol__FlexUlCqiReport * origi
   full_ul_report->has_sfn_sn = original->has_sfn_sn;
   full_ul_report->n_cqi_meas = original->n_cqi_meas;
 
-  Protocol__FlexUlCqi **ul_report;
+  Protocol__FlexUlCqi **ul_report=NULL;
   ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas);
   if(ul_report == NULL)
     goto error;
@@ -348,7 +348,7 @@ Protocol__FlexDlCqiReport * copy_dl_cqi_report(Protocol__FlexDlCqiReport * origi
   dl_report->has_sfn_sn = original->has_sfn_sn;
   dl_report->n_csi_report = original->n_csi_report;
 
-  Protocol__FlexDlCsi **csi_reports;
+  Protocol__FlexDlCsi **csi_reports=NULL;
   csi_reports = malloc(sizeof(Protocol__FlexDlCsi *) * dl_report->n_csi_report);
   if (csi_reports == NULL)
     goto error;
@@ -383,7 +383,7 @@ Protocol__FlexPagingBufferReport * copy_paging_buffer_report(Protocol__FlexPagin
   protocol__flex_paging_buffer_report__init(copy);
   copy->n_paging_info = original->n_paging_info;
   
-  Protocol__FlexPagingInfo **p_info;
+  Protocol__FlexPagingInfo **p_info=NULL;
   p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * copy->n_paging_info);
   if (p_info == NULL)
     goto error;
diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h
index 210b753afbb..72e77c38000 100644
--- a/openair2/ENB_APP/L1_paramdef.h
+++ b/openair2/ENB_APP/L1_paramdef.h
@@ -30,6 +30,8 @@
  * \warning
  */
 
+#ifndef __ENB_APP_L1_PARAMDEF__H__
+#define __ENB_APP_L1_PARAMDEF__H__
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
@@ -114,3 +116,5 @@
 #define L1_PUCCH1_DTX_EMTC3_THRESHOLD_IDX                  22
 #define L1_PUCCH1AB_DTX_EMTC3_THRESHOLD_IDX                23
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+#endif
diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h
index 724dde6557e..55ce9d5059e 100644
--- a/openair2/ENB_APP/MACRLC_paramdef.h
+++ b/openair2/ENB_APP/MACRLC_paramdef.h
@@ -31,6 +31,8 @@
  */
 
 
+#ifndef __ENB_APP_MACRLC_PARAMDEF__H__
+#define __ENB_APP_MACRLC_PARAMDEF__H__
 
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 
@@ -104,3 +106,5 @@
 #define MACRLC_PUSCH10xSNR_IDX                                 18
 #define MACRLC_PUCCH10xSNR_IDX                                 19 
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+#endif
diff --git a/openair2/ENB_APP/NB_IoT_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h
index 6409fe63ee5..8778f6d2e40 100644
--- a/openair2/ENB_APP/NB_IoT_paramdef.h
+++ b/openair2/ENB_APP/NB_IoT_paramdef.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __ENB_APP_NB_IOT_PARAMDEF__H__
+#define __ENB_APP_NB_IOT_PARAMDEF__H__
+
 #include "common/config/config_paramdesc.h"
 #include "SystemInformationBlockType2.h"
 #include "DL-GapConfig-NB-r13.h"
@@ -398,3 +401,5 @@
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /* NB IoT L1 configuration list section name   */
 #define NBIOT_L1LIST_CONFIG_STRING                          "NB-IoT_L1s"
+
+#endif
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index f91c7056c59..344214a1f17 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -90,6 +90,7 @@ typedef enum {
 #define CONFIG_STRING_RU_NBIOTRRC_LIST            "NbIoT_RRC_instances"
 #define CONFIG_STRING_RU_SDR_ADDRS                "sdr_addrs"
 #define CONFIG_STRING_RU_SDR_CLK_SRC              "clock_src"
+#define CONFIG_STRING_RU_SDR_TME_SRC              "time_src"
 #define CONFIG_STRING_RU_SF_EXTENSION             "sf_extension"
 #define CONFIG_STRING_RU_END_OF_BURST_DELAY       "end_of_burst_delay"
 #define CONFIG_STRING_RU_OTA_SYNC_ENABLE          "ota_sync_enabled"
@@ -117,11 +118,12 @@ typedef enum {
 #define RU_NBIOTRRC_LIST_IDX          18
 #define RU_SDR_ADDRS                  19
 #define RU_SDR_CLK_SRC                20
-#define RU_SF_EXTENSION_IDX           21
-#define RU_END_OF_BURST_DELAY_IDX     22
-#define RU_OTA_SYNC_ENABLE_IDX        23
-#define RU_BF_WEIGHTS_LIST_IDX        24
-#define RU_IF_FREQUENCY               25
+#define RU_SDR_TME_SRC                21
+#define RU_SF_EXTENSION_IDX           22
+#define RU_END_OF_BURST_DELAY_IDX     23
+#define RU_OTA_SYNC_ENABLE_IDX        24
+#define RU_BF_WEIGHTS_LIST_IDX        25
+#define RU_IF_FREQUENCY               26
 
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
@@ -149,6 +151,7 @@ typedef enum {
     {CONFIG_STRING_RU_NBIOTRRC_LIST,               NULL,       0,       uptr:NULL,       defintarrayval:DEFENBS,  TYPE_INTARRAY,    1}, \
     {CONFIG_STRING_RU_SDR_ADDRS,                   NULL,       0,       strptr:NULL,     defstrval:"type=b200",   TYPE_STRING,      0}, \
     {CONFIG_STRING_RU_SDR_CLK_SRC,                 NULL,       0,       strptr:NULL,     defstrval:"internal",    TYPE_STRING,      0}, \
+    {CONFIG_STRING_RU_SDR_TME_SRC,                 NULL,       0,       strptr:NULL,     defstrval:"internal",    TYPE_STRING,      0}, \
     {CONFIG_STRING_RU_SF_EXTENSION,                NULL,       0,       uptr:NULL,       defuintval:312,          TYPE_UINT,        0}, \
     {CONFIG_STRING_RU_END_OF_BURST_DELAY,          NULL,       0,       uptr:NULL,       defuintval:400,          TYPE_UINT,        0}, \
     {CONFIG_STRING_RU_OTA_SYNC_ENABLE,             NULL,       0,       strptr:NULL,     defstrval:"no",          TYPE_STRING,      0}, \
diff --git a/openair2/ENB_APP/enb_paramdef_emtc.h b/openair2/ENB_APP/enb_paramdef_emtc.h
index 7ec6f4940a3..de774c4ea69 100644
--- a/openair2/ENB_APP/enb_paramdef_emtc.h
+++ b/openair2/ENB_APP/enb_paramdef_emtc.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __ENB_APP_ENB_PARAMDEF_EMTC__H__
+#define __ENB_APP_ENB_PARAMDEF_EMTC__H__
+
 #include "common/config/config_paramdesc.h"
 #include "RRC_paramsvalues.h"
 
@@ -405,3 +408,5 @@ typedef struct ccparams_eMTC_s {
 {"sib2_interval_ULHoppingConfigCommonModeB_r13_val",                 NULL,   0,           iptr:&eMTCconfig->sib2_interval_ULHoppingConfigCommonModeB_r13_val,   defintval:0,            TYPE_UINT,       0}, \
 {"sib2_mpdcch_pdsch_hoppingOffset_r13",                              NULL,   0,           iptr:&eMTCconfig->sib2_mpdcch_pdsch_hoppingOffset_r13,                defintval:1,             TYPE_UINT,         0} \
 }
+
+#endif
diff --git a/openair2/ENB_APP/enb_paramdef_mce.h b/openair2/ENB_APP/enb_paramdef_mce.h
index 8a4dd157667..fdc2731e16b 100644
--- a/openair2/ENB_APP/enb_paramdef_mce.h
+++ b/openair2/ENB_APP/enb_paramdef_mce.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __ENB_APP_ENB_PARAMDEF_MCE__H__
+#define __ENB_APP_ENB_PARAMDEF_MCE__H__
+
 #include "common/config/config_paramdesc.h"
 #include "RRC_paramsvalues.h"
 
@@ -235,5 +238,4 @@
 #define MCE_CONFIG_STRING_NUM_FRAME_IDX	2
 #define MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX	3
 
-
-
+#endif
diff --git a/openair2/ENB_APP/enb_paramdef_mme.h b/openair2/ENB_APP/enb_paramdef_mme.h
index 0ff1df765c0..fde9b1c3a87 100644
--- a/openair2/ENB_APP/enb_paramdef_mme.h
+++ b/openair2/ENB_APP/enb_paramdef_mme.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __ENB_APP_ENB_PARAMDEF_MME__H__
+#define __ENB_APP_ENB_PARAMDEF_MME__H__
+
 #include "common/config/config_paramdesc.h"
 #include "RRC_paramsvalues.h"
 
@@ -77,6 +80,4 @@
 {MME_CONFIG_STRING_MME_PORT_FOR_M3C,                     NULL,      0,         uptr:&mme_port_for_m3c,           	 defintval:36444L,    TYPE_UINT,        0},      \
 } 
 
-
-
-
+#endif
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index a66081d99f2..32cb8c74e18 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -98,7 +98,7 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) {
 int flexran_get_mac_num_ues(mid_t mod_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.num_UEs;
+  return RC.mac[mod_id]->UE_info.num_UEs;
 }
 
 int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id) {
@@ -123,7 +123,7 @@ int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) {
 
   /* get the (active) UE with RNTI i */
   for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[mod_id]->UE_list.active[n] == TRUE
+    if (RC.mac[mod_id]->UE_info.active[n] == TRUE
         && rnti == UE_RNTI(mod_id, n)) {
       return n;
     }
@@ -139,7 +139,7 @@ int flexran_get_mac_ue_id(mid_t mod_id, int i) {
 
   /* get the (i+1)'th active UE */
   for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[mod_id]->UE_list.active[n] == TRUE) {
+    if (RC.mac[mod_id]->UE_info.active[n] == TRUE) {
       if (i == 0)
         return n;
 
@@ -159,19 +159,19 @@ rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id) {
 int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid) {
   if (!mac_is_present(mod_id)) return -1;
 
-  return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid];
+  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid];
 }
 
 int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info;
+  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info;
 }
 
 uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0];
+  return RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].dl_cqi[0];
 }
 
 rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
@@ -180,7 +180,7 @@ rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logi
   rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0,0, 0
+  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0
                                                        );
   return rlc_status.bytes_in_buffer;
 }
@@ -191,7 +191,7 @@ rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, lo
   rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0,0, 0
+  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0
                                                        );
   return rlc_status.pdus_in_buffer;
 }
@@ -202,7 +202,7 @@ frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t chann
   rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0,0, 0
+  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0, 0
                                                        );
   return rlc_status.head_sdu_creation_time;
 }
@@ -242,7 +242,7 @@ int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
 uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes;
 }
 
 uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) {
@@ -251,7 +251,7 @@ uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id
   uint64_t bytes = 0;
 
   for (int i = 0; i < NB_RB_MAX; ++i) {
-    bytes += RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i];
+    bytes += RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i];
   }
 
   return bytes;
@@ -260,135 +260,135 @@ uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id
 uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].TBS;
 }
 
 uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_TBS;
 }
 
 uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_retx;
 }
 
 uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx;
 }
 
 uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used;
 }
 
 uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_rx;
 }
 
 uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id];
+  return RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id];
 }
 
 uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
 }
 
 uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2;
 }
 
 uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1;
 }
 
 uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2;
 }
 
 uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_rbs_used;
 }
 
 uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx;
 }
 
 uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_num_pdus;
 }
 
 uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx;
 }
 
 uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes;
 }
 
 uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS;
 }
 
 int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].harq_round;
 }
 
 uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx;
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx;
 }
 
 unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index];
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index];
 }
 
 uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid];
+  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid];
 }
 
 
 /* TODO needs to be revised */
 void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
   /*
-    UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list;
-    UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id];
+    UE_info_t *UE_info=&eNB_mac_inst[mod_id].UE_info;
+    UE_sched_ctrl *ue_sched_ctl = &UE_info->UE_sched_ctrl[ue_id];
 
     if (ue_sched_ctl->ta_timer == 0) {
 
@@ -432,7 +432,7 @@ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
 int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.numactiveCCs[ue_id];
+  return RC.mac[mod_id]->UE_info.numactiveCCs[ue_id];
 }
 
 uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
@@ -890,13 +890,13 @@ uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) {
 uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
+  return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
 }
 
 uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
+  return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
 }
 
 int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti) {
@@ -1235,7 +1235,7 @@ uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti) {
 long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) {
   if (!mac_is_present(mod_id)) return 0;
 
-  return RC.mac[mod_id]->UE_list.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id];
+  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id];
 }
 
 /* TODO Navid: needs to be revised */
@@ -3016,7 +3016,7 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti)
 int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return -1;
 
-  int slice_idx = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id];
+  int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id];
 
   if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl)
     return RC.mac[mod_id]->slice_info.dl[slice_idx].id;
@@ -3031,13 +3031,13 @@ void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
 
   if (!flexran_dl_slice_exists(mod_id, slice_idx)) return;
 
-  RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx;
+  //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id] = slice_idx;
 }
 
 int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
   if (!mac_is_present(mod_id)) return -1;
 
-  int slice_idx = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id];
+  int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id];
 
   if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul)
     return RC.mac[mod_id]->slice_info.ul[slice_idx].id;
@@ -3052,7 +3052,7 @@ void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) {
 
   if (!flexran_ul_slice_exists(mod_id, slice_idx)) return;
 
-  RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx;
+  //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id] = slice_idx;
 }
 
 int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) {
@@ -3103,14 +3103,14 @@ int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) {
 
   memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl]));
   /* all UEs that have been in the old slice are put into slice index 0 */
-  int *assoc_list = RC.mac[mod_id]->UE_list.assoc_dl_slice_idx;
+  //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_dl_slice_idx;
 
-  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
-    if (assoc_list[i] == slice_idx)
-      assoc_list[i] = 0;
-  }
+  //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
+  //  if (assoc_list[i] == slice_idx)
+  //    assoc_list[i] = 0;
+  //}
 
-  return sli->n_dl;
+  return 1;
 }
 
 int flexran_get_num_dl_slices(mid_t mod_id) {
@@ -3397,12 +3397,12 @@ int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) {
 
   memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul]));
   /* all UEs that have been in the old slice are put into slice index 0 */
-  int *assoc_list = RC.mac[mod_id]->UE_list.assoc_ul_slice_idx;
+  //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_ul_slice_idx;
 
-  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
-    if (assoc_list[i] == slice_idx)
-      assoc_list[i] = 0;
-  }
+  //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) {
+  //  if (assoc_list[i] == slice_idx)
+  //    assoc_list[i] = 0;
+  //}
 
   return sli->n_ul;
 }
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index edc5a2c0a9a..a64f2d529b3 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -37,7 +37,6 @@
 #include "f1ap_cu_ue_context_management.h"
 #include <string.h>
 
-#include "openair2/LAYER2/MAC/mac_proto.h"
 #include "rrc_extern.h"
 #include "rrc_eNB_UE_context.h"
 #include "rrc_eNB_S1AP.h"
diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
index 803551818ae..fb9450728b4 100644
--- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c
+++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c
@@ -697,7 +697,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance,
           break;
         }
         
-        UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_list.UE_sched_ctrl[UE_id_mac]);
+        UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]);
         
         if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
           UE_scheduling_control->cdrx_waiting_ack = FALSE;
diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c
index b9c79e1f18a..bae59a509e2 100644
--- a/openair2/F1AP/f1ap_du_ue_context_management.c
+++ b/openair2/F1AP/f1ap_du_ue_context_management.c
@@ -633,9 +633,9 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t       instance,
   int UE_out_of_sync = 0;
 
   for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[instance]->UE_list.active[n] == TRUE
+    if (RC.mac[instance]->UE_info.active[n] == TRUE
         && rnti == UE_RNTI(instance, n)) {
-      UE_out_of_sync = RC.mac[instance]->UE_list.UE_sched_ctrl[n].ul_out_of_sync;
+      UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync;
       break;
     }
   }
diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h
index 889a50c814b..a5a808c2811 100644
--- a/openair2/GNB_APP/L1_nr_paramdef.h
+++ b/openair2/GNB_APP/L1_nr_paramdef.h
@@ -30,6 +30,8 @@
  * \warning
  */
 
+#ifndef __GNB_APP_L1_NR_PARAMDEF__H__
+#define __GNB_APP_L1_NR_PARAMDEF__H__
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
@@ -71,3 +73,4 @@
 #define L1_REMOTE_N_PORTD_IDX                              8
 
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+#endif
diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h
index b55aeacdce7..308af2eeb91 100644
--- a/openair2/GNB_APP/MACRLC_nr_paramdef.h
+++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h
@@ -31,6 +31,8 @@
  */
 
 
+#ifndef __GNB_APP_MACRLC_NR_PARAMDEF__H__
+#define __GNB_APP_MACRLC_NR_PARAMDEF__H__
 
 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 
@@ -96,3 +98,4 @@
 #define MACRLC_LOCAL_S_PORTD_IDX                               15
 #define MACRLC_REMOTE_S_PORTD_IDX                              16
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#endif
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index 82873f22b4b..4c5da80764c 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -128,18 +128,18 @@
 #define GNB_CONFIG_STRING_RARESPONSEWINDOW                      "ra_ResponseWindow"
 #define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSBPR   "ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR"
 #define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSB     "ssb_perRACH_OccasionAndCB_PreamblesPerSSB"
-#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER                    "ra_ContentionResolutionTimer"                     
-#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB                               "rsrp_ThresholdSSB"                                
-#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR                     "prach_RootSequenceIndex_PR"                     
-#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX                     "prach_RootSequenceIndex"                     
-#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING                          "msg1_SubcarrierSpacing"                           
-#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG                            "restrictedSetConfig"                              
-#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST                  "puschTimeDomainAllocationList"
-#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE                              "msg3_DeltaPreamble"
-#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT                             "p0_NominalWithGrant"
-#define GNB_CONFIG_STRING_PUCCHGROUPHOPPING                              "pucchGroupHopping"
-#define GNB_CONFIG_STRING_HOPPINGID                                      "hoppingId"
-#define GNB_CONFIG_STRING_P0NOMINAL                                      "p0_nominal"
+#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER           "ra_ContentionResolutionTimer"                     
+#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB                      "rsrp_ThresholdSSB"                                
+#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR              "prach_RootSequenceIndex_PR"                     
+#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX                "prach_RootSequenceIndex"                     
+#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING                 "msg1_SubcarrierSpacing"                           
+#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG                   "restrictedSetConfig"                              
+#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST         "puschTimeDomainAllocationList"
+#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE                     "msg3_DeltaPreamble"
+#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT                    "p0_NominalWithGrant"
+#define GNB_CONFIG_STRING_PUCCHGROUPHOPPING                     "pucchGroupHopping"
+#define GNB_CONFIG_STRING_HOPPINGID                             "hoppingId"
+#define GNB_CONFIG_STRING_P0NOMINAL                             "p0_nominal"
 #define GNB_CONFIG_STRING_INITIALULBWPK2_0                      "initialULBWPk2_0"
 #define GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0             "initialULBWPmappingType_0"
 #define GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0    "initialULBWPstartSymbolAndLength_0"
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 93555170726..e7fd2f3cf84 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -978,8 +978,6 @@ void NRRCConfig(void) {
   paramlist_def_t RUParamList     = {CONFIG_STRING_RU_LIST,NULL,0};
   paramdef_t GNBSParams[]         = GNBSPARAMS_DESC;
   
-  char aprefix[MAX_OPTNAME_SIZE*2 + 8];  
-  
 /* get global parameters, defined outside any section in the config file */
  
   LOG_I(GNB_APP, "Getting GNBSParams\n");
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index 2d9ecb8c8a5..84045fc622f 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __GNB_APP_GNB_PARAMDEF__H__
+#define __GNB_APP_GNB_PARAMDEF__H__
+
 #include "common/config/config_paramdesc.h"
 #include "RRC_nr_paramsvalues.h"
 
@@ -430,3 +433,4 @@ typedef struct ccparams_nr_x2 {
 #define CONFIG_HLP_WORKER                          "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
 #define CONFIG_HLP_PARALLEL                        "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#endif
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 76c8e33b168..49949bd771b 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -782,7 +782,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
   int i;
   int UE_id = -1;
   eNB_MAC_INST *eNB = RC.mac[Mod_idP];
-  UE_list_t *UE_list= &eNB->UE_list;
+  UE_info_t *UE_info= &eNB->UE_info;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
   LOG_D(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib);
 
@@ -882,6 +882,34 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
     }
   }
 
+  if (logicalChannelIdentity > 0) { // is SRB1,2 or DRB
+    if ((UE_id = find_UE_id(Mod_idP, rntiP)) < 0) {
+      LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP);
+      return(-1);
+    }
+    int idx = -1;
+    UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
+      if (sched_ctrl->dl_lc_ids[i] == logicalChannelIdentity) {
+        /* TODO this might also mean we have to remove it, not clear */
+        idx = i;
+        break;
+      }
+    }
+    if (idx < 0) {
+      sched_ctrl->dl_lc_num++;
+      sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num-1] = logicalChannelIdentity;
+      sched_ctrl->dl_lc_bytes[sched_ctrl->dl_lc_num-1] = 0;
+      LOG_I(MAC, "UE %d RNTI %x adding LC %ld idx %d to scheduling control (total %d)\n", UE_id, rntiP, logicalChannelIdentity, sched_ctrl->dl_lc_num-1, sched_ctrl->dl_lc_num);
+      if (logicalChannelIdentity == 1) { // if it is SRB1, add SRB2 directly because RRC does not indicate this separately
+        sched_ctrl->dl_lc_num++;
+        sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num-1] = 2;
+        sched_ctrl->dl_lc_bytes[sched_ctrl->dl_lc_num-1] = 0;
+        LOG_I(MAC, "UE %d RNTI %x adding LC 2 idx %d to scheduling control (total %d)\n", UE_id, rntiP, sched_ctrl->dl_lc_num-1, sched_ctrl->dl_lc_num);
+      }
+    }
+  }
+
   // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
   if (logicalChannelConfig != NULL) { // check for eMTC specific things
     UE_id = find_UE_id(Mod_idP, rntiP);
@@ -892,9 +920,9 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
     }
 
     if (logicalChannelConfig) {
-      UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity]      = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
-      UE_list->UE_template[CC_idP][UE_id].lcgidpriority[logicalChannelIdentity] =  logicalChannelConfig->ul_SpecificParameters->priority;
-    } else UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity]   =  0;
+      UE_info->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity]      = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup;
+      UE_info->UE_template[CC_idP][UE_id].lcgidpriority[logicalChannelIdentity] =  logicalChannelConfig->ul_SpecificParameters->priority;
+    } else UE_info->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity]   =  0;
   }
 
   if (physicalConfigDedicated != NULL) {
@@ -905,7 +933,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
       return(-1);
     }
 
-    UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated = physicalConfigDedicated;
+    UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated = physicalConfigDedicated;
     LOG_I(MAC,"Added physicalConfigDedicated %p for %d.%d\n",physicalConfigDedicated,CC_idP,UE_id);
   }
 
@@ -1048,15 +1076,11 @@ void eNB_Config_Local_DRX(instance_t Mod_id,
                           rrc_mac_drx_config_req_t *rrc_mac_drx_config_req)
 //-----------------------------------------------------------------------------
 {
-  UE_list_t *UE_list_mac = NULL;
+  UE_info_t *UE_info_mac = &RC.mac[Mod_id]->UE_info;
   UE_sched_ctrl_t *UE_scheduling_control = NULL;
-  int UE_id = -1;
-  
-  rnti_t rnti = rrc_mac_drx_config_req->rnti;
   LTE_DRX_Config_t *const drx_Configuration = rrc_mac_drx_config_req->drx_Configuration;
-
-  UE_list_mac = &(RC.mac[Mod_id]->UE_list);
-  UE_id = find_UE_id(Mod_id, rnti);
+  rnti_t rnti = rrc_mac_drx_config_req->rnti;
+  int UE_id = find_UE_id(Mod_id, rnti);
 
   /* Check UE_id */
   if (UE_id == -1) {
@@ -1065,7 +1089,7 @@ void eNB_Config_Local_DRX(instance_t Mod_id,
   }
 
   /* Get struct to modify */
-  UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]);
+  UE_scheduling_control = &(UE_info_mac->UE_sched_ctrl[UE_id]);
   UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error
 
   /* Check drx_Configuration */
diff --git a/openair2/LAYER2/MAC/config_NB_IoT.h b/openair2/LAYER2/MAC/config_NB_IoT.h
index fb8c85ebed2..1821b4e12d8 100644
--- a/openair2/LAYER2/MAC/config_NB_IoT.h
+++ b/openair2/LAYER2/MAC/config_NB_IoT.h
@@ -8,8 +8,8 @@
  *
  */
 
-#ifndef _CONFIG_H_
-#define _CONFIG_H_
+#ifndef __LAYER2_MAC_CONFIG_NB_IOT__H__
+#define __LAYER2_MAC_CONFIG_NB_IOT__H__
 
 //#include "NB_IoT_Message_definitions.h"
 
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
deleted file mode 100644
index 05660b727e9..00000000000
--- a/openair2/LAYER2/MAC/defs.h
+++ /dev/null
@@ -1,1321 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/*! \file LAYER2/MAC/defs.h
-* \brief MAC data structures, constant, and function prototype
-* \author Navid Nikaein and Raymond Knopp
-* \date 2011
-* \version 0.5
-* \email navid.nikaein@eurecom.fr
-
-*/
-/** @defgroup _oai2  openair2 Reference Implementation
- * @ingroup _ref_implementation_
- * @{
- */
-
-/*@}*/
-
-#ifndef __LAYER2_MAC_DEFS_H__
-#define __LAYER2_MAC_DEFS_H__
-
-
-
-#ifdef USER_MODE
-  #include <stdio.h>
-  #include <stdlib.h>
-  #include <string.h>
-#endif
-
-//#include "COMMON/openair_defs.h"
-
-
-
-#include "PHY/defs.h"
-#include "PHY/LTE_TRANSPORT/defs.h"
-#include "COMMON/platform_constants.h"
-#include "BCCH-BCH-Message.h"
-#include "RadioResourceConfigCommon.h"
-#include "RadioResourceConfigDedicated.h"
-#include "MeasGapConfig.h"
-#include "SchedulingInfoList.h"
-#include "TDD-Config.h"
-#include "RACH-ConfigCommon.h"
-#include "MeasObjectToAddModList.h"
-#include "MobilityControlInfo.h"
-#include "MBSFN-AreaInfoList-r9.h"
-#include "MBSFN-SubframeConfigList.h"
-#include "PMCH-InfoList-r9.h"
-#include "SCellToAddMod-r10.h"
-#include "SystemInformationBlockType1-v1310-IEs.h"
-
-
-#include "nfapi_interface.h"
-#include "PHY_INTERFACE/IF_Module.h"
-
-/** @defgroup _mac  MAC
- * @ingroup _oai2
- * @{
- */
-
-#define BCCH_PAYLOAD_SIZE_MAX 128
-#define CCCH_PAYLOAD_SIZE_MAX 128
-#define PCCH_PAYLOAD_SIZE_MAX 128
-#define RAR_PAYLOAD_SIZE_MAX 128
-
-#define SCH_PAYLOAD_SIZE_MAX 4096
-/// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB)
-
-
-// Mask for identifying subframe for MBMS
-#define MBSFN_TDD_SF3 0x80// for TDD
-#define MBSFN_TDD_SF4 0x40
-#define MBSFN_TDD_SF7 0x20
-#define MBSFN_TDD_SF8 0x10
-#define MBSFN_TDD_SF9 0x08
-#define MBSFN_FDD_SF1 0x80// for FDD
-#define MBSFN_FDD_SF2 0x40
-#define MBSFN_FDD_SF3 0x20
-#define MBSFN_FDD_SF6 0x10
-#define MBSFN_FDD_SF7 0x08
-#define MBSFN_FDD_SF8 0x04
-
-#define MAX_MBSFN_AREA 8
-#define MAX_PMCH_perMBSFN 15
-/*!\brief MAX MCCH payload size  */
-#define MCCH_PAYLOAD_SIZE_MAX 128
-
-
-#ifdef USER_MODE
-  #define printk printf
-#endif //USER_MODE
-
-/*!\brief Maximum number of logical channl group IDs */
-#define MAX_NUM_LCGID 4
-/*!\brief logical channl group ID 0 */
-#define LCGID0 0
-/*!\brief logical channl group ID 1 */
-#define LCGID1 1
-/*!\brief logical channl group ID 2 */
-#define LCGID2 2
-/*!\brief logical channl group ID 3 */
-#define LCGID3 3
-/*!\brief Maximum number of logical chanels */
-#define MAX_NUM_LCID 11
-/*!\brief Maximum number od control elemenets */
-#define MAX_NUM_CE 5
-/*!\brief Maximum number of random access process */
-#define NB_RA_PROC_MAX 4
-/*!\brief size of buffer status report table */
-#define BSR_TABLE_SIZE 64
-/*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */
-#define PHR_MAPPING_OFFSET 23  // if ( x>= -23 ) val = floor (x + 23)
-/*!\brief maximum number of resource block groups */
-#define N_RBG_MAX 25 // for 20MHz channel BW
-/*!\brief minimum value for channel quality indicator */
-#define MIN_CQI_VALUE  0
-/*!\brief maximum value for channel quality indicator */
-#define MAX_CQI_VALUE  15
-/*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */
-#define MAX_SUPPORTED_BW  4
-/*!\brief CQI values range from 1 to 15 (4 bits) */
-#define CQI_VALUE_RANGE 16
-
-/*!\brief value for indicating BSR Timer is not running */
-#define MAC_UE_BSR_TIMER_NOT_RUNNING   (0xFFFF)
-
-#define LCID_EMPTY 0
-#define LCID_NOT_EMPTY 1
-
-/*!\brief minimum RLC PDU size to be transmitted = min RLC Status PDU or RLC UM PDU SN 5 bits */
-#define MIN_RLC_PDU_SIZE    (2)
-
-/*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */
-#define MIN_MAC_HDR_RLC_SIZE    (1 + MIN_RLC_PDU_SIZE)
-
-/*!\brief maximum number of slices / groups */
-#define MAX_NUM_SLICES 4
-
-/*
- * eNB part
- */
-
-
-/*
- * UE/ENB common part
- */
-/*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */
-typedef struct {
-  uint8_t RAPID:6;
-  uint8_t T:1;
-  uint8_t E:1;
-} __attribute__((__packed__))RA_HEADER_RAPID;
-
-/*!\brief  MAC header of Random Access Response for backoff indicator (BI)*/
-typedef struct {
-  uint8_t BI:4;
-  uint8_t R:2;
-  uint8_t T:1;
-  uint8_t E:1;
-} __attribute__((__packed__))RA_HEADER_BI;
-/*
-typedef struct {
-  uint64_t padding:16;
-  uint64_t t_crnti:16;
-  uint64_t hopping_flag:1;
-  uint64_t rb_alloc:10;
-  uint64_t mcs:4;
-  uint64_t TPC:3;
-  uint64_t UL_delay:1;
-  uint64_t cqi_req:1;
-  uint64_t Timing_Advance_Command:11;  // first/2nd octet LSB
-  uint64_t R:1;                        // octet MSB
-  } __attribute__((__packed__))RAR_PDU;
-
-typedef struct {
-  uint64_t padding:16;
-  uint64_t R:1;                        // octet MSB
-  uint64_t Timing_Advance_Command:11;  // first/2nd octet LSB
-  uint64_t cqi_req:1;
-  uint64_t UL_delay:1;
-  uint64_t TPC:3;
-  uint64_t mcs:4;
-  uint64_t rb_alloc:10;
-  uint64_t hopping_flag:1;
-  uint64_t t_crnti:16;
-  } __attribute__((__packed__))RAR_PDU;
-
-#define sizeof_RAR_PDU 6
-*/
-/*!\brief  MAC subheader short with 7bit Length field */
-typedef struct {
-  uint8_t LCID:5;  // octet 1 LSB
-  uint8_t E:1;
-  uint8_t R:2;     // octet 1 MSB
-  uint8_t L:7;     // octet 2 LSB
-  uint8_t F:1;     // octet 2 MSB
-} __attribute__((__packed__))SCH_SUBHEADER_SHORT;
-/*!\brief  MAC subheader long  with 15bit Length field */
-typedef struct {
-  uint8_t LCID:5;   // octet 1 LSB
-  uint8_t E:1;
-  uint8_t R:2;      // octet 1 MSB
-  uint8_t L_MSB:7;
-  uint8_t F:1;      // octet 2 MSB
-  uint8_t L_LSB:8;
-  uint8_t padding;
-} __attribute__((__packed__))SCH_SUBHEADER_LONG;
-/*!\brief MAC subheader short without length field */
-typedef struct {
-  uint8_t LCID:5;
-  uint8_t E:1;
-  uint8_t R:2;
-} __attribute__((__packed__))SCH_SUBHEADER_FIXED;
-
-/*!\brief  mac control element: short buffer status report for a specific logical channel group ID*/
-typedef struct {
-  uint8_t Buffer_size:6;  // octet 1 LSB
-  uint8_t LCGID:2;        // octet 1 MSB
-} __attribute__((__packed__))BSR_SHORT;
-
-typedef BSR_SHORT BSR_TRUNCATED;
-/*!\brief  mac control element: long buffer status report for all logical channel group ID*/
-typedef struct {
-  uint8_t Buffer_size3:6;
-  uint8_t Buffer_size2:6;
-  uint8_t Buffer_size1:6;
-  uint8_t Buffer_size0:6;
-} __attribute__((__packed__))BSR_LONG;
-
-#define BSR_LONG_SIZE  (sizeof(BSR_LONG))
-/*!\brief  mac control element: timing advance  */
-typedef struct {
-  uint8_t TA:6;
-  uint8_t R:2;
-} __attribute__((__packed__))TIMING_ADVANCE_CMD;
-/*!\brief  mac control element: power headroom report  */
-typedef struct {
-  uint8_t PH:6;
-  uint8_t R:2;
-} __attribute__((__packed__))POWER_HEADROOM_CMD;
-
-/*! \brief MIB payload */
-typedef struct {
-  uint8_t payload[3] ;
-} __attribute__((__packed__))MIB_PDU;
-/*! \brief CCCH payload */
-typedef struct {
-  uint8_t payload[CCCH_PAYLOAD_SIZE_MAX] ;
-} __attribute__((__packed__))CCCH_PDU;
-/*! \brief BCCH payload */
-typedef struct {
-  uint8_t payload[BCCH_PAYLOAD_SIZE_MAX] ;
-} __attribute__((__packed__))BCCH_PDU;
-/*! \brief RAR payload */
-typedef struct {
-  uint8_t payload[RAR_PAYLOAD_SIZE_MAX];
-} __attribute__ ((__packed__)) RAR_PDU;
-/*! \brief BCCH payload */
-typedef struct {
-  uint8_t payload[PCCH_PAYLOAD_SIZE_MAX] ;
-} __attribute__((__packed__))PCCH_PDU;
-
-/*! \brief MCCH payload */
-typedef struct {
-  uint8_t payload[MCCH_PAYLOAD_SIZE_MAX] ;
-} __attribute__((__packed__))MCCH_PDU;
-/*!< \brief MAC control element for activation and deactivation of component carriers */
-typedef struct {
-  uint8_t C7:1;/*!< \brief Component carrier 7 */
-  uint8_t C6:1;/*!< \brief Component carrier 6 */
-  uint8_t C5:1;/*!< \brief Component carrier 5 */
-  uint8_t C4:1;/*!< \brief Component carrier 4 */
-  uint8_t C3:1;/*!< \brief Component carrier 3 */
-  uint8_t C2:1;/*!< \brief Component carrier 2 */
-  uint8_t C1:1;/*!< \brief Component carrier 1 */
-  uint8_t R:1;/*!< \brief Reserved  */
-} __attribute__((__packed__))CC_ELEMENT;
-/*! \brief MAC control element: MCH Scheduling Information */
-typedef struct {
-  uint8_t stop_sf_MSB:3; // octet 1 LSB
-  uint8_t lcid:5;        // octet 2 MSB
-  uint8_t stop_sf_LSB:8;
-} __attribute__((__packed__))MSI_ELEMENT;
-/*! \brief Values of CCCH LCID for DLSCH */
-#define CCCH_LCHANID 0
-/*!\brief Values of BCCH logical channel (fake)*/
-#define BCCH 3  // SI
-/*!\brief Values of PCCH logical channel (fake)*/
-#define PCCH 4  // Paging
-/*!\brief Values of PCCH logical channel (fake) */
-#define MIBCH 5  // MIB
-/*!\brief Values of BCCH SIB1_BR logical channel (fake) */
-#define BCCH_SIB1_BR 6  // SIB1_BR
-/*!\brief Values of BCCH SIB_BR logical channel (fake) */
-#define BCCH_SI_BR 7  // SI-BR
-/*!\brief Value of CCCH / SRB0 logical channel */
-#define CCCH 0  // srb0
-/*!\brief DCCH / SRB1 logical channel */
-#define DCCH 1  // srb1
-/*!\brief DCCH1 / SRB2  logical channel */
-#define DCCH1 2 // srb2
-/*!\brief DTCH DRB1  logical channel */
-#define DTCH 3 // LCID
-/*!\brief MCCH logical channel */
-#define MCCH 11
-/*!\brief MTCH logical channel */
-#define MTCH 1
-// DLSCH LCHAN ID
-/*!\brief LCID of UE contention resolution identity for DLSCH*/
-#define UE_CONT_RES 28
-/*!\brief LCID of timing advance for DLSCH */
-#define TIMING_ADV_CMD 29
-/*!\brief LCID of discontinous reception mode for DLSCH */
-#define DRX_CMD 30
-/*!\brief LCID of padding LCID for DLSCH */
-#define SHORT_PADDING 31
-
-// MCH LCHAN IDs (table6.2.1-4 TS36.321)
-/*!\brief LCID of MCCH for DL */
-#define MCCH_LCHANID 0
-/*!\brief LCID of MCH scheduling info for DL */
-#define MCH_SCHDL_INFO 3
-/*!\brief LCID of Carrier component activation/deactivation */
-#define CC_ACT_DEACT 27
-
-// ULSCH LCHAN IDs
-/*!\brief LCID of extended power headroom for ULSCH */
-#define EXTENDED_POWER_HEADROOM 25
-/*!\brief LCID of power headroom for ULSCH */
-#define POWER_HEADROOM 26
-/*!\brief LCID of CRNTI for ULSCH */
-#define CRNTI 27
-/*!\brief LCID of truncated BSR for ULSCH */
-#define TRUNCATED_BSR 28
-/*!\brief LCID of short BSR for ULSCH */
-#define SHORT_BSR 29
-/*!\brief LCID of long BSR for ULSCH */
-#define LONG_BSR 30
-/*!\bitmaps for BSR Triggers */
-#define BSR_TRIGGER_NONE    (0)     /* No BSR Trigger */
-#define BSR_TRIGGER_REGULAR   (1)     /* For Regular and ReTxBSR Expiry Triggers */
-#define BSR_TRIGGER_PERIODIC  (2)     /* For BSR Periodic Timer Expiry Trigger */
-#define BSR_TRIGGER_PADDING   (4)     /* For Padding BSR Trigger */
-
-
-/*! \brief Downlink SCH PDU Structure */
-typedef struct {
-  uint8_t payload[8][SCH_PAYLOAD_SIZE_MAX];
-  uint16_t Pdu_size[8];
-} __attribute__ ((__packed__)) DLSCH_PDU;
-
-
-/*! \brief MCH PDU Structure */
-typedef struct {
-  int8_t payload[SCH_PAYLOAD_SIZE_MAX];
-  uint16_t Pdu_size;
-  uint8_t mcs;
-  uint8_t sync_area;
-  uint8_t msi_active;
-  uint8_t mcch_active;
-  uint8_t mtch_active;
-} __attribute__ ((__packed__)) MCH_PDU;
-
-/*! \brief Uplink SCH PDU Structure */
-typedef struct {
-  int8_t payload[SCH_PAYLOAD_SIZE_MAX];         /*!< \brief SACH payload */
-  uint16_t Pdu_size;
-} __attribute__ ((__packed__)) ULSCH_PDU;
-
-#include "PHY/impl_defs_top.h"
-
-/*!\brief  UE ULSCH scheduling states*/
-typedef enum {
-  S_UL_NONE =0,
-  S_UL_WAITING,
-  S_UL_SCHEDULED,
-  S_UL_BUFFERED,
-  S_UL_NUM_STATUS
-} UE_ULSCH_STATUS;
-
-/*!\brief  UE DLSCH scheduling states*/
-typedef enum {
-  S_DL_NONE =0,
-  S_DL_WAITING,
-  S_DL_SCHEDULED,
-  S_DL_BUFFERED,
-  S_DL_NUM_STATUS
-} UE_DLSCH_STATUS;
-
-/*!\brief  scheduling policy for the contention-based access */
-typedef enum {
-  CBA_ES=0, /// equal share of RB among groups w
-  CBA_ES_S,  /// equal share of RB among groups with small allocation
-  CBA_PF, /// proportional fair (kind of)
-  CBA_PF_S,  /// proportional fair (kind of) with small RB allocation
-  CBA_RS /// random allocation
-} CBA_POLICY;
-
-
-/*! \brief temporary struct for ULSCH sched */
-typedef struct {
-  rnti_t rnti;
-  uint16_t subframe;
-  uint16_t serving_num;
-  UE_ULSCH_STATUS status;
-} eNB_ULSCH_INFO;
-/*! \brief temp struct for DLSCH sched */
-typedef struct {
-  rnti_t rnti;
-  uint16_t weight;
-  uint16_t subframe;
-  uint16_t serving_num;
-  UE_DLSCH_STATUS status;
-} eNB_DLSCH_INFO;
-/*! \brief eNB overall statistics */
-typedef struct {
-  /// num BCCH PDU per CC
-  uint32_t total_num_bcch_pdu;
-  /// BCCH buffer size
-  uint32_t bcch_buffer;
-  /// total BCCH buffer size
-  uint32_t total_bcch_buffer;
-  /// BCCH MCS
-  uint32_t bcch_mcs;
-
-  /// num CCCH PDU per CC
-  uint32_t total_num_ccch_pdu;
-  /// BCCH buffer size
-  uint32_t ccch_buffer;
-  /// total BCCH buffer size
-  uint32_t total_ccch_buffer;
-  /// BCCH MCS
-  uint32_t ccch_mcs;
-
-  /// num active users
-  uint16_t num_dlactive_UEs;
-  ///  available number of PRBs for a give SF
-  uint16_t available_prbs;
-  /// total number of PRB available for the user plane
-  uint32_t total_available_prbs;
-  /// aggregation
-  /// total avilable nccc : num control channel element
-  uint16_t available_ncces;
-  // only for a new transmission, should be extended for retransmission
-  // current dlsch  bit rate for all transport channels
-  uint32_t dlsch_bitrate;
-  //
-  uint32_t dlsch_bytes_tx;
-  //
-  uint32_t dlsch_pdus_tx;
-  //
-  uint32_t total_dlsch_bitrate;
-  //
-  uint32_t total_dlsch_bytes_tx;
-  //
-  uint32_t total_dlsch_pdus_tx;
-
-  // here for RX
-  //
-  uint32_t ulsch_bitrate;
-  //
-  uint32_t ulsch_bytes_rx;
-  //
-  uint64_t ulsch_pdus_rx;
-
-  uint32_t total_ulsch_bitrate;
-  //
-  uint32_t total_ulsch_bytes_rx;
-  //
-  uint32_t total_ulsch_pdus_rx;
-
-
-  /// MAC agent-related stats
-  /// total number of scheduling decisions
-  int sched_decisions;
-  /// missed deadlines
-  int missed_deadlines;
-
-} eNB_STATS;
-/*! \brief eNB statistics for the connected UEs*/
-typedef struct {
-
-  /// CRNTI of UE
-  rnti_t crnti; ///user id (rnti) of connected UEs
-  // rrc status
-  uint8_t rrc_status;
-  /// harq pid
-  uint8_t harq_pid;
-  /// harq rounf
-  uint8_t harq_round;
-  /// total available number of PRBs for a new transmission
-  uint16_t rbs_used;
-  /// total available number of PRBs for a retransmission
-  uint16_t rbs_used_retx;
-  /// total nccc used for a new transmission: num control channel element
-  uint16_t ncce_used;
-  /// total avilable nccc for a retransmission: num control channel element
-  uint16_t ncce_used_retx;
-
-  // mcs1 before the rate adaptaion
-  uint8_t dlsch_mcs1;
-  /// Target mcs2 after rate-adaptation
-  uint8_t dlsch_mcs2;
-  //  current TBS with mcs2
-  uint32_t TBS;
-  //  total TBS with mcs2
-  //  uint32_t total_TBS;
-  //  total rb used for a new transmission
-  uint32_t total_rbs_used;
-  //  total rb used for retransmission
-  uint32_t total_rbs_used_retx;
-
-  /// TX
-  /// Num pkt
-  uint32_t num_pdu_tx[NB_RB_MAX];
-  /// num bytes
-  uint32_t num_bytes_tx[NB_RB_MAX];
-  /// num retransmission / harq
-  uint32_t num_retransmission;
-  /// instantaneous tx throughput for each TTI
-  //  uint32_t tti_throughput[NB_RB_MAX];
-
-  /// overall
-  //
-  uint32_t  dlsch_bitrate;
-  //total
-  uint32_t  total_dlsch_bitrate;
-  /// headers+ CE +  padding bytes for a MAC PDU
-  uint64_t overhead_bytes;
-  /// headers+ CE +  padding bytes for a MAC PDU
-  uint64_t total_overhead_bytes;
-  /// headers+ CE +  padding bytes for a MAC PDU
-  uint64_t avg_overhead_bytes;
-  // MAC multiplexed payload
-  uint64_t total_sdu_bytes;
-  // total MAC pdu bytes
-  uint64_t total_pdu_bytes;
-
-  // total num pdu
-  uint32_t total_num_pdus;
-  //
-  //  uint32_t avg_pdu_size;
-
-  /// RX
-
-  /// PUCCH1a/b power (dBm)
-  int32_t Po_PUCCH_dBm;
-  /// Indicator that Po_PUCCH has been updated by PHY
-  int32_t Po_PUCCH_update;
-  /// Uplink measured RSSI
-  int32_t UL_rssi;
-  /// preassigned mcs after rate adaptation
-  uint8_t ulsch_mcs1;
-  /// adjusted mcs
-  uint8_t ulsch_mcs2;
-
-  /// estimated average pdu inter-departure time
-  uint32_t avg_pdu_idt;
-  /// estimated average pdu size
-  uint32_t avg_pdu_ps;
-  ///
-  uint32_t aggregated_pdu_size;
-  uint32_t aggregated_pdu_arrival;
-
-  ///  uplink transport block size
-  uint32_t ulsch_TBS;
-
-  ///  total rb used for a new uplink transmission
-  uint32_t num_retransmission_rx;
-  ///  total rb used for a new uplink transmission
-  uint32_t rbs_used_rx;
-  ///  total rb used for a new uplink retransmission
-  uint32_t rbs_used_retx_rx;
-  ///  total rb used for a new uplink transmission
-  uint32_t total_rbs_used_rx;
-  /// snr
-  int32_t      snr;
-  /// target snr
-  int32_t    target_snr;
-
-  /// num rx pdu
-  uint32_t num_pdu_rx[NB_RB_MAX];
-  /// num bytes rx
-  uint32_t num_bytes_rx[NB_RB_MAX];
-  /// instantaneous rx throughput for each TTI
-  //  uint32_t tti_goodput[NB_RB_MAX];
-  /// errors
-  uint32_t num_errors_rx;
-
-  uint64_t overhead_bytes_rx;
-  /// headers+ CE +  padding bytes for a MAC PDU
-  uint64_t total_overhead_bytes_rx;
-  /// headers+ CE +  padding bytes for a MAC PDU
-  uint64_t avg_overhead_bytes_rx;
-  //
-  uint32_t  ulsch_bitrate;
-  //total
-  uint32_t  total_ulsch_bitrate;
-  /// overall
-  ///  MAC pdu bytes
-  uint64_t pdu_bytes_rx;
-  /// total MAC pdu bytes
-  uint64_t total_pdu_bytes_rx;
-  /// total num pdu
-  uint32_t total_num_pdus_rx;
-  /// num of error pdus
-  uint32_t total_num_errors_rx;
-
-} eNB_UE_STATS;
-/*! \brief eNB template for UE context information  */
-typedef struct {
-  /// C-RNTI of UE
-  rnti_t rnti;
-  /// NDI from last scheduling
-  uint8_t oldNDI[8];
-  /// mcs1 from last scheduling
-  uint8_t oldmcs1[8];
-  /// mcs2 from last scheduling
-  uint8_t oldmcs2[8];
-  /// NDI from last UL scheduling
-  uint8_t oldNDI_UL[8];
-  /// mcs from last UL scheduling
-  uint8_t mcs_UL[8];
-  /// TBS from last UL scheduling
-  uint8_t TBS_UL[8];
-  /// CQI_req from last scheduling
-  uint8_t oldCQI_UL[8];
-  /// TPC from last scheduling
-  uint8_t oldTPC_UL[8];
-  /// Flag to indicate UL has been scheduled at least once
-  boolean_t ul_active;
-  /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received)
-  boolean_t configured;
-
-  /// MCS from last scheduling
-  uint8_t mcs[8];
-
-  /// TPC from last scheduling
-  uint8_t oldTPC[8];
-
-  // PHY interface info
-
-  /// Number of Allocated RBs for DL after scheduling (prior to frequency allocation)
-  uint16_t nb_rb[8]; // num_max_harq
-
-  /// Number of Allocated RBs for UL after scheduling
-  uint16_t nb_rb_ul[8]; // num_max_harq
-
-  /// Number of Allocated RBs for UL after scheduling
-  uint16_t first_rb_ul[8]; // num_max_harq
-
-  /// Is CQI requested for UL after scheduling 1st transmission
-  uint8_t cqi_req[8];         // num_max_harq
-
-  /// Cyclic shift for DMRS after scheduling
-  uint16_t cshift[8]; // num_max_harq
-
-  /// Number of Allocated RBs by the ulsch preprocessor
-  uint8_t pre_allocated_nb_rb_ul;
-
-  /// index of Allocated RBs by the ulsch preprocessor
-  int8_t pre_allocated_rb_table_index_ul;
-
-  /// total allocated RBs
-  int8_t total_allocated_rbs;
-
-  /// pre-assigned MCS by the ulsch preprocessor
-  uint8_t pre_assigned_mcs_ul;
-
-  /// assigned MCS by the ulsch scheduler
-  uint8_t assigned_mcs_ul;
-
-  /// DL DAI
-  uint8_t DAI;
-
-  /// UL DAI
-  uint8_t DAI_ul[10];
-
-  /// UL Scheduling Request Received
-  uint8_t ul_SR;
-
-  ///Resource Block indication for each sub-band in MU-MIMO
-  uint8_t rballoc_subband[8][50];
-
-  // Logical channel info for link with RLC
-
-  /// Last received UE BSR info for each logical channel group id
-  uint8_t bsr_info[MAX_NUM_LCGID];
-
-  /// LCGID mapping
-  long lcgidmap[11];
-
-  /// phr information
-  int8_t phr_info;
-
-  /// phr information
-  int8_t phr_info_configured;
-
-  ///dl buffer info
-  uint32_t dl_buffer_info[MAX_NUM_LCID];
-  /// total downlink buffer info
-  uint32_t dl_buffer_total;
-  /// total downlink pdus
-  uint32_t dl_pdus_total;
-  /// downlink pdus for each LCID
-  uint32_t dl_pdus_in_buffer[MAX_NUM_LCID];
-  /// creation time of the downlink buffer head for each LCID
-  uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID];
-  /// maximum creation time of the downlink buffer head across all LCID
-  uint32_t  dl_buffer_head_sdu_creation_time_max;
-  /// a flag indicating that the downlink head SDU is segmented
-  uint8_t    dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID];
-  /// size of remaining size to send for the downlink head SDU
-  uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID];
-
-  /// total uplink buffer size
-  uint32_t ul_total_buffer;
-  /// uplink buffer creation time for each LCID
-  uint32_t ul_buffer_creation_time[MAX_NUM_LCGID];
-  /// maximum uplink buffer creation time across all the LCIDs
-  uint32_t ul_buffer_creation_time_max;
-  /// uplink buffer size per LCID
-  uint32_t ul_buffer_info[MAX_NUM_LCGID];
-
-  /// UE tx power
-  int32_t ue_tx_power;
-
-  /// stores the frame where the last TPC was transmitted
-  uint32_t pusch_tpc_tx_frame;
-  uint32_t pusch_tpc_tx_subframe;
-  uint32_t pucch_tpc_tx_frame;
-  uint32_t pucch_tpc_tx_subframe;
-
-#ifdef LOCALIZATION
-  eNB_UE_estimated_distances distance;
-#endif
-
-
-  uint8_t rach_resource_type;
-
-  uint16_t mpdcch_repetition_cnt;
-  struct PhysicalConfigDedicated  *physicalConfigDedicated;
-  frame_t Msg2_frame;
-  sub_frame_t Msg2_subframe;
-
-} UE_TEMPLATE;
-
-/*! \brief scheduling control information set through an API (not used)*/
-typedef struct {
-  ///UL transmission bandwidth in RBs
-  uint8_t ul_bandwidth[MAX_NUM_LCID];
-  ///DL transmission bandwidth in RBs
-  uint8_t dl_bandwidth[MAX_NUM_LCID];
-
-  //To do GBR bearer
-  uint8_t min_ul_bandwidth[MAX_NUM_LCID];
-
-  uint8_t min_dl_bandwidth[MAX_NUM_LCID];
-
-  ///aggregated bit rate of non-gbr bearer per UE
-  uint64_t  ue_AggregatedMaximumBitrateDL;
-  ///aggregated bit rate of non-gbr bearer per UE
-  uint64_t  ue_AggregatedMaximumBitrateUL;
-  ///CQI scheduling interval in subframes.
-  uint16_t cqiSchedInterval;
-  ///Contention resolution timer used during random access
-  uint8_t mac_ContentionResolutionTimer;
-
-  uint16_t max_allowed_rbs[MAX_NUM_LCID];
-
-  uint8_t max_mcs[MAX_NUM_LCID];
-
-  uint16_t priority[MAX_NUM_LCID];
-
-  // resource scheduling information
-
-  /// Current DL harq round per harq_pid on each CC
-  uint8_t       round[MAX_NUM_CCs][10];
-  /// Current Active TBs per harq_pid on each CC
-  uint8_t       tbcnt[MAX_NUM_CCs][10];
-  /// Current UL harq round per harq_pid on each CC
-  uint8_t       round_UL[MAX_NUM_CCs][8];
-  uint8_t       dl_pow_off[MAX_NUM_CCs];
-  uint16_t      pre_nb_available_rbs[MAX_NUM_CCs];
-  unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX];
-  uint16_t      ta_timer;
-  int16_t       ta_update;
-  uint16_t      ul_consecutive_errors;
-  int32_t       context_active_timer;
-  int32_t       cqi_req_timer;
-  int32_t       ul_inactivity_timer;
-  int32_t       ul_failure_timer;
-  int32_t       ul_scheduled;
-  int32_t       ra_pdcch_order_sent;
-  int32_t       ul_out_of_sync;
-  int32_t       phr_received;
-  uint8_t       periodic_ri_received[NFAPI_CC_MAX];
-  uint8_t       aperiodic_ri_received[NFAPI_CC_MAX];
-  uint32_t      pucch_tpc_accumulated[NFAPI_CC_MAX];
-  uint8_t       pucch1_cqi_update[NFAPI_CC_MAX];
-  uint8_t       pucch1_snr[NFAPI_CC_MAX];
-  uint8_t       pucch2_cqi_update[NFAPI_CC_MAX];
-  uint8_t       pucch2_snr[NFAPI_CC_MAX];
-  uint8_t       pucch3_cqi_update[NFAPI_CC_MAX];
-  uint8_t       pucch3_snr[NFAPI_CC_MAX];
-  uint8_t       pusch_snr[NFAPI_CC_MAX];
-  uint16_t      feedback_cnt[NFAPI_CC_MAX];
-  uint16_t      timing_advance;
-  uint16_t      timing_advance_r9;
-  uint8_t       periodic_wideband_cqi[NFAPI_CC_MAX];
-  uint8_t       periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX];
-  uint8_t       periodic_wideband_pmi[NFAPI_CC_MAX];
-  uint8_t       periodic_subband_cqi[NFAPI_CC_MAX][16];
-  uint8_t       periodic_subband_spatial_diffcqi[NFAPI_CC_MAX][16];
-  uint8_t       aperiodic_subband_cqi0[NFAPI_CC_MAX][25];
-  uint8_t       aperiodic_subband_pmi[NFAPI_CC_MAX][25];
-  uint8_t       aperiodic_subband_diffcqi0[NFAPI_CC_MAX][25];
-  uint8_t       aperiodic_subband_cqi1[NFAPI_CC_MAX][25];
-  uint8_t       aperiodic_subband_diffcqi1[NFAPI_CC_MAX][25];
-  uint8_t       aperiodic_wideband_cqi0[NFAPI_CC_MAX];
-  uint8_t       aperiodic_wideband_pmi[NFAPI_CC_MAX];
-  uint8_t       aperiodic_wideband_cqi1[NFAPI_CC_MAX];
-  uint8_t       aperiodic_wideband_pmi1[NFAPI_CC_MAX];
-  uint8_t       dl_cqi[NFAPI_CC_MAX];
-} UE_sched_ctrl;
-/*! \brief eNB template for the Random access information */
-typedef struct {
-  /// Flag to indicate this process is active
-  boolean_t RA_active;
-  /// Size of DCI for RA-Response (bytes)
-  uint8_t RA_dci_size_bytes1;
-  /// Size of DCI for RA-Response (bits)
-  uint8_t RA_dci_size_bits1;
-  /// Actual DCI to transmit for RA-Response
-  uint8_t RA_alloc_pdu1[(MAX_DCI_SIZE_BITS>>3)+1];
-  /// DCI format for RA-Response (should be 1A)
-  uint8_t RA_dci_fmt1;
-  /// Size of DCI for Msg4/ContRes (bytes)
-  uint8_t RA_dci_size_bytes2;
-  /// Size of DCI for Msg4/ContRes (bits)
-  uint8_t RA_dci_size_bits2;
-  /// Actual DCI to transmit for Msg4/ContRes
-  uint8_t RA_alloc_pdu2[(MAX_DCI_SIZE_BITS>>3)+1];
-  /// DCI format for Msg4/ContRes (should be 1A)
-  uint8_t RA_dci_fmt2;
-  /// Flag to indicate the eNB should generate RAR.  This is triggered by detection of PRACH
-  uint8_t generate_rar;
-  /// Subframe where preamble was received
-  uint8_t preamble_subframe;
-  /// Subframe where Msg2 is to be sent
-  uint8_t Msg2_subframe;
-  /// Frame where Msg2 is to be sent
-  frame_t Msg2_frame;
-  /// Subframe where Msg3 is to be sent
-  sub_frame_t Msg3_subframe;
-  /// Frame where Msg3 is to be sent
-  frame_t Msg3_frame;
-  /// Subframe where Msg4 is to be sent
-  sub_frame_t Msg4_subframe;
-  /// Frame where Msg4 is to be sent
-  frame_t Msg4_frame;
-  /// Flag to indicate the eNB should generate Msg4 upon reception of SDU from RRC.  This is triggered by first ULSCH reception at eNB for new user.
-  uint8_t generate_Msg4;
-  /// Flag to indicate that eNB is waiting for ACK that UE has received Msg3.
-  uint8_t wait_ack_Msg4;
-  /// harq_pid used for Msg4 transmission
-  uint8_t harq_pid;
-  /// UE RNTI allocated during RAR
-  rnti_t rnti;
-  /// RA RNTI allocated from received PRACH
-  uint16_t RA_rnti;
-  /// Received preamble_index
-  uint8_t preamble_index;
-  /// Received UE Contention Resolution Identifier
-  uint8_t cont_res_id[6];
-  /// Timing offset indicated by PHY
-  int16_t timing_offset;
-  /// Timeout for RRC connection
-  int16_t RRC_timer;
-  /// Msg3 first RB
-  uint8_t msg3_first_rb;
-  /// Msg3 number of RB
-  uint8_t msg3_nb_rb;
-  /// Msg3 MCS
-  uint8_t msg3_mcs;
-  /// Msg3 TPC command
-  uint8_t msg3_TPC;
-  /// Msg3 ULdelay command
-  uint8_t msg3_ULdelay;
-  /// Msg3 cqireq command
-  uint8_t msg3_cqireq;
-  /// Round of Msg3 HARQ
-  uint8_t msg3_round;
-  /// TBS used for Msg4
-  int msg4_TBsize;
-  /// MCS used for Msg4
-  int msg4_mcs;
-  /// size off piggybacked RRC SDU
-  uint8_t msg4_rrc_sdu_length;
-  uint32_t msg4_delay;
-  uint8_t rach_resource_type;
-  uint8_t msg2_mpdcch_repetition_cnt;
-  uint8_t msg2_mpdcch_done;
-  uint8_t msg4_mpdcch_repetition_cnt;
-  uint8_t msg4_mpdcch_done;
-  uint8_t msg2_narrowband;
-  uint32_t msg34_narrowband;
-} RA_TEMPLATE;
-
-
-/*! \brief subband bitmap confguration (for ALU icic algo purpose), in test phase */
-typedef struct {
-  uint8_t sbmap[NUMBER_OF_SUBBANDS_MAX]; //13 = number of SB MAX for 100 PRB
-  uint8_t periodicity;
-  uint8_t first_subframe;
-  uint8_t sb_size;
-  uint8_t nb_active_sb;
-} SBMAP_CONF;
-/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
-typedef struct {
-  /// Dedicated information for UEs
-  struct PhysicalConfigDedicated  *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// DLSCH pdu
-  DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX];
-  /// DCI template and MAC connection parameters for UEs
-  UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// DCI template and MAC connection for RA processes
-  int pCC_id[NUMBER_OF_UE_MAX];
-  /// sorted downlink component carrier for the scheduler
-  int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// number of downlink active component carrier
-  int numactiveCCs[NUMBER_OF_UE_MAX];
-  /// sorted uplink component carrier for the scheduler
-  int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// number of uplink active component carrier
-  int numactiveULCCs[NUMBER_OF_UE_MAX];
-  /// number of downlink active component carrier
-  uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX];
-  /// eNB to UE statistics
-  eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-  /// scheduling control info
-  UE_sched_ctrl UE_sched_ctrl[NUMBER_OF_UE_MAX];
-  int next[NUMBER_OF_UE_MAX];
-  int head;
-  int next_ul[NUMBER_OF_UE_MAX];
-  int head_ul;
-  int avail;
-  int num_UEs;
-  boolean_t active[NUMBER_OF_UE_MAX];
-} UE_list_t;
-
-/*! \brief eNB common channels */
-typedef struct {
-  int                              physCellId;
-  int                              p_eNB;
-  int                              Ncp;
-  int                              eutra_band;
-  uint32_t                         dl_CarrierFreq;
-  BCCH_BCH_Message_t               *mib;
-  RadioResourceConfigCommonSIB_t   *radioResourceConfigCommon;
-  RadioResourceConfigCommonSIB_t   *radioResourceConfigCommon_BR;
-  TDD_Config_t                     *tdd_Config;
-  SchedulingInfoList_t             *schedulingInfoList;
-  ARFCN_ValueEUTRA_t               ul_CarrierFreq;
-  long                             ul_Bandwidth;
-  /// Outgoing MIB PDU for PHY
-  MIB_PDU MIB_pdu;
-  /// Outgoing BCCH pdu for PHY
-  BCCH_PDU BCCH_pdu;
-  /// Outgoing BCCH DCI allocation
-  uint32_t BCCH_alloc_pdu;
-  /// Outgoing CCCH pdu for PHY
-  CCCH_PDU CCCH_pdu;
-  /// Outgoing RAR pdu for PHY
-  RAR_PDU RAR_pdu;
-  /// Template for RA computations
-  RA_TEMPLATE RA_template[NB_RA_PROC_MAX];
-  /// VRB map for common channels
-  uint8_t vrb_map[100];
-  /// VRB map for common channels and retransmissions by PHICH
-  uint8_t vrb_map_UL[100];
-  /// MBSFN SubframeConfig
-  struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8];
-  /// number of subframe allocation pattern available for MBSFN sync area
-  uint8_t num_sf_allocation_pattern;
-  /// MBMS Flag
-  uint8_t MBMS_flag;
-  /// Outgoing MCCH pdu for PHY
-  MCCH_PDU MCCH_pdu;
-  /// MCCH active flag
-  uint8_t msi_active;
-  /// MCCH active flag
-  uint8_t mcch_active;
-  /// MTCH active flag
-  uint8_t mtch_active;
-  /// number of active MBSFN area
-  uint8_t num_active_mbsfn_area;
-  /// MBSFN Area Info
-  struct  MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA];
-  /// PMCH Config
-  struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN];
-  /// MBMS session info list
-  struct MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN];
-  /// Outgoing MCH pdu for PHY
-  MCH_PDU MCH_pdu;
-  /// Rel13 parameters from SIB1
-  SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext;
-  /// Counter for SIB1-BR scheduling
-  int SIB1_BR_cnt;
-  /// Outgoing BCCH-BR pdu for PHY
-  BCCH_PDU BCCH_BR_pdu[20];
-} COMMON_channels_t;
-/*! \brief top level eNB MAC structure */
-typedef struct eNB_MAC_INST_s {
-  /// Ethernet parameters for northbound midhaul interface
-  eth_params_t         eth_params_n;
-  /// Ethernet parameters for fronthaul interface
-  eth_params_t         eth_params_s;
-  ///
-  module_id_t Mod_id;
-  /// frame counter
-  frame_t frame;
-  /// subframe counter
-  sub_frame_t subframe;
-  /// Pointer to IF module instance for PHY
-  IF_Module_t *if_inst;
-  /// Common cell resources
-  COMMON_channels_t common_channels[MAX_NUM_CCs];
-  /// current PDU index (BCH,MCH,DLSCH)
-  uint16_t pdu_index[MAX_NUM_CCs];
-
-  /// NFAPI Config Request Structure
-  nfapi_config_request_t config[MAX_NUM_CCs];
-  /// Preallocated DL pdu list
-  nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_CCs][MAX_NUM_DL_PDU];
-  /// NFAPI DL Config Request Structure
-  nfapi_dl_config_request_t DL_req[MAX_NUM_CCs];
-  /// Preallocated UL pdu list
-  nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU];
-  /// Preallocated UL pdu list for ULSCH (n+k delay)
-  nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU];
-  /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place
-  nfapi_ul_config_request_t UL_req[MAX_NUM_CCs];
-  /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests
-  nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10];
-  /// Preallocated HI_DCI0 pdu list
-  nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU];
-  /// NFAPI HI/DCI0 Config Request Structure
-  nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs];
-  /// Prealocated TX pdu list
-  nfapi_tx_request_pdu_t tx_request_pdu[MAX_NUM_CCs][MAX_NUM_TX_REQUEST_PDU];
-  /// NFAPI DL PDU structure
-  nfapi_tx_request_t TX_req[MAX_NUM_CCs];
-  /// UL handle
-  uint32_t ul_handle;
-  UE_list_t UE_list;
-
-  ///subband bitmap configuration
-  SBMAP_CONF sbmap_conf;
-  /// CCE table used to build DCI scheduling information
-  int CCE_table[MAX_NUM_CCs][800];
-  ///  active flag for Other lcid
-  uint8_t lcid_active[NB_RB_MAX];
-  /// eNB stats
-  eNB_STATS eNB_stats[MAX_NUM_CCs];
-  // MAC function execution peformance profiler
-  /// processing time of eNB scheduler
-  time_stats_t eNB_scheduler;
-  /// processing time of eNB scheduler for SI
-  time_stats_t schedule_si;
-  /// processing time of eNB scheduler for Random access
-  time_stats_t schedule_ra;
-  /// processing time of eNB ULSCH scheduler
-  time_stats_t schedule_ulsch;
-  /// processing time of eNB DCI generation
-  time_stats_t fill_DLSCH_dci;
-  /// processing time of eNB MAC preprocessor
-  time_stats_t schedule_dlsch_preprocessor;
-  /// processing time of eNB DLSCH scheduler
-  time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor
-  /// processing time of eNB MCH scheduler
-  time_stats_t schedule_mch;
-  /// processing time of eNB ULSCH reception
-  time_stats_t rx_ulsch_sdu; // include rlc_data_ind
-} eNB_MAC_INST;
-
-/*
- * UE part
- */
-
-typedef enum {
-  TYPE0,
-  TYPE1,
-  TYPE1A,
-  TYPE2,
-  TYPE2A,
-  TYPEUESPEC
-} MPDCCH_TYPES_t;
-
-/*!\brief UE layer 2 status */
-typedef enum {
-  CONNECTION_OK=0,
-  CONNECTION_LOST,
-  PHY_RESYNCH,
-  PHY_HO_PRACH
-} UE_L2_STATE_t;
-
-/*!\brief UE scheduling info */
-typedef struct {
-  /// buffer status for each lcgid
-  uint8_t  BSR[MAX_NUM_LCGID]; // should be more for mesh topology
-  /// keep the number of bytes in rlc buffer for each lcgid
-  int32_t  BSR_bytes[MAX_NUM_LCGID];
-  /// after multiplexing buffer remain for each lcid
-  int32_t  LCID_buffer_remain[MAX_NUM_LCID];
-  /// sum of all lcid buffer size
-  uint16_t  All_lcid_buffer_size_lastTTI;
-  /// buffer status for each lcid
-  uint8_t  LCID_status[MAX_NUM_LCID];
-  /// SR pending as defined in 36.321
-  uint8_t  SR_pending;
-  /// SR_COUNTER as defined in 36.321
-  uint16_t SR_COUNTER;
-  /// logical channel group ide for each LCID
-  uint8_t  LCGID[MAX_NUM_LCID];
-  /// retxBSR-Timer, default value is sf2560
-  uint16_t retxBSR_Timer;
-  /// retxBSR_SF, number of subframe before triggering a regular BSR
-  uint16_t retxBSR_SF;
-  /// periodicBSR-Timer, default to infinity
-  uint16_t periodicBSR_Timer;
-  /// periodicBSR_SF, number of subframe before triggering a periodic BSR
-  uint16_t periodicBSR_SF;
-  /// default value is 0: not configured
-  uint16_t sr_ProhibitTimer;
-  /// sr ProhibitTime running
-  uint8_t sr_ProhibitTimer_Running;
-  ///  default value to n5
-  uint16_t maxHARQ_Tx;
-  /// default value is false
-  uint16_t ttiBundling;
-  /// default value is release
-  struct DRX_Config *drx_config;
-  /// default value is release
-  struct MAC_MainConfig__phr_Config *phr_config;
-  ///timer before triggering a periodic PHR
-  uint16_t periodicPHR_Timer;
-  ///timer before triggering a prohibit PHR
-  uint16_t prohibitPHR_Timer;
-  ///DL Pathloss change value
-  uint16_t PathlossChange;
-  ///number of subframe before triggering a periodic PHR
-  int16_t periodicPHR_SF;
-  ///number of subframe before triggering a prohibit PHR
-  int16_t prohibitPHR_SF;
-  ///DL Pathloss Change in db
-  uint16_t PathlossChange_db;
-
-  /// default value is false
-  uint16_t extendedBSR_Sizes_r10;
-  /// default value is false
-  uint16_t extendedPHR_r10;
-
-  //Bj bucket usage per  lcid
-  int16_t Bj[MAX_NUM_LCID];
-  // Bucket size per lcid
-  int16_t bucket_size[MAX_NUM_LCID];
-} UE_SCHEDULING_INFO;
-/*!\brief Top level UE MAC structure */
-typedef struct {
-  uint16_t Node_id;
-  /// RX frame counter
-  frame_t     rxFrame;
-  /// RX subframe counter
-  sub_frame_t rxSubframe;
-  /// TX frame counter
-  frame_t     txFrame;
-  /// TX subframe counter
-  sub_frame_t txSubframe;
-  /// C-RNTI of UE
-  uint16_t crnti;
-  /// C-RNTI of UE before HO
-  rnti_t crnti_before_ho; ///user id (rnti) of connected UEs
-  /// uplink active flag
-  uint8_t ul_active;
-  /// pointer to RRC PHY configuration
-  RadioResourceConfigCommonSIB_t *radioResourceConfigCommon;
-  /// pointer to RACH_ConfigDedicated (NULL when not active, i.e. upon HO completion or T304 expiry)
-  struct RACH_ConfigDedicated *rach_ConfigDedicated;
-  /// pointer to RRC PHY configuration
-  struct PhysicalConfigDedicated *physicalConfigDedicated;
-  /// pointer to RRC PHY configuration SCEll
-  struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10;
-  /// pointer to TDD Configuration (NULL for FDD)
-  TDD_Config_t *tdd_Config;
-  /// Number of adjacent cells to measure
-  uint8_t  n_adj_cells;
-  /// Array of adjacent physical cell ids
-  uint32_t adj_cell_id[6];
-  /// Pointer to RRC MAC configuration
-  MAC_MainConfig_t *macConfig;
-  /// Pointer to RRC Measurement gap configuration
-  MeasGapConfig_t  *measGapConfig;
-  /// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive.
-  LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID];
-  /// Scheduling Information
-  UE_SCHEDULING_INFO scheduling_info;
-  /// Outgoing CCCH pdu for PHY
-  CCCH_PDU CCCH_pdu;
-  /// Outgoing RAR pdu for PHY
-  RAR_PDU RAR_pdu;
-  /// Incoming DLSCH pdu for PHY
-  DLSCH_PDU DLSCH_pdu[NUMBER_OF_UE_MAX][2];
-  /// number of attempt for rach
-  uint8_t RA_attempt_number;
-  /// Random-access procedure flag
-  uint8_t RA_active;
-  /// Random-access window counter
-  int8_t RA_window_cnt;
-  /// Random-access Msg3 size in bytes
-  uint8_t RA_Msg3_size;
-  /// Random-access prachMaskIndex
-  uint8_t RA_prachMaskIndex;
-  /// Flag indicating Preamble set (A,B) used for first Msg3 transmission
-  uint8_t RA_usedGroupA;
-  /// Random-access Resources
-  PRACH_RESOURCES_t RA_prach_resources;
-  /// Random-access PREAMBLE_TRANSMISSION_COUNTER
-  uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
-  /// Random-access backoff counter
-  int16_t RA_backoff_cnt;
-  /// Random-access variable for window calculation (frame of last change in window counter)
-  uint32_t RA_tx_frame;
-  /// Random-access variable for window calculation (subframe of last change in window counter)
-  uint8_t RA_tx_subframe;
-  /// Random-access Group B maximum path-loss
-  /// Random-access variable for backoff (frame of last change in backoff counter)
-  uint32_t RA_backoff_frame;
-  /// Random-access variable for backoff (subframe of last change in backoff counter)
-  uint8_t RA_backoff_subframe;
-  /// Random-access Group B maximum path-loss
-  uint16_t RA_maxPL;
-  /// Random-access Contention Resolution Timer active flag
-  uint8_t RA_contention_resolution_timer_active;
-  /// Random-access Contention Resolution Timer count value
-  uint8_t RA_contention_resolution_cnt;
-  /// power headroom reporitng reconfigured
-  uint8_t PHR_reconfigured;
-  /// power headroom state as configured by the higher layers
-  uint8_t PHR_state;
-  /// power backoff due to power management (as allowed by P-MPRc) for this cell
-  uint8_t PHR_reporting_active;
-  /// power backoff due to power management (as allowed by P-MPRc) for this cell
-  uint8_t power_backoff_db[NUMBER_OF_eNB_MAX];
-  /// BSR report falg management
-  uint8_t BSR_reporting_active;
-  /// retxBSR-Timer expires flag
-  uint8_t retxBSRTimer_expires_flag;
-  /// periodBSR-Timer expires flag
-  uint8_t periodBSRTimer_expires_flag;
-
-  /// MBSFN_Subframe Configuration
-  struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA?
-  /// number of subframe allocation pattern available for MBSFN sync area
-  uint8_t num_sf_allocation_pattern;
-  /// number of active MBSFN area
-  uint8_t num_active_mbsfn_area;
-  /// MBSFN Area Info
-  struct  MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA];
-  /// PMCH Config
-  struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN];
-  /// MCCH status
-  uint8_t mcch_status;
-  /// MSI status
-  uint8_t msi_status;// could be an array if there are >1 MCH in one MBSFN area
-  /// CBA RNTI for each group
-  uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
-  /// last SFN for CBA channel access
-  uint8_t cba_last_access[NUM_MAX_CBA_GROUP];
-  /// total UE scheduler processing time
-  time_stats_t ue_scheduler; // total
-  /// UE ULSCH tx  processing time inlcuding RLC interface (rlc_data_req) and mac header generation
-  time_stats_t tx_ulsch_sdu;
-  /// UE DLSCH rx  processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser
-  time_stats_t rx_dlsch_sdu ;
-  /// UE query for MCH subframe processing time
-  time_stats_t ue_query_mch;
-  /// UE MCH rx processing time
-  time_stats_t rx_mch_sdu;
-  /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind)
-  time_stats_t rx_si;
-  /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind)
-  time_stats_t rx_p;
-} UE_MAC_INST;
-/*! \brief ID of the neighboring cells used for HO*/
-typedef struct {
-  uint16_t cell_ids[6];
-  uint8_t n_adj_cells;
-} neigh_cell_id_t;
-
-#include "proto.h"
-/*@}*/
-#endif /*__LAYER2_MAC_DEFS_H__ */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index eef1f9c9762..c46005ee2d5 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -35,7 +35,6 @@
 #include "LAYER2/MAC/mac_extern.h"
 
 #include "LAYER2/MAC/mac_proto.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "common/utils/LOG/log.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
@@ -89,7 +88,7 @@ void schedule_SRS(module_id_t module_idP,
   const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} };  // Table 5.5.3.3-2 3GPP 36.211 FDD
   const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
   eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &(eNB->UE_list);
+  UE_info_t *UE_info = &eNB->UE_info;
   nfapi_ul_config_request_body_t *ul_req = NULL;
   UE_sched_ctrl_t *UE_scheduling_control = NULL;
   COMMON_channels_t *cc = eNB->common_channels;
@@ -117,7 +116,7 @@ void schedule_SRS(module_id_t module_idP,
       if ((1 << tmp) & deltaTSFC) {
         /* This is an SRS subframe, loop over UEs */
         for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-          if (!UE_list->active[UE_id]) {
+          if (!UE_info->active[UE_id]) {
             continue;
           }
 
@@ -126,14 +125,14 @@ void schedule_SRS(module_id_t module_idP,
             continue;
           }
 
-          if(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) {
+          if(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) {
             LOG_E(MAC,"physicalConfigDedicated is null for UE %d\n",UE_id);
             printf("physicalConfigDedicated is null for UE %d\n",UE_id);
             return;
           }
 
           /* CDRX condition on Active Time and SRS type-0 report (36.321 5.7) */
-          UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
+          UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
 
           /* Test if Active Time not running since 6+ subframes */
           if (UE_scheduling_control->cdrx_configured == TRUE && UE_scheduling_control->in_active_time == FALSE) {
@@ -145,7 +144,7 @@ void schedule_SRS(module_id_t module_idP,
 
           ul_req = &(eNB->UL_req[CC_id].ul_config_request_body);
 
-          if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
+          if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
             if (soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) {
               get_srs_pos(&cc[CC_id],
                           soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex,
@@ -161,7 +160,7 @@ void schedule_SRS(module_id_t module_idP,
                 ul_config_pdu->pdu_size =  2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
                 ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
                 ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
-                ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
+                ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti;
                 ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
                 ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
                 ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
@@ -173,7 +172,7 @@ void schedule_SRS(module_id_t module_idP,
                 ul_req->number_of_pdus++;
               } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
             } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
-          } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
+          } // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
         } // end for loop on UE_id
       } // if((1<<tmp) & deltaTSFC)
     } // SRS config not NULL
@@ -196,7 +195,7 @@ void schedule_CSI(module_id_t module_idP,
   uint16_t                       N_OFFSET_CQI = 0;
   struct LTE_CQI_ReportPeriodic  *cqi_ReportPeriodic = NULL;
   eNB_MAC_INST                   *eNB = RC.mac[module_idP];
-  UE_list_t                      *UE_list = &eNB->UE_list;
+  UE_info_t                      *UE_info = &eNB->UE_info;
   COMMON_channels_t              *cc = NULL;
   nfapi_ul_config_request_body_t *ul_req = NULL;
   UE_sched_ctrl_t *UE_scheduling_control = NULL;
@@ -205,7 +204,7 @@ void schedule_CSI(module_id_t module_idP,
     cc = &eNB->common_channels[CC_id];
 
     for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-      if (UE_list->active[UE_id] == FALSE) {
+      if (UE_info->active[UE_id] == FALSE) {
         continue;
       }
 
@@ -214,7 +213,7 @@ void schedule_CSI(module_id_t module_idP,
         continue;
       }
 
-      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
+      AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
                   "physicalConfigDedicated is null for UE %d\n",
                   UE_id);
       /*
@@ -222,7 +221,7 @@ void schedule_CSI(module_id_t module_idP,
       * Here we consider classic periodic reports on PUCCH without PUSCH simultaneous transmission condition.
       * TODO: add the handling or test on simultaneous PUCCH/PUSCH transmission
       */
-      UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
+      UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
 
       if (UE_scheduling_control->cdrx_configured == TRUE) {
         /* Test if CQI masking activated */
@@ -246,8 +245,8 @@ void schedule_CSI(module_id_t module_idP,
 
       ul_req = &(eNB->UL_req[CC_id].ul_config_request_body);
 
-      if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL) {
-        cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;
+      if (UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL) {
+        cqi_ReportPeriodic = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;
 
         if (cqi_ReportPeriodic != NULL) {
           /* Rel8 Periodic CSI (CQI/PMI/RI) reporting */
@@ -262,10 +261,10 @@ void schedule_CSI(module_id_t module_idP,
               ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
               ul_config_pdu->pdu_size                                                          = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu));
               ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag             = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
-              ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
+              ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_info->UE_template[CC_id][UE_id].rnti;
               ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag           = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG;
               ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
-              ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, get_tmode(module_idP, CC_id, UE_id),
+              ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = get_rel8_dl_cqi_pmi_size(&UE_info->UE_sched_ctrl[UE_id], CC_id, cc, get_tmode(module_idP, CC_id, UE_id),
                   cqi_ReportPeriodic);
               ul_req->number_of_pdus++;
               ul_req->tl.tag                                                                   = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
@@ -279,7 +278,7 @@ void schedule_CSI(module_id_t module_idP,
                 ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
                 ul_config_pdu->pdu_size                                                          = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu));
                 ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag             = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
-                ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
+                ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_info->UE_template[CC_id][UE_id].rnti;
                 ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag           = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG;
                 ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
                 ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = (cc->p_eNB == 2) ? 1 : 2;
@@ -291,7 +290,7 @@ void schedule_CSI(module_id_t module_idP,
           } // if CSI Periodic is not release state
         } // if (cqi_ReportPeriodic != NULL)
       } // if cqi_ReportConfig != NULL
-    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
+    } // for (UE_id=UE_info->head; UE_id>=0; UE_id=UE_info->next[UE_id]) {
   } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 }
 
@@ -309,7 +308,7 @@ schedule_SR (module_id_t module_idP,
   int is_harq = 0;
   int pdu_list_index = 0;
   eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
+  UE_info_t *UE_info = &eNB->UE_info;
   nfapi_ul_config_request_t      *ul_req = NULL;
   nfapi_ul_config_request_body_t *ul_req_body = NULL;
   LTE_SchedulingRequestConfig_t  *SRconfig = NULL;
@@ -319,13 +318,13 @@ schedule_SR (module_id_t module_idP,
     eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
 
     for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-      if (!UE_list->active[UE_id]) {
+      if (!UE_info->active[UE_id]) {
         continue;
       }
 
-      if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) continue;
+      if (UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) continue;
 
-      if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) {
+      if ((SRconfig = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) {
         if (SRconfig->present == LTE_SchedulingRequestConfig_PR_setup) {
           if (SRconfig->choice.setup.sr_ConfigIndex <= 4) {          // 5 ms SR period
             if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue;
@@ -337,9 +336,11 @@ schedule_SR (module_id_t module_idP,
             if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue;
           } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) {  // 80 ms SR period
             if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue;
+          } else if (SRconfig->choice.setup.sr_ConfigIndex <= 156) { // 2ms SR period
+            if ((subframeP % 2) != (SRconfig->choice.setup.sr_ConfigIndex - 155)) continue;
           }
         }  // SRconfig->present == SchedulingRequestConfig_PR_setup)
-      }  // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL)
+      }  // SRconfig = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL)
 
       /* If we get here there is some PUCCH1 reception to schedule for SR */
       ul_req = &(eNB->UL_req[CC_id]);
@@ -354,14 +355,14 @@ schedule_SR (module_id_t module_idP,
              (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) ||
              (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) ||
              (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) &&
-            (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
+            (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_info->UE_template[CC_id][UE_id].rnti)) {
           skip_ue = 1;
           pdu_list_index = i;
           break;
         }
         /* If there is already an HARQ pdu, convert to SR_HARQ */
         else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) &&
-                 (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
+                 (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_info->UE_template[CC_id][UE_id].rnti)) {
           is_harq = 1;
           pdu_list_index = i;
           break;
@@ -375,20 +376,20 @@ schedule_SR (module_id_t module_idP,
             frameP,
             subframeP,
             UE_id,
-            UE_list->UE_template[CC_id][UE_id].rnti,
+            UE_info->UE_template[CC_id][UE_id].rnti,
             is_harq);
 
       /* Check Rel10 or Rel8 SR */
-      if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) &&
-          (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) &&
-          (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) {
+      if ((UE_info-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) &&
+          (UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) &&
+          (UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) {
         sr.sr_information_rel10.tl.tag                    = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG;
         sr.sr_information_rel10.number_of_pucch_resources = 1;
-        sr.sr_information_rel10.pucch_index_p1            = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
+        sr.sr_information_rel10.pucch_index_p1            = *UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
         LOG_D(MAC, "REL10 PUCCH INDEX P1:%d \n", sr.sr_information_rel10.pucch_index_p1);
       } else {
         sr.sr_information_rel8.tl.tag      = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG;
-        sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
+        sr.sr_information_rel8.pucch_index = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
         LOG_D(MAC, "REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index);
       }
 
@@ -401,7 +402,7 @@ schedule_SR (module_id_t module_idP,
       } else {
         ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type                                              = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
         ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag  = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
-        ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti    = UE_list->UE_template[CC_id][UE_id].rnti;
+        ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti    = UE_info->UE_template[CC_id][UE_id].rnti;
         ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0;
         ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0;
         ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information                             = sr;
@@ -416,20 +417,20 @@ schedule_SR (module_id_t module_idP,
 void
 check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
                  frame_t frameP, sub_frame_t subframeP) {
-  UE_list_t                 *UE_list = &RC.mac[module_idP]->UE_list;
+  UE_info_t                 *UE_info = &RC.mac[module_idP]->UE_info;
   nfapi_dl_config_request_t  *DL_req = &RC.mac[module_idP]->DL_req[0];
   uint16_t                      rnti = UE_RNTI(module_idP, UE_id);
   COMMON_channels_t              *cc = RC.mac[module_idP]->common_channels;
 
   // check uplink failure
-  if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
-      (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
-    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 1)
+  if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
+      (UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
+    if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer == 1)
       LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
-            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
+            UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
 
-    if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
-      UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
+    if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
+      UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
       // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
       nfapi_dl_config_request_pdu_t *dl_config_pdu                    = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu];
       memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t));
@@ -438,7 +439,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format            = NFAPI_DL_DCI_FORMAT_1A;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP, CC_id),
-          UE_list->UE_sched_ctrl[UE_id].
+          UE_info->UE_sched_ctrl[UE_id].
           dl_cqi[CC_id], format1A);
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                  = rnti;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type             = 1;  // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
@@ -454,22 +455,22 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
       LOG_D(MAC,
             "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
             UE_id, rnti,
-            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
+            UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
             dl_config_pdu->dci_dl_pdu.
             dci_dl_pdu_rel8.resource_block_coding);
     } else {    // ra_pdcch_sent==1
       LOG_D(MAC,
             "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
             UE_id, rnti,
-            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
+            UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
 
-      if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0;  // resend every 8 frames
+      if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0;  // resend every 8 frames
     }
 
-    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
+    UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++;
 
     // check threshold
-    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) {
+    if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) {
       // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311)
       if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) {
         MessageDef *m = itti_alloc_new_message(TASK_MAC_ENB, F1AP_UE_CONTEXT_RELEASE_REQ);
@@ -491,17 +492,17 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
                                rnti);
       }
 
-      UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
-      UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync   = 1;
+      UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
+      UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync   = 1;
     }
   }       // ul_failure_timer>0
 
-  UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
+  UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
 
-  if((U_PLANE_INACTIVITY_VALUE != 0) && (UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE * 10))) {
+  if((U_PLANE_INACTIVITY_VALUE != 0) && (UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE * 10))) {
     LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
     mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
-    UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer  = 0;
+    UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer  = 0;
   }// time > 60s
 }
 
@@ -565,7 +566,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   int               CC_id = 0;
   int               UE_id = -1;
   eNB_MAC_INST      *eNB                    = RC.mac[module_idP];
-  UE_list_t         *UE_list                = &(eNB->UE_list);
+  UE_info_t         *UE_info                = &(eNB->UE_info);
   COMMON_channels_t *cc                     = eNB->common_channels;
   UE_sched_ctrl_t     *UE_scheduling_control  = NULL;
   start_meas(&(eNB->eNB_scheduler));
@@ -584,16 +585,16 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
 
   /* Refresh UE list based on UEs dropped by PHY in previous subframe */
   for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-    if (UE_list->active[UE_id]) {
+    if (UE_info->active[UE_id]) {
       rnti = UE_RNTI(module_idP, UE_id);
       CC_id = UE_PCCID(module_idP, UE_id);
-      UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
+      UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
 
       if (((frameP & 127) == 0) && (subframeP == 0)) {
         LOG_I(MAC,"UE  rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n",
               rnti,
               UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync",
-              UE_list->UE_template[CC_id][UE_id].phr_info,
+              UE_info->UE_template[CC_id][UE_id].phr_info,
               UE_scheduling_control->dl_cqi[CC_id],
               (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10,
               (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10);
@@ -601,7 +602,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
 
       RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63;
 
-      if (UE_id == UE_list->head) {
+      if (UE_id == UE_info->list.head) {
         VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP]);
       }
 
@@ -735,7 +736,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
          * here for the current subframe. The variable 'UE_scheduling_control->in_active_time' should be updated
          * ONLY here. The variable can then be used for testing the actual state of the UE for scheduling purpose.
          */
-        UE_template = &(UE_list->UE_template[CC_id][UE_id]);
+        UE_template = &(UE_info->UE_template[CC_id][UE_id]);
 
         /* (a)synchronous HARQ processes handling for Active Time */
         for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) {
@@ -981,7 +982,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   /* Allocate CCEs for good after scheduling is done */
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
     if (cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) {
-      allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2);
+      int rc = allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2);
+      if (rc < 0)
+        LOG_E(MAC, "%s() %4d.%d ERROR ALLOCATING CCEs\n", __func__, frameP, subframeP);
     }
   }
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index fb765e6dacb..d1365b9ac32 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -587,7 +587,7 @@ generate_Msg4(module_id_t module_idP,
 {
   eNB_MAC_INST *mac = RC.mac[module_idP];
   COMMON_channels_t *cc = mac->common_channels;
-  UE_list_t *UE_list = &(mac->UE_list);
+  UE_info_t *UE_info = &mac->UE_info;
   int16_t rrc_sdu_length = 0;
   uint16_t msg4_padding = 0;
   uint16_t msg4_post_padding = 0;
@@ -831,7 +831,7 @@ generate_Msg4(module_id_t module_idP,
       dl_req_body->number_pdu++;
       ra->state = WAITMSG4ACK;
       lcid = 0;
-      UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
+      UE_info->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
       msg4_header = 1 + 6 + 1;        // CR header, CR CE, SDU header
       AssertFatal((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header)>=0,
                   "msg4_TBS %d is too small, change mcs to increase by %d bytes\n",ra->msg4_TBsize,ra->msg4_rrc_sdu_length+msg4_header-ra->msg4_TBsize);
@@ -848,7 +848,7 @@ generate_Msg4(module_id_t module_idP,
              module_idP, CC_idP, frameP, subframeP, ra->msg4_TBsize, ra->msg4_rrc_sdu_length, msg4_header, msg4_padding, msg4_post_padding);
       DevAssert (UE_id != UE_INDEX_INVALID);  // FIXME not sure how to gracefully return
       // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
-      offset = generate_dlsch_header ((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,       //num_sdus
+      offset = generate_dlsch_header ((unsigned char *) mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,       //num_sdus
                                       (unsigned short *) &ra->msg4_rrc_sdu_length,     //
                                       &lcid,  // sdu_lcid
                                       255,    // no drx
@@ -856,7 +856,7 @@ generate_Msg4(module_id_t module_idP,
                                       ra->cont_res_id,       // contention res id
                                       msg4_padding,   // no padding
                                       msg4_post_padding);
-      memcpy ((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0][(unsigned char) offset], &cc[CC_idP].CCCH_pdu.payload[0], ra->msg4_rrc_sdu_length);
+      memcpy ((void *) &mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0][(unsigned char) offset], &cc[CC_idP].CCCH_pdu.payload[0], ra->msg4_rrc_sdu_length);
       // DL request
       mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
       TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
@@ -864,7 +864,7 @@ generate_Msg4(module_id_t module_idP,
       TX_req->pdu_index = mac->pdu_index[CC_idP]++;
       TX_req->num_segments = 1;
       TX_req->segments[0].segment_length = ra->msg4_TBsize;
-      TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0];
+      TX_req->segments[0].segment_data = mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0];
       mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
       // Program ACK/NAK for Msg4 PDSCH
       int             absSF = (frameP * 10) + subframeP;
@@ -899,8 +899,8 @@ generate_Msg4(module_id_t module_idP,
 
       ul_req_body->number_of_pdus++;
       T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP),
-         T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize));
-      trace_pdu (DIRECTION_DOWNLINK, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0],
+         T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_info.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize));
+      trace_pdu (DIRECTION_DOWNLINK, (uint8_t *) mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0],
                  ra->msg4_rrc_sdu_length,
                  UE_id, 3, UE_RNTI (module_idP, UE_id),
                  mac->frame, mac->subframe, 0, 0);
@@ -963,10 +963,10 @@ generate_Msg4(module_id_t module_idP,
                              1, // tpc, none
                              getRIV(N_RB_DL, first_rb, 4),  // resource_block_coding
                              ra->msg4_mcs,  // mcs
-                             1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
+                             1 - UE_info->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
                              0, // rv
                              0);  // vrb_flag
-        UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid];
+        UE_info->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_info->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid];
         LOG_D(MAC,
               "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n",
               frameP, subframeP, dl_req_body->number_pdu,
@@ -1000,7 +1000,7 @@ generate_Msg4(module_id_t module_idP,
           lcid = 0;
           // put HARQ process round to 0
           ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
-          UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
+          UE_info->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
 
           if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
             msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
@@ -1018,7 +1018,7 @@ generate_Msg4(module_id_t module_idP,
           DevAssert(UE_id != UE_INDEX_INVALID); // FIXME not sure how to gracefully return
           // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
           int num_sdus = rrc_sdu_length > 0 ? 1 : 0;
-          offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0],
+          offset = generate_dlsch_header((unsigned char *) mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0],
                                          num_sdus,  //num_sdus
                                          (unsigned short *) &rrc_sdu_length,  //
                                          &lcid, // sdu_lcid
@@ -1027,10 +1027,14 @@ generate_Msg4(module_id_t module_idP,
                                          ra->cont_res_id, // contention res id
                                          msg4_padding,  // no padding
                                          msg4_post_padding);
-          memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
+          memcpy((void *) &mac->UE_info.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
                  &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length);
           // DLSCH Config
-          fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, mac->pdu_index[CC_idP], ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D
+          fill_nfapi_dlsch_config(&dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu],
+                                  ra->msg4_TBsize,
+                                  mac->pdu_index[CC_idP],
+                                  ra->rnti,
+                                  2, // resource_allocation_type : format 1A/1B/1D
                                   0,  // virtual_resource_block_assignment_flag : localized
                                   getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB
                                   2,  // modulation: QPSK
@@ -1049,6 +1053,7 @@ generate_Msg4(module_id_t module_idP,
                                   (cc->p_eNB == 1) ? 1 : 2, // transmission mode
                                   1,  // num_bf_prb_per_subband
                                   1); // num_bf_vector
+          dl_req_body->number_pdu++;
           LOG_D(MAC,
                 "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n",
                 dl_req_body->number_pdu, mac->pdu_index[CC_idP]);
@@ -1058,7 +1063,7 @@ generate_Msg4(module_id_t module_idP,
                               (frameP * 10) + subframeP,
                               rrc_sdu_length+offset,
                               mac->pdu_index[CC_idP],
-                              mac->UE_list.
+                              mac->UE_info.
                               DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]);
           mac->pdu_index[CC_idP]++;
           dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf;
@@ -1074,11 +1079,11 @@ generate_Msg4(module_id_t module_idP,
           T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP),
             T_INT(CC_idP), T_INT(ra->rnti), T_INT(frameP),
             T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ),
-            T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].
+            T_BUFFER(&mac->UE_info.DLSCH_pdu[CC_idP][0][UE_id].
                      payload[0], ra->msg4_TBsize));
           trace_pdu(DIRECTION_DOWNLINK,
                     (uint8_t *) mac->
-                    UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
+                    UE_info.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
                     rrc_sdu_length, UE_id,  WS_C_RNTI,
                     UE_RNTI(module_idP, UE_id), mac->frame,
                     mac->subframe, 0, 0);
@@ -1116,14 +1121,14 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
   int first_rb;
   int N_RB_DL;
   nfapi_dl_config_request_pdu_t *dl_config_pdu;
-  UE_list_t *UE_list = &mac->UE_list;
+  UE_info_t *UE_info = &mac->UE_info;
   nfapi_dl_config_request_t *dl_req;
   nfapi_dl_config_request_body_t *dl_req_body;
   int round;
   // check HARQ status and retransmit if necessary
   UE_id = find_UE_id(module_idP, ra->rnti);
   AssertFatal(UE_id >= 0, "Can't find UE for t-crnti\n");
-  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid];
+  round = UE_info->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid];
   vrb_map = cc[CC_idP].vrb_map;
   dl_req = &mac->DL_req[CC_idP];
   dl_req_body = &dl_req->dl_config_request_body;
@@ -1156,7 +1161,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
                              1, // tpc, none
                              getRIV(N_RB_DL, first_rb, 4),  // resource_block_coding
                              ra->msg4_mcs,  // mcs
-                             UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
+                             UE_info->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
                              round & 3, // rv
                              0);  // vrb_flag
 
@@ -1173,7 +1178,8 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
           // DLSCH Config
           //DJP - fix this pdu_index = -1
           LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
-          fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize,
+          fill_nfapi_dlsch_config(&dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu],
+                                  ra->msg4_TBsize,
                                   -1
                                   /* retransmission, no pdu_index */
                                   , ra->rnti, 2,  // resource_allocation_type : format 1A/1B/1D
@@ -1195,6 +1201,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
                                   (cc->p_eNB == 1) ? 1 : 2, // transmission mode
                                   1,  // num_bf_prb_per_subband
                                   1); // num_bf_vector
+          dl_req_body->number_pdu++;
 
           if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) {
             set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
@@ -1226,8 +1233,8 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
     LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP);
     UE_id = find_UE_id(module_idP, ra->rnti);
     DevAssert(UE_id != -1);
-    mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
-    mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels;
+    mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
+    mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels;
     cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
   }
 }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index eba4bdcee99..7621994ab2e 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -86,31 +86,6 @@ add_ue_dlsch_info(module_id_t module_idP,
   return;
 }
 
-//------------------------------------------------------------------------------
-int
-schedule_next_dlue(module_id_t module_idP,
-                   int CC_id,
-                   sub_frame_t subframeP)
-//------------------------------------------------------------------------------
-{
-  int next_ue;
-  UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
-
-  for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) {
-    if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_WAITING) {
-      return next_ue;
-    }
-  }
-
-  for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) {
-    if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) {
-      eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING;
-    }
-  }
-
-  return (-1);        //next_ue;
-}
-
 //------------------------------------------------------------------------------
 int
 generate_dlsch_header(unsigned char *mac_header,
@@ -317,12 +292,12 @@ set_ul_DAI(int module_idP,
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
+  UE_info_t *UE_info = &eNB->UE_info;
   unsigned char DAI;
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
 
   if (cc->tdd_Config != NULL) {    //TDD
-    DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
+    DAI = (UE_info->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
     LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",
           module_idP,
           CC_idP,
@@ -341,20 +316,20 @@ set_ul_DAI(int module_idP,
         switch (subframeP) {
           case 0:
           case 1:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
             break;
 
           case 4:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
             break;
 
           case 5:
           case 6:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
             break;
 
           case 9:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
             break;
         }
 
@@ -362,30 +337,30 @@ set_ul_DAI(int module_idP,
 
       case 2:
         //      if ((subframeP==3)||(subframeP==8))
-        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
+        //  UE_info->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
         break;
 
       case 3:
 
         //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) {
         //  LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1);
-        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
+        //  UE_info->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
         //}
         switch (subframeP) {
           case 5:
           case 6:
           case 1:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
             break;
 
           case 7:
           case 8:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
             break;
 
           case 9:
           case 0:
-            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI;
+            UE_info->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI;
             break;
 
           default:
@@ -396,17 +371,17 @@ set_ul_DAI(int module_idP,
 
       case 4:
         //      if ((subframeP==8)||(subframeP==9))
-        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
+        //  UE_info->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
         break;
 
       case 5:
         //      if (subframeP==8)
-        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
+        //  UE_info->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
         break;
 
       case 6:
         //      if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9))
-        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
+        //  UE_info->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
         break;
 
       default:
@@ -417,20 +392,129 @@ set_ul_DAI(int module_idP,
   return;
 }
 
+void ue_rrc_release(rnti_t rnti) {
+  if(rrc_release_info.num_UEs == 0 || rlc_am_mui.rrc_mui_num == 0) {
+    return;
+  }
+
+  while(pthread_mutex_trylock(&rrc_release_freelist)) {
+    /* spin... */
+  }
+
+  uint16_t release_total = 0;
+
+  for (uint16_t n = 0; n < NUMBER_OF_UE_MAX; n++) {
+    RRC_release_ctrl_t *release_ctrl = &rrc_release_info.RRC_release_ctrl[n];
+    if(release_ctrl->flag == 0)
+      continue;
+
+    release_total++;
+    if(release_ctrl->flag == 1 && release_ctrl->rnti == rnti) {
+      for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
+        if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) {
+          release_ctrl->flag = 3;
+          LOG_D(MAC,
+                "DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",
+                n, rnti, rlc_am_mui.rrc_mui[mui_num], mui_num);
+          break;
+        }
+      }
+    }
+
+    if(release_ctrl->flag == 2 && release_ctrl->rnti == rnti) {
+      for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
+        if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) {
+          release_ctrl->flag = 4;
+          LOG_D(MAC, "DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",
+                n,
+                rnti,
+                rlc_am_mui.rrc_mui[mui_num],
+                mui_num);
+          break;
+        }
+      }
+    }
+
+    if(release_total >= rrc_release_info.num_UEs)
+      break;
+  }
+
+  pthread_mutex_unlock(&rrc_release_freelist);
+}
+
+void check_ra_rnti_mui(module_id_t mod_id, int CC_id, frame_t f, sub_frame_t sf, rnti_t rnti) {
+  LTE_TDD_Config_t *tdd_config = RC.mac[mod_id]->common_channels[CC_id].tdd_Config;
+  int harq_pid = frame_subframe2_dl_harq_pid(tdd_config, f, sf);
+  RA_t *ra = &RC.mac[mod_id]->common_channels[CC_id].ra[0];
+  for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) {
+    if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) {
+      for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
+        if (ra->crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) {
+          ra->crnti_harq_pid = harq_pid;
+          ra->state = MSGCRNTI_ACK;
+          break;
+        }
+      }
+    }
+  }
+}
+
 //------------------------------------------------------------------------------
 void
 schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) {
-  int i = 0;
-  slice_info_t *sli = &RC.mac[module_idP]->slice_info;
-  memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub));
-
-  for (i = 0; i < sli->n_dl; i++) {
-    // Run each enabled slice-specific schedulers one by one
-    sli->dl[i].sched_cb(module_idP,
-                        i,
-                        frameP,
-                        subframeP,
-                        mbsfn_flag/*, dl_info*/);
+  if (is_pmch_subframe(frameP, subframeP, &RC.eNB[module_idP][0]->frame_parms))
+    return;
+
+  for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
+    // for TDD: check that we have to act here, otherwise skip
+    COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
+    if (cc->tdd_Config) {
+      int tdd_sfa = cc->tdd_Config->subframeAssignment;
+
+      switch (subframeP) {
+        case 0:
+          // always continue
+          break;
+
+        case 1:
+        case 2:
+          continue;
+
+        case 3:
+          if (tdd_sfa != 2 && tdd_sfa != 5)
+            continue;
+          break;
+
+        case 4:
+          if (tdd_sfa != 1 && tdd_sfa != 2 && tdd_sfa != 4 && tdd_sfa != 5)
+            continue;
+          break;
+
+        case 5:
+          break;
+
+        case 6:
+        case 7:
+          if (tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5)
+            continue;
+          break;
+
+        case 8:
+          if (tdd_sfa != 2 && tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5)
+            continue;
+          break;
+
+        case 9:
+          if (tdd_sfa == 0)
+            continue;
+          break;
+      }
+    }
+
+    if (mbsfn_flag[CC_id] != 0)
+      continue;
+
+    schedule_ue_spec(module_idP, CC_id, frameP, subframeP);
   }
 }
 
@@ -454,138 +538,35 @@ void  getRepetition(UE_TEMPLATE *pue_template,unsigned int *maxRep, unsigned int
 */
 void
 schedule_ue_spec(module_id_t module_idP,
-                 int slice_idxP,
+                 int CC_id,
                  frame_t frameP,
-                 sub_frame_t subframeP,
-                 int *mbsfn_flag)
+                 sub_frame_t subframeP)
 //------------------------------------------------------------------------------
 {
-  int CC_id;
-  int UE_id;
-  int aggregation;
-  mac_rlc_status_resp_t rlc_status;
-  int ta_len = 0;
-  unsigned char sdu_lcids[NB_RB_MAX];
-  int lcid, offset, num_sdus = 0;
-  int nb_rb, nb_rb_temp, nb_available_rb;
-  uint16_t sdu_lengths[NB_RB_MAX];
-  int TBS, j, padding = 0, post_padding = 0;
-  rnti_t rnti;
   unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
-  int round_DL = 0;
-  int harq_pid = 0;
-  uint16_t release_num;
-  uint8_t ra_ii;
-  eNB_UE_STATS *eNB_UE_stats = NULL;
-  UE_TEMPLATE *ue_template = NULL;
-  eNB_STATS *eNB_stats = NULL;
-  RRC_release_ctrl_t *release_ctrl = NULL;
-  DLSCH_PDU *dlsch_pdu = NULL;
-  RA_t *ra = NULL;
-  int sdu_length_total = 0;
   eNB_MAC_INST *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc = eNB->common_channels;
-  UE_list_t *UE_list = &eNB->UE_list;
-  int continue_flag = 0;
-  int32_t snr, target_snr;
-  int tpc = 1;
-  UE_sched_ctrl_t *ue_sched_ctrl;
-  int mcs;
-  int i;
-  int min_rb_unit[NFAPI_CC_MAX];
-  int N_RB_DL[NFAPI_CC_MAX];
-  int total_nb_available_rb[NFAPI_CC_MAX];
-  int N_RBG[NFAPI_CC_MAX];
-  nfapi_dl_config_request_body_t *dl_req;
-  nfapi_dl_config_request_pdu_t *dl_config_pdu;
-  int tdd_sfa;
-  int ta_update;
-  int header_length_last;
-  int header_length_total;
-  rrc_eNB_ue_context_t *ue_contextP = NULL;
-  int nb_mac_CC = RC.nb_mac_CC[module_idP];
-  long dl_Bandwidth;
-
-  if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
-       //LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
-       return ;
-  }
-
+  UE_info_t *UE_info = &eNB->UE_info;
+  const int dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth;
+  const int N_RB_DL = to_prb(dl_Bandwidth);
+  const int N_RBG = to_rbg(eNB->common_channels[CC_id].mib->message.dl_Bandwidth);
+  int total_nb_available_rb = N_RB_DL;
+  nfapi_dl_config_request_body_t *dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
 
   start_meas(&eNB->schedule_dlsch);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
                                           VCD_FUNCTION_IN);
 
-  // for TDD: check that we have to act here, otherwise return
-  if (cc[0].tdd_Config) {
-    tdd_sfa = cc[0].tdd_Config->subframeAssignment;
-
-    switch (subframeP) {
-      case 0:
-        // always continue
-        break;
-
-      case 1:
-      case 2:
-        return;
-
-      case 3:
-        if (tdd_sfa != 2 && tdd_sfa != 5)
-          return;
-
-        break;
-
-      case 4:
-        if (tdd_sfa != 1 && tdd_sfa != 2 && tdd_sfa != 4 && tdd_sfa != 5)
-          return;
-
-        break;
-
-      case 5:
-        break;
-
-      case 6:
-      case 7:
-        if (tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5)
-          return;
-
-        break;
-
-      case 8:
-        if (tdd_sfa != 2 && tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5)
-          return;
-
-        break;
-
-      case 9:
-        if (tdd_sfa == 0)
-          return;
-
-        break;
-    }
-  }
+  for (int i = 0; i < N_RB_DL; i++)
+    if (cc[CC_id].vrb_map[i] != 0)
+      total_nb_available_rb--;
 
-  aggregation = 2;
-
-  for (CC_id = 0, eNB_stats = &eNB->eNB_stats[0]; CC_id < nb_mac_CC; CC_id++, eNB_stats++) {
-    dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth;
-    N_RB_DL[CC_id] = to_prb(dl_Bandwidth);
-    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
-    // get number of PRBs less those used by common channels
-    total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
-
-    for (i = 0; i < N_RB_DL[CC_id]; i++)
-      if (cc[CC_id].vrb_map[i] != 0)
-        total_nb_available_rb[CC_id]--;
-
-    N_RBG[CC_id] = to_rbg(dl_Bandwidth);
-    // store the global enb stats:
-    eNB_stats->num_dlactive_UEs = UE_list->num_UEs;
-    eNB_stats->available_prbs = total_nb_available_rb[CC_id];
-    eNB_stats->total_available_prbs += total_nb_available_rb[CC_id];
-    eNB_stats->dlsch_bytes_tx = 0;
-    eNB_stats->dlsch_pdus_tx = 0;
-  }
+  // store the global enb stats:
+  eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_info->num_UEs;
+  eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb;
+  eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb;
+  eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0;
+  eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0;
 
   // CALLING Pre_Processor for downlink scheduling
   // (Returns estimation of RBs required by each UE and the allocation on sub-band)
@@ -593,1257 +574,624 @@ schedule_ue_spec(module_id_t module_idP,
                                           VCD_FUNCTION_IN);
   start_meas(&eNB->schedule_dlsch_preprocessor);
   dlsch_scheduler_pre_processor(module_idP,
-                                slice_idxP,
+                                CC_id,
                                 frameP,
-                                subframeP,
-                                mbsfn_flag,
-                                eNB->slice_info.rballoc_sub);
+                                subframeP);
   stop_meas(&eNB->schedule_dlsch_preprocessor);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
                                           VCD_FUNCTION_OUT);
 
-  if (RC.mac[module_idP]->slice_info.interslice_share_active) {
-    dlsch_scheduler_interslice_multiplexing(module_idP,
-                                            frameP,
-                                            subframeP,
-                                            eNB->slice_info.rballoc_sub);
-    /* the interslice multiplexing re-sorts the UE_list for the slices it tries
-     * to multiplex, so we need to sort it for the current slice again */
-    sort_UEs(module_idP,
-             slice_idxP,
-             frameP,
-             subframeP);
-  }
-
-  for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) {
-    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",
-          CC_id);
-    dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
-
-    if (mbsfn_flag[CC_id] > 0)
-      continue;
-
-    for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-      LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n",
-            CC_id,
-            UE_id);
-      continue_flag = 0; // reset the flag to allow allocation for the remaining UEs
-      rnti = UE_RNTI(module_idP, UE_id);
-      ue_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
-      ue_template = &UE_list->UE_template[CC_id][UE_id];
-
-      if (ue_template->rach_resource_type > 0) {
-        continue_flag = 1;
-      }
-
-      if (&(UE_list->eNB_UE_stats[CC_id][UE_id]) == NULL) {
-        LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
-        continue_flag = 1;
-      } else {
-        eNB_UE_stats = &(UE_list->eNB_UE_stats[CC_id][UE_id]);
-      }
-
-      if (continue_flag != 1) {
-        switch (get_tmode(module_idP,
-                          CC_id,
-                          UE_id)) {
-          case 1:
-          case 2:
-          case 7:
-            aggregation = get_aggregation(get_bw_index(module_idP,
-                                          CC_id),
-                                          ue_sched_ctrl->dl_cqi[CC_id],
-                                          format1);
-            break;
-
-          case 3:
-            aggregation = get_aggregation(get_bw_index(module_idP,
-                                          CC_id),
-                                          ue_sched_ctrl->dl_cqi[CC_id],
-                                          format2A);
-            break;
-
-          default:
-            AssertFatal(1==0,"Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id));
-            aggregation = 2;
-            break;
-        }
-      }
-
-      /* if (continue_flag != 1 */
-      if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0 || // no RBs allocated
-          CCE_allocation_infeasible(module_idP,
-                                    CC_id,
-                                    1,
-                                    subframeP,
-                                    aggregation,
-                                    rnti)) {
-        LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
-              module_idP,
-              frameP,
-              UE_id,
-              CC_id);
-        continue_flag = 1;  //to next user (there might be rbs availiable for other UEs in TM5
-      }
-
-      // If TDD
-      if (cc[CC_id].tdd_Config != NULL) {    //TDD
-        set_ue_dai(subframeP,
-                   UE_id,
-                   CC_id,
-                   cc[CC_id].tdd_Config->subframeAssignment,
-                   UE_list);
-        // update UL DAI after DLSCH scheduling
-        set_ul_DAI(module_idP,
-                   UE_id,
-                   CC_id,
-                   frameP,
-                   subframeP);
-      }
-
-      if (continue_flag == 1) {
-        add_ue_dlsch_info(module_idP,
-                          CC_id,
-                          UE_id,
-                          subframeP,
-                          S_DL_NONE,
-                          rnti);
-        continue;
-      }
-
-      nb_available_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id];
-      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,
-                                             frameP,
-                                             subframeP);
-      round_DL = ue_sched_ctrl->round[CC_id][harq_pid];
-      eNB_UE_stats->crnti = rnti;
-      eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
-      eNB_UE_stats->harq_pid = harq_pid;
-      eNB_UE_stats->harq_round = round_DL;
-
-      if (eNB_UE_stats->rrc_status < RRC_RECONFIGURED) {
-        ue_sched_ctrl->uplane_inactivity_timer = 0;
-      }
-
-      if (eNB_UE_stats->rrc_status < RRC_CONNECTED) {
-        LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id);
-        continue;
-      }
-
-      header_length_total = 0;
-      sdu_length_total = 0;
-      num_sdus = 0;
-
-      /*
-      DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) ||
-                (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)),
-                eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
-      */
-      if (NFAPI_MODE != NFAPI_MONOLITHIC) {
-        eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]];
-      } else { // this operation is also done in the preprocessor
-        eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
-                                        eNB->slice_info.dl[slice_idxP].maxmcs);  // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
-      }
-
-      // Store stats
-      // eNB_UE_stats->dl_cqi= eNB_UE_stats->dl_cqi;
-
-      // Initializing the rb allocation indicator for each UE
-      for (j = 0; j < N_RBG[CC_id]; j++) {
-        ue_template->rballoc_subband[harq_pid][j] = 0;
-      }
-
-      LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
-            module_idP,
-            frameP,
-            UE_id,
-            CC_id,
-            rnti,
-            harq_pid,
-            round_DL,
-            nb_available_rb,
-            ue_sched_ctrl->dl_cqi[CC_id],
-            eNB_UE_stats->dlsch_mcs1,
-            eNB_UE_stats->rrc_status);
-
-      /* Process retransmission  */
-      if (round_DL != 8) {
-        // get freq_allocation
-        nb_rb = ue_template->nb_rb[harq_pid];
-        TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid],
-                         nb_rb);
-
-        if (nb_rb <= nb_available_rb) {
-          /* CDRX */
-          ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
-
-          if (ue_sched_ctrl->cdrx_configured) {
-            ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission
-
-            /*
-             * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop.
-             */
-            if (harq_pid == 0) {
-              VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]);
-            }
-          }
-
-          if (cc[CC_id].tdd_Config != NULL) {
-            ue_template->DAI++;
-            update_ul_dci(module_idP,
-                          CC_id,
-                          rnti,
-                          ue_template->DAI,
-                          subframeP);
-            LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
-                  CC_id,
-                  subframeP,
-                  UE_id,
-                  ue_template->DAI);
-          }
-
-          if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
-            for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
-              ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
-            }
-          } else {
-            nb_rb_temp = nb_rb;
-            j = 0;
-
-            while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
-              if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) {
-                if (ue_template->rballoc_subband[harq_pid][j])
-                  LOG_W(MAC, "WARN: rballoc_subband not free for retrans?\n");
-
-                ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
-                nb_rb_temp -= min_rb_unit[CC_id];
-
-                if ((j == N_RBG[CC_id] - 1) && (N_RB_DL[CC_id] == 25 || N_RB_DL[CC_id] == 50))
-                  nb_rb_temp++;
-              }
-
-              j++;
-            }
-          }
-
-          nb_available_rb -= nb_rb;
-
-          switch (get_tmode(module_idP, CC_id, UE_id)) {
-            case 1:
-            case 2:
-            case 7:
-            default:
-              LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n",
-                    rnti);
-              dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
-              memset((void *) dl_config_pdu,
-                     0,
-                     sizeof(nfapi_dl_config_request_pdu_t));
-              dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
-              dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
-                get_aggregation(get_bw_index(module_idP,
-                                             CC_id),
-                                ue_sched_ctrl->dl_cqi[CC_id],
-                                format1);
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ue_template->oldNDI[harq_pid];
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = ue_template->oldmcs1[harq_pid];
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round_DL & 3;
-
-              // TDD
-              if (cc[CC_id].tdd_Config != NULL) {
-                dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3;
-                LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
-                      module_idP,
-                      CC_id,
-                      harq_pid,
-                      round_DL,
-                      ue_template->DAI - 1,
-                      ue_template->oldmcs1[harq_pid]);
-              } else {
-                LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
-                      module_idP,
-                      CC_id,
-                      harq_pid,
-                      round_DL,
-                      ue_template->oldmcs1[harq_pid]);
-              }
-
-              if (!CCE_allocation_infeasible(module_idP,
-                                             CC_id,
-                                             1,
-                                             subframeP,
-                                             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
-                                             rnti)) {
-                dl_req->number_dci++;
-                dl_req->number_pdu++;
-                dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
-                eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
-                eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
-                fill_nfapi_dlsch_config(eNB,
-                                        dl_req,
-                                        TBS,
-                                        -1,   // retransmission, no pdu_index
-                                        rnti,
-                                        0,    // type 0 allocation from 7.1.6 in 36.213
-                                        0,    // virtual_resource_block_assignment_flag, unused here
-                                        0,    // resource_block_coding, to be filled in later
-                                        getQm(ue_template->oldmcs1[harq_pid]),
-                                        round_DL & 3, // redundancy version
-                                        1,    // transport blocks
-                                        0,    // transport block to codeword swap flag
-                                        cc[CC_id].p_eNB == 1 ? 0 : 1,    // transmission_scheme
-                                        1,    // number of layers
-                                        1,    // number of subbands
-                                        //                      uint8_t codebook_index,
-                                        4,    // UE category capacity
-                                        ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
-                                        0,    // delta_power_offset for TM5
-                                        0,    // ngap
-                                        0,    // nprb
-                                        cc[CC_id].p_eNB == 1 ? 1 : 2,    // transmission mode
-                                        0,    //number of PRBs treated as one subband, not used here
-                                        0);   // number of beamforming vectors, not used here
-                LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
-                      eNB->pdu_index[CC_id],
-                      round_DL);
-                program_dlsch_acknak(module_idP,
-                                     CC_id,
-                                     UE_id,
-                                     frameP,
-                                     subframeP,
-                                     dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
-                // No TX request for retransmission (check if null request for FAPI)
-              } else {
-                LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
-                      frameP,
-                      subframeP,
-                      UE_id,
-                      rnti);
-              }
-          }
-
-          add_ue_dlsch_info(module_idP,
-                            CC_id, UE_id,
-                            subframeP,
-                            S_DL_SCHEDULED,
-                            rnti);
-          //eNB_UE_stats->dlsch_trials[round]++;
-          eNB_UE_stats->num_retransmission += 1;
-          eNB_UE_stats->rbs_used_retx = nb_rb;
-          eNB_UE_stats->total_rbs_used_retx += nb_rb;
-          eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
-        } else {
-          LOG_D(MAC,
-                "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
-                module_idP,
-                frameP,
-                CC_id,
-                UE_id);
-        }
-      } else {
-        /* This is a potentially new SDU opportunity */
-        rlc_status.bytes_in_buffer = 0;
-        // Now check RLC information to compute number of required RBs
-        // get maximum TBS size for RLC request
-        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-                         nb_available_rb);
-
-        // add the length for  all the control elements (timing adv, drx, etc) : header + payload
-
-        if (ue_sched_ctrl->ta_timer == 0) {
-          ta_update = ue_sched_ctrl->ta_update;
-
-          /* if we send TA then set timer to not send it for a while */
-          if (ta_update != 31) {
-            ue_sched_ctrl->ta_timer = 20;
-          }
-
-          /* reset ta_update */
-          ue_sched_ctrl->ta_update = 31;
-        } else {
-          ta_update = 31;
-        }
-
-        ta_len = (ta_update != 31) ? 2 : 0;
-
-        // RLC data on DCCH
-        if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP,
-                                          rnti,
-                                          module_idP,
-                                          frameP,
-                                          subframeP,
-                                          ENB_FLAG_YES,
-                                          MBMS_FLAG_NO,
-                                          DCCH,
-                                          TBS - ta_len - header_length_total - sdu_length_total - 3, 0, 0
-                                         );
-          sdu_lengths[0] = 0;
-
-          if (rlc_status.bytes_in_buffer > 0) {
-            LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
-                  module_idP,
-                  frameP,
-                  subframeP,
-                  CC_id,
-                  TBS - ta_len - header_length_total - sdu_length_total - 3);
-            sdu_lengths[0] = mac_rlc_data_req(module_idP,
-                                              rnti,
-                                              module_idP,
-                                              frameP,
-                                              ENB_FLAG_YES,
-                                              MBMS_FLAG_NO,
-                                              DCCH,
-                                              TBS, //not used
-                                              (char *)&dlsch_buffer[0], 0, 0
-                                             );
-
-            if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) {
-              while(pthread_mutex_trylock(&rrc_release_freelist)) {
-                /* spin... */
-              }
-
-              uint16_t release_total = 0;
-
-              for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
-                   release_num < NUMBER_OF_UE_MAX;
-                   release_num++, release_ctrl++) {
-                if(release_ctrl->flag > 0) {
-                  release_total++;
-                } else {
-                  continue;
-                }
-
-                if(release_ctrl->flag == 1) {
-                  if(release_ctrl->rnti == rnti) {
-                    for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
-                      if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) {
-                        release_ctrl->flag = 3;
-                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",
-                              release_num,
-                              rnti,
-                              rlc_am_mui.rrc_mui[mui_num],
-                              mui_num);
-                        break;
-                      }
-                    }
-                  }
-                }
-
-                if(release_ctrl->flag == 2) {
-                  if(release_ctrl->rnti == rnti) {
-                    for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
-                      if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) {
-                        release_ctrl->flag = 4;
-                        LOG_D(MAC, "DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",
-                              release_num,
-                              rnti,
-                              rlc_am_mui.rrc_mui[mui_num],
-                              mui_num);
-                        break;
-                      }
-                    }
-                  }
-                }
-
-                if(release_total >= rrc_release_info.num_UEs)
-                  break;
-              }
-
-              pthread_mutex_unlock(&rrc_release_freelist);
-            }
-
-            for (ra_ii = 0, ra = &eNB->common_channels[CC_id].ra[0]; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) {
-              if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) {
-                for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) {
-                  if (ra->crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) {
-                    ra->crnti_harq_pid = harq_pid;
-                    ra->state = MSGCRNTI_ACK;
-                    break;
-                  }
-                }
-              }
-            }
-
-            T(T_ENB_MAC_UE_DL_SDU,
-              T_INT(module_idP),
-              T_INT(CC_id),
-              T_INT(rnti),
-              T_INT(frameP),
-              T_INT(subframeP),
-              T_INT(harq_pid),
-              T_INT(DCCH),
-              T_INT(sdu_lengths[0]));
-            LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
-                  module_idP,
-                  CC_id,
-                  sdu_lengths[0]);
-            sdu_length_total = sdu_lengths[0];
-            sdu_lcids[0] = DCCH;
-            eNB_UE_stats->lcid_sdu[0] = DCCH;
-            eNB_UE_stats->sdu_length_tx[DCCH] = sdu_lengths[0];
-            eNB_UE_stats->num_pdu_tx[DCCH] += 1;
-            eNB_UE_stats->num_bytes_tx[DCCH] += sdu_lengths[0];
-            header_length_last = 1 + 1 + (sdu_lengths[0] >= 128);
-            header_length_total += header_length_last;
-            num_sdus = 1;
-#ifdef DEBUG_eNB_SCHEDULER
-            LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :",
-                  module_idP,
-                  CC_id,
-                  sdu_lengths[0]);
-
-            for (j = 0; j < sdu_lengths[0]; ++j) {
-              LOG_T(MAC, "%x ",
-                    dlsch_buffer[j]);
-            }
-
-            LOG_T(MAC, "\n");
-#endif
-          }
-        }
-
-        // RLC data on DCCH1
-        if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP,
-                                          rnti,
-                                          module_idP,
-                                          frameP,
-                                          subframeP,
-                                          ENB_FLAG_YES,
-                                          MBMS_FLAG_NO,
-                                          DCCH + 1,
-                                          TBS - ta_len - header_length_total - sdu_length_total - 3, 0, 0
-                                         );
-          // DCCH SDU
-          sdu_lengths[num_sdus] = 0;
-
-          if (rlc_status.bytes_in_buffer > 0) {
-            LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
-                  module_idP, frameP, CC_id,
-                  TBS - ta_len - header_length_total - sdu_length_total - 3);
-            sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP,
-                                     rnti,
-                                     module_idP,
-                                     frameP,
-                                     ENB_FLAG_YES,
-                                     MBMS_FLAG_NO, DCCH + 1,
-                                     TBS, //not used
-                                     (char *) &dlsch_buffer[sdu_length_total], 0, 0
-                                                     );
-            T(T_ENB_MAC_UE_DL_SDU,
-              T_INT(module_idP),
-              T_INT(CC_id),
-              T_INT(rnti),
-              T_INT(frameP),
-              T_INT(subframeP),
-              T_INT(harq_pid),
-              T_INT(DCCH + 1),
-              T_INT(sdu_lengths[num_sdus]));
-            sdu_lcids[num_sdus] = DCCH1;
-            sdu_length_total += sdu_lengths[num_sdus];
-            eNB_UE_stats->lcid_sdu[num_sdus] = DCCH1;
-            eNB_UE_stats->sdu_length_tx[DCCH1] = sdu_lengths[num_sdus];
-            eNB_UE_stats->num_pdu_tx[DCCH1] += 1;
-            eNB_UE_stats->num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
-            header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
-            header_length_total += header_length_last;
-            num_sdus++;
-#ifdef DEBUG_eNB_SCHEDULER
-            LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :",
-                  module_idP,
-                  CC_id,
-                  sdu_lengths[num_sdus]);
-
-            for (j = 0; j < sdu_lengths[num_sdus]; ++j) {
-              LOG_T(MAC, "%x ",
-                    dlsch_buffer[j]);
-            }
-
-            LOG_T(MAC, "\n");
-#endif
-          }
-        }
-
-        // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list).
-        for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
-          // TODO: check if the lcid is active
-          LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
-                module_idP,
-                frameP,
-                lcid,
-                TBS,
-                TBS - ta_len - header_length_total - sdu_length_total - 3);
-
-          if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
-            rlc_status = mac_rlc_status_ind(module_idP,
-                                            rnti,
-                                            module_idP,
-                                            frameP,
-                                            subframeP,
-                                            ENB_FLAG_YES,
-                                            MBMS_FLAG_NO,
-                                            lcid,
-                                            TBS - ta_len - header_length_total - sdu_length_total - 3, 0, 0
-                                           );
-
-            if (rlc_status.bytes_in_buffer > 0) {
-              LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
-                    module_idP,
-                    frameP,
-                    TBS - ta_len - header_length_total - sdu_length_total - 3,
-                    lcid,
-                    header_length_total);
-              sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
-                                      rnti,
-                                      module_idP,
-                                      frameP,
-                                      ENB_FLAG_YES,
-                                      MBMS_FLAG_NO,
-                                      lcid,
-                                      TBS, //not used
-                                      (char *) &dlsch_buffer[sdu_length_total], 0, 0
-                                                      );
-              T(T_ENB_MAC_UE_DL_SDU,
-                T_INT(module_idP),
-                T_INT(CC_id),
-                T_INT(rnti),
-                T_INT(frameP),
-                T_INT(subframeP),
-                T_INT(harq_pid),
-                T_INT(lcid),
-                T_INT(sdu_lengths[num_sdus]));
-              LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
-                    module_idP,
-                    sdu_lengths[num_sdus],
-                    lcid);
-              sdu_lcids[num_sdus] = lcid;
-              sdu_length_total += sdu_lengths[num_sdus];
-              eNB_UE_stats->num_pdu_tx[lcid]++;
-              eNB_UE_stats->lcid_sdu[num_sdus] = lcid;
-              eNB_UE_stats->sdu_length_tx[lcid] = sdu_lengths[num_sdus];
-              eNB_UE_stats->num_bytes_tx[lcid] += sdu_lengths[num_sdus];
-              header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
-              header_length_total += header_length_last;
-              num_sdus++;
-              ue_sched_ctrl->uplane_inactivity_timer = 0;
-              // reset RRC inactivity timer after uplane activity
-              ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
-
-              if (ue_contextP != NULL) {
-                ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
-              } else {
-                LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n",
-                      module_idP,
-                      CC_id,
-                      rnti);
-              }
-            } // end if (rlc_status.bytes_in_buffer > 0)
-          } else {  // no TBS left
-            break;  // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--)
-          }
-        }
-
-        /* Last header does not have length field */
-        if (header_length_total) {
-          header_length_total -= header_length_last;
-          header_length_total++;
-        }
-
-        // there is at least one SDU or TA command
-        // if (num_sdus > 0 ){
-        if (ta_len + sdu_length_total + header_length_total > 0) {
-          // Now compute number of required RBs for total sdu length
-          // Assume RAH format 2
-          mcs = eNB_UE_stats->dlsch_mcs1;
-
-          if (mcs == 0) {
-            nb_rb = 4;    // don't let the TBS get too small
-          } else {
-            nb_rb = min_rb_unit[CC_id];
-          }
-
-          TBS = get_TBS_DL(mcs, nb_rb);
-
-          while (TBS < sdu_length_total + header_length_total + ta_len) {
-            nb_rb += min_rb_unit[CC_id];  //
-
-            if (nb_rb > nb_available_rb) {  // if we've gone beyond the maximum number of RBs
-              // (can happen if N_RB_DL is odd)
-              TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-                               nb_available_rb);
-              nb_rb = nb_available_rb;
-              break;
-            }
-
-            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-                             nb_rb);
-          }
-
-          if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
-            for (j = 0; j < N_RBG[CC_id]; ++j) {    // for indicating the rballoc for each sub-band
-              ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
-            }
-          } else {
-            nb_rb_temp = nb_rb;
-            j = 0;
-
-            while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
-              if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) {
-                ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
-
-                if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) {
-                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1;
-                } else {
-                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
-                }
-              }
-
-              j++;
-            }
-          }
-
-          // decrease mcs until TBS falls below required length
-          while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
-            mcs--;
-            TBS = get_TBS_DL(mcs,
-                             nb_rb);
-          }
-
-          // if we have decreased too much or we don't have enough RBs, increase MCS
-          while (TBS < sdu_length_total + header_length_total + ta_len &&
-                 ((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) {
-            mcs++;
-            TBS = get_TBS_DL(mcs,
-                             nb_rb);
-          }
-
-          LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n",
-                eNB_UE_stats->dlsch_mcs1,
-                mcs);
-#ifdef DEBUG_eNB_SCHEDULER
-          LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
-                module_idP,
-                CC_id,
-                mcs, TBS,
-                nb_rb);
-          // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
-          //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
-#endif
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n",
+          CC_id,
+          UE_id);
+    UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
+    eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
+    const rnti_t rnti = ue_template->rnti;
+
+    // If TDD
+    if (cc[CC_id].tdd_Config != NULL) {    //TDD
+      set_ue_dai(subframeP,
+                 UE_id,
+                 CC_id,
+                 cc[CC_id].tdd_Config->subframeAssignment,
+                 UE_info);
+      // update UL DAI after DLSCH scheduling
+      set_ul_DAI(module_idP,
+                 UE_id,
+                 CC_id,
+                 frameP,
+                 subframeP);
+    }
 
-          if (TBS - header_length_total - sdu_length_total - ta_len <= 2) {
-            padding = TBS - header_length_total - sdu_length_total - ta_len;
-            post_padding = 0;
-          } else {
-            padding = 0;
-            post_padding = 1;
-          }
+    ue_rrc_release(rnti);
+    check_ra_rnti_mui(module_idP, CC_id, frameP, subframeP, rnti);
 
-          offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
-                                         num_sdus,    //num_sdus
-                                         sdu_lengths,    //
-                                         sdu_lcids,
-                                         255,    // no drx
-                                         ta_update,    // timing advance
-                                         NULL,    // contention res id
-                                         padding,
-                                         post_padding);
+    if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0) { // no RBs allocated
+      LOG_D(MAC, "%d.%d: no RBs allocated for UE %d on CC_id %d\n",
+            frameP,
+            subframeP,
+            UE_id,
+            CC_id);
+      continue;
+    }
 
-          //#ifdef DEBUG_eNB_SCHEDULER
-          if (ta_update != 31) {
-            LOG_D(MAC,
-                  "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n",
-                  module_idP,
-                  frameP,
-                  UE_id,
-                  CC_id,
-                  sdu_length_total,
-                  num_sdus,
-                  sdu_lengths[0],
-                  sdu_lcids[0],
-                  offset,
-                  ta_update,
-                  padding,
-                  post_padding,
-                  mcs,
-                  TBS,
-                  nb_rb,
-                  header_length_total);
-          }
+    int dci_dl_pdu_idx = ue_sched_ctrl->pre_dci_dl_pdu_idx;
+    if (dci_dl_pdu_idx < 0) {
+      dci_dl_pdu_idx = CCE_try_allocate_dlsch(
+          module_idP, CC_id, subframeP, UE_id, ue_sched_ctrl->dl_cqi[CC_id]);
+      if (dci_dl_pdu_idx < 0) {
+        LOG_W(MAC, "%d.%d: Dropping Allocation for RNTI 0x%04x/UE %d\n",
+              frameP,
+              subframeP,
+              rnti,
+              UE_id);
+        continue;
+      }
+    }
 
-          //#endif
-#ifdef DEBUG_eNB_SCHEDULER
-          LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
+    /* verify it is the right UE */
+    nfapi_dl_config_request_pdu_t *dci = &dl_req->dl_config_pdu_list[dci_dl_pdu_idx];
+    nfapi_dl_config_request_pdu_t *dlsch = &dl_req->dl_config_pdu_list[dci_dl_pdu_idx + 1];
+    if (dci->pdu_type != NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE
+        || dci->dci_dl_pdu.dci_dl_pdu_rel8.rnti != rnti
+        || dlsch->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE
+        || dlsch->dlsch_pdu.dlsch_pdu_rel8.rnti != rnti) {
+      LOG_E(MAC, "illegal dl_config_pdu_list index %d for UE %d/RNTI %04x\n",
+            dci_dl_pdu_idx,
+            UE_id,
+            rnti);
+      continue;
+    }
 
-          for (i = 0; i < 16; i++) {
-            LOG_T(MAC, "%x.",
-                  dlsch_buffer[i]);
-          }
+    const int harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,
+                                                     frameP,
+                                                     subframeP);
+    const int round_DL = ue_sched_ctrl->round[CC_id][harq_pid];
+    eNB_UE_stats->crnti = rnti;
+    eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
+    eNB_UE_stats->harq_pid = harq_pid;
+    eNB_UE_stats->harq_round = round_DL;
+
+    if (eNB_UE_stats->rrc_status < RRC_RECONFIGURED) {
+      ue_sched_ctrl->uplane_inactivity_timer = 0;
+    }
 
-          LOG_T(MAC, "\n");
-#endif
-          // cycle through SDUs and place in dlsch_buffer
-          dlsch_pdu = &UE_list->DLSCH_pdu[CC_id][0][UE_id];
-          memcpy(&dlsch_pdu->payload[0][offset],
-                 dlsch_buffer,
-                 sdu_length_total);
-          // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
-
-          // fill remainder of DLSCH with 0
-          for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
-            dlsch_pdu->payload[0][offset + sdu_length_total + j] = 0;
-          }
+    LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
+          module_idP,
+          frameP,
+          UE_id,
+          CC_id,
+          rnti,
+          harq_pid,
+          round_DL,
+          ue_sched_ctrl->pre_nb_available_rbs[CC_id],
+          ue_sched_ctrl->dl_cqi[CC_id],
+          eNB_UE_stats->dlsch_mcs1,
+          eNB_UE_stats->rrc_status);
+
+    /* Process retransmission  */
+    if (round_DL != 8) {
+      // get freq_allocation
+      const int nb_rb = ue_template->nb_rb[harq_pid];
+      int TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid], nb_rb);
+      const uint32_t rbc = allocate_prbs_sub(
+          nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
+
+      if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
+        LOG_D(MAC,
+              "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
+              module_idP,
+              frameP,
+              CC_id,
+              UE_id);
+        continue;
+      }
 
-          trace_pdu(DIRECTION_DOWNLINK,
-                    (uint8_t *) dlsch_pdu->payload[0],
-                    TBS,
-                    module_idP,
-                    WS_C_RNTI,
-                    UE_RNTI(module_idP,
-                            UE_id),
-                    eNB->frame,
-                    eNB->subframe,
-                    0,
-                    0);
-          T(T_ENB_MAC_UE_DL_PDU_WITH_DATA,
-            T_INT(module_idP),
-            T_INT(CC_id),
-            T_INT(rnti),
-            T_INT(frameP),
-            T_INT(subframeP),
-            T_INT(harq_pid),
-            T_BUFFER(dlsch_pdu->payload[0],
-                     TBS));
-          ue_template->nb_rb[harq_pid] = nb_rb;
-          add_ue_dlsch_info(module_idP,
-                            CC_id,
-                            UE_id,
-                            subframeP,
-                            S_DL_SCHEDULED,
-                            rnti);
-          // store stats
-          eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total;
-          eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1;
-          eNB_UE_stats->rbs_used = nb_rb;
-          eNB_UE_stats->num_mac_sdu_tx = num_sdus;
-          eNB_UE_stats->total_rbs_used += nb_rb;
-          eNB_UE_stats->dlsch_mcs2 = mcs;
-          eNB_UE_stats->TBS = TBS;
-          eNB_UE_stats->overhead_bytes = TBS - sdu_length_total;
-          eNB_UE_stats->total_sdu_bytes += sdu_length_total;
-          eNB_UE_stats->total_pdu_bytes += TBS;
-          eNB_UE_stats->total_num_pdus += 1;
-
-          if (cc[CC_id].tdd_Config != NULL) { // TDD
-            ue_template->DAI++;
-            update_ul_dci(module_idP,
-                          CC_id,
-                          rnti,
-                          ue_template->DAI,
-                          subframeP);
-          }
+      /* CDRX */
+      ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
 
-          // do PUCCH power control
-          // this is the snr
-          // unit is not dBm, it's special from nfapi
-          // converting to dBm
-          snr = (5 * ue_sched_ctrl->pucch1_snr[CC_id] - 640) / 10;
-          target_snr = eNB->puCch10xSnr / 10;
-          // this assumes accumulated tpc
-          // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
-          int32_t framex10psubframe = ue_template->pucch_tpc_tx_frame * 10 + ue_template->pucch_tpc_tx_subframe;
-
-          if (framex10psubframe + 10 <= (frameP * 10) + subframeP ||  //normal case
-              (framex10psubframe > (frameP * 10) + subframeP && 10240 - framex10psubframe + (frameP * 10) + subframeP >= 10)) //frame wrap-around
-            if (ue_sched_ctrl->pucch1_cqi_update[CC_id] == 1) {
-              ue_sched_ctrl->pucch1_cqi_update[CC_id] = 0;
-              ue_template->pucch_tpc_tx_frame = frameP;
-              ue_template->pucch_tpc_tx_subframe = subframeP;
+      if (ue_sched_ctrl->cdrx_configured) {
+        ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission
 
-              if (snr > target_snr + 4) {
-                tpc = 0;  //-1
-              } else if (snr < target_snr - 4) {
-                tpc = 2;  //+1
-              } else {
-                tpc = 1;  //0
-              }
+        /*
+         * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop.
+         */
+        if (harq_pid == 0) {
+          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]);
+        }
+      }
 
-              LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d (normal case)\n",
-                    module_idP,
-                    frameP,
-                    subframeP,
-                    harq_pid,
-                    tpc,
-                    snr,
-                    target_snr);
-            } // Po_PUCCH has been updated
-            else {
-              tpc = 1;  //0
-            } // time to do TPC update
-          else {
-            tpc = 1;  //0
-          }
+      if (cc[CC_id].tdd_Config != NULL) {
+        ue_template->DAI++;
+        update_ul_dci(module_idP,
+                      CC_id,
+                      rnti,
+                      ue_template->DAI,
+                      subframeP);
+        LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
+              CC_id,
+              subframeP,
+              UE_id,
+              ue_template->DAI);
+      }
 
-          dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
-          memset((void *) dl_config_pdu,
-                 0,
-                 sizeof(nfapi_dl_config_request_pdu_t));
-          dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+      nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dci_dl_pdu_idx];
+      switch (get_tmode(module_idP, CC_id, UE_id)) {
+        case 1:
+        case 2:
+        case 7:
+        default:
+          LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n",
+                rnti);
           dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level =
-            get_aggregation(get_bw_index(module_idP,
-                                         CC_id),
-                            ue_sched_ctrl->dl_cqi[CC_id],
-                            format1);
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;    // equal to RS power
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc;    // dont adjust power when retransmitting
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - ue_template->oldNDI[harq_pid];
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
-          //deactivate second codeword
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
-
-          if (cc[CC_id].tdd_Config != NULL) {    //TDD
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ue_template->oldNDI[harq_pid];
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = ue_template->oldmcs1[harq_pid];
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round_DL & 3;
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rbc;
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
+
+          // TDD
+          if (cc[CC_id].tdd_Config != NULL) {
             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3;
-            LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
+            LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                   module_idP,
                   CC_id,
                   harq_pid,
-                  (ue_template->DAI - 1),
-                  mcs);
+                  round_DL,
+                  ue_template->DAI - 1,
+                  ue_template->oldmcs1[harq_pid]);
           } else {
-            LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
+            LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                   module_idP,
                   CC_id,
                   harq_pid,
-                  mcs);
+                  round_DL,
+                  ue_template->oldmcs1[harq_pid]);
           }
 
-          LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n",
-                dl_req->number_pdu);
-
-          if (!CCE_allocation_infeasible(module_idP,
-                                         CC_id,
-                                         1,
-                                         subframeP,
-                                         dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
-                                         rnti)) {
-            ue_sched_ctrl->round[CC_id][harq_pid] = 0;
-            dl_req->number_dci++;
-            dl_req->number_pdu++;
-            dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
-            eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP;
-            eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
-            /* CDRX */
-            ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
-
-            if (ue_sched_ctrl->cdrx_configured) {
-              ue_sched_ctrl->drx_inactivity_timer = 1; // restart drx inactivity timer when new transmission
-              ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission
-              /*
-               * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop.
-               */
-              VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) ue_sched_ctrl->drx_inactivity_timer);
-
-              if (harq_pid == 0) {
-                VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]);
-              }
-            }
-
-            // Toggle NDI for next time
-            LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
-                  CC_id,
-                  frameP,
-                  subframeP,
-                  UE_id,
-                  rnti,
-                  harq_pid,
-                  ue_template->oldNDI[harq_pid]);
-            ue_template->oldNDI[harq_pid] = 1 - ue_template->oldNDI[harq_pid];
-            ue_template->oldmcs1[harq_pid] = mcs;
-            ue_template->oldmcs2[harq_pid] = 0;
-            AssertFatal(ue_template->physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n");
-            AssertFatal(ue_template->physicalConfigDedicated->pdsch_ConfigDedicated != NULL,
-                        "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
-            fill_nfapi_dlsch_config(eNB,
-                                    dl_req,
-                                    TBS,
-                                    eNB->pdu_index[CC_id],
-                                    rnti,
-                                    0, // type 0 allocation from 7.1.6 in 36.213
-                                    0,  // virtual_resource_block_assignment_flag, unused here
-                                    0,  // resource_block_coding, to be filled in later
-                                    getQm(mcs),
-                                    0,  // redundancy version
-                                    1,  // transport blocks
-                                    0,  // transport block to codeword swap flag
-                                    cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
-                                    1,  // number of layers
-                                    1,  // number of subbands
-                                    //                       uint8_t codebook_index,
-                                    4,  // UE category capacity
-                                    ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
-                                    0,  // delta_power_offset for TM5
-                                    0,  // ngap
-                                    0,  // nprb
-                                    cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
-                                    0,  //number of PRBs treated as one subband, not used here
-                                    0); // number of beamforming vectors, not used here
-            eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
-                                        (frameP * 10) + subframeP,
-                                        TBS,
-                                        eNB->pdu_index[CC_id],
-                                        dlsch_pdu->payload[0]);
-            LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",
-                  eNB->pdu_index[CC_id]);
-            eNB->pdu_index[CC_id]++;
-            program_dlsch_acknak(module_idP,
-                                 CC_id,
-                                 UE_id,
-                                 frameP,
-                                 subframeP,
-                                 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
-          } else {
-            LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
-                  frameP,
-                  subframeP,
-                  UE_id,
-                  rnti);
-          }
-        } else {  // There is no data from RLC or MAC header, so don't schedule
-        }
+          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+          eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
+          eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
+          fill_nfapi_dlsch_config(&dl_req->dl_config_pdu_list[dci_dl_pdu_idx + 1],
+                                  TBS,
+                                  -1,   // retransmission, no pdu_index
+                                  rnti,
+                                  0,    // type 0 allocation from 7.1.6 in 36.213
+                                  0,    // virtual_resource_block_assignment_flag, unused here
+                                  rbc,  // resource_block_coding
+                                  getQm(ue_template->oldmcs1[harq_pid]),
+                                  round_DL & 3, // redundancy version
+                                  1,    // transport blocks
+                                  0,    // transport block to codeword swap flag
+                                  cc[CC_id].p_eNB == 1 ? 0 : 1,    // transmission_scheme
+                                  1,    // number of layers
+                                  1,    // number of subbands
+                                  //                      uint8_t codebook_index,
+                                  4,    // UE category capacity
+                                  ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
+                                  0,    // delta_power_offset for TM5
+                                  0,    // ngap
+                                  0,    // nprb
+                                  cc[CC_id].p_eNB == 1 ? 1 : 2,    // transmission mode
+                                  0,    //number of PRBs treated as one subband, not used here
+                                  0);   // number of beamforming vectors, not used here
+          LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
+                eNB->pdu_index[CC_id],
+                round_DL);
+          program_dlsch_acknak(module_idP,
+                               CC_id,
+                               UE_id,
+                               frameP,
+                               subframeP,
+                               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
+          // No TX request for retransmission (check if null request for FAPI)
       }
 
-      if (cc[CC_id].tdd_Config != NULL) {    // TDD
-        set_ul_DAI(module_idP,
-                   UE_id,
-                   CC_id,
-                   frameP,
-                   subframeP);
-      }
-    }     // UE_id loop
-  }       // CC_id loop
+      //eNB_UE_stats->dlsch_trials[round]++;
+      eNB_UE_stats->num_retransmission += 1;
+      eNB_UE_stats->rbs_used_retx = nb_rb;
+      eNB_UE_stats->total_rbs_used_retx += nb_rb;
+      eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
+    } else {
+      // Now check RLC information to compute number of required RBs
+      // get maximum TBS size for RLC request
+      const int nb_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id];
+      int TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb);
+      const uint32_t rbc = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
 
-  fill_DLSCH_dci(module_idP,
-                 frameP,
-                 subframeP,
-                 mbsfn_flag);
-  stop_meas(&eNB->schedule_dlsch);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
-                                          VCD_FUNCTION_OUT);
-}
+      // add the length for  all the control elements (timing adv, drx, etc) : header + payload
 
-//------------------------------------------------------------------------------
-void
-dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
-                                        int frameP,
-                                        sub_frame_t subframeP,
-                                        uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX])
-//------------------------------------------------------------------------------
-{
-  // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct.
-  int UE_id, CC_id, rbg, i;
-  int N_RB_DL, min_rb_unit, tm;
-  int owned, used;
-  eNB_MAC_INST *eNB = RC.mac[Mod_id];
-  int nb_mac_CC = RC.nb_mac_CC[Mod_id];
-  UE_list_t *UE_list = &eNB->UE_list;
-  slice_info_t *sli = &eNB->slice_info;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  COMMON_channels_t *cc;
-  int N_RBG[NFAPI_CC_MAX];
-  int slice_sorted_list[MAX_NUM_SLICES];
-  int slice_idx;
-  int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX];
-  int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES];
-  uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
-  uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB];
-  uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB];
-  uint8_t  (*MIMO_mode_indicator)[N_RBG_MAX];
-
-  // Initialize the free RBGs map
-  // free_rbgs_map[CC_id][rbg] = -1 if RBG is allocated,
-  // otherwise it contains the id of the slice it belongs to.
-  // (Information about slicing must be retained to deal with isolation).
-  // FIXME: This method does not consider RBGs that are free and belong to no slices
-  for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) {
-    cc = &eNB->common_channels[CC_id];
-    N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
-
-    for (rbg = 0; rbg < N_RBG[CC_id]; rbg++) {
-      for (i = 0; i < sli->n_dl; ++i) {
-        owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg];
-
-        if (owned) {
-          used = rballoc_sub[CC_id][rbg];
-          free_rbgs_map[CC_id][rbg] = used ? -1 : i;
-          break;
-        }
-      }
-    }
-  }
+      if (ue_sched_ctrl->ta_timer)
+        ue_sched_ctrl->ta_timer--;
 
-  // Find out which slices need other resources.
-  // FIXME: I don't think is really needed since we check nb_rbs_remaining later
-  for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) {
-    for (i = 0; i < sli->n_dl; i++) {
-      has_traffic[CC_id][i] = 0;
+      int ta_update = 31;
+      if (ue_sched_ctrl->ta_timer == 0) {
+        ta_update = ue_sched_ctrl->ta_update;
 
-      for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-        if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) {
-          has_traffic[CC_id][i] = 1;
-          break;
+        /* if we send TA then set timer to not send it for a while */
+        if (ta_update != 31) {
+          ue_sched_ctrl->ta_timer = 20;
         }
+
+        /* reset ta_update */
+        ue_sched_ctrl->ta_update = 31;
       }
-    }
-  }
 
-  slice_priority_sort(Mod_id,
-                      slice_sorted_list);
+      int ta_len = (ta_update != 31) ? 2 : 0;
 
-  // MULTIPLEXING
-  // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code
-  for (CC_id = 0; CC_id < nb_mac_CC; ++CC_id) {
-    N_RB_DL = to_prb(eNB->common_channels[CC_id].mib->message.dl_Bandwidth);
-    min_rb_unit = get_min_rb_unit(Mod_id,
-                                  CC_id);
 
-    for (i = 0; i < sli->n_dl; ++i) {
-      slice_idx = slice_sorted_list[i];
+      int num_sdus = 0;
+      uint16_t sdu_lengths[NB_RB_MAX];
+      int sdu_length_total = 0;
+      int header_length_total = 0;
+      int header_length_last = 0;
+      unsigned char sdu_lcids[NB_RB_MAX];
+      for (int i = 0; i < ue_sched_ctrl->dl_lc_num; ++i) {
+        const int lcid = ue_sched_ctrl->dl_lc_ids[i]; // will match DCCH, DCCH1, DTCH
 
-      if (has_traffic[CC_id][slice_idx] == 0) continue;
+        if (TBS - ta_len - header_length_total - sdu_length_total - 3 <= 0)
+          break;
 
-      // Build an ad-hoc allocation mask fo the slice
-      for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
-        if (free_rbgs_map[CC_id][rbg] == -1) {
-          // RBG is already allocated
-          allocation_mask[CC_id][rbg] = 0;
+        if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC!
           continue;
-        }
 
-        if (sli->dl[free_rbgs_map[CC_id][rbg]].isol == 1) {
-          // RBG belongs to an isolated slice
-          allocation_mask[CC_id][rbg] = 0;
-          continue;
+        LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+              module_idP,
+              frameP,
+              subframeP,
+              lcid,
+              CC_id,
+              TBS - ta_len - header_length_total - sdu_length_total - 3);
+
+        sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+                                                 rnti,
+                                                 module_idP,
+                                                 frameP,
+                                                 ENB_FLAG_YES,
+                                                 MBMS_FLAG_NO,
+                                                 lcid,
+                                                 TBS - ta_len - header_length_total - sdu_length_total - 3,
+                                                 (char *)&dlsch_buffer[sdu_length_total],
+                                                 0,
+                                                 0
+                                               );
+
+#ifdef DEBUG_eNB_SCHEDULER
+          LOG_T(MAC, "[eNB %d][%d] CC_id %d Got %d bytes :",
+                module_idP,
+                lcid,
+                CC_id,
+                sdu_lengths[num_sdus]);
+          for (int j = 0; j < sdu_lengths[num_sdus]; ++j)
+            LOG_T(MAC, "%x ", dlsch_buffer[sdu_length_total + j]);
+          LOG_T(MAC, "\n");
+#endif
+
+        T(T_ENB_MAC_UE_DL_SDU,
+          T_INT(module_idP),
+          T_INT(CC_id),
+          T_INT(rnti),
+          T_INT(frameP),
+          T_INT(subframeP),
+          T_INT(harq_pid),
+          T_INT(lcid),
+          T_INT(sdu_lengths[num_sdus]));
+        LOG_D(MAC, "[eNB %d][LC %d] CC_id %d Got %d bytes from RLC\n",
+              module_idP,
+              lcid,
+              CC_id,
+              sdu_lengths[num_sdus]);
+        sdu_lcids[num_sdus]               = lcid;
+        sdu_length_total                 += sdu_lengths[num_sdus];
+        eNB_UE_stats->num_pdu_tx[lcid]   += 1;
+        eNB_UE_stats->lcid_sdu[num_sdus]  = lcid;
+        eNB_UE_stats->sdu_length_tx[lcid] = sdu_lengths[num_sdus];
+        eNB_UE_stats->num_bytes_tx[lcid] += sdu_lengths[num_sdus];
+        header_length_last                = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
+        header_length_total              += header_length_last;
+        num_sdus                         += 1;
+
+        if (lcid >= 3) { // if this is DTCH
+            ue_sched_ctrl->uplane_inactivity_timer = 0;
+
+            // reset RRC inactivity timer after uplane activity
+            rrc_eNB_ue_context_t *ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
+            if (ue_contextP == NULL)
+              LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n",
+                    module_idP,
+                    CC_id,
+                    rnti);
+            ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
         }
+      }
 
-        // RBG is free
-        allocation_mask[CC_id][rbg] = 1;
+      /* Last header does not have length field */
+      if (header_length_total) {
+        header_length_total -= header_length_last;
+        header_length_total++;
       }
 
-      // Sort UE again
-      // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point)
-      // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it
-      sort_UEs(Mod_id,
-               slice_idx,
-               frameP,
-               subframeP);
-      nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining;
-      nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required;
-      MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator;
+      // there is at least one SDU or TA command
+      if (ta_len + sdu_length_total + header_length_total > 0) {
+        // Now compute number of required RBs for total sdu length
+        // Assume RAH format 2
+        int mcs = eNB_UE_stats->dlsch_mcs1;
+
+        /* TODO make special function */
+        // decrease mcs until TBS falls below required length
+        while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
+          mcs--;
+          TBS = get_TBS_DL(mcs, nb_rb);
+        }
+
+        // if we have decreased too much or we don't have enough RBs, increase MCS
+        while (TBS < sdu_length_total + header_length_total + ta_len && mcs < 28) {
+            // the second part of this condition is useless since dl_pow_off is
+            // always 2?
+            //&& ((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) {
+          mcs++;
+          TBS = get_TBS_DL(mcs,
+                           nb_rb);
+        }
 
-      // Allocation
-      for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-        ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-        tm = get_tmode(Mod_id,
-                       CC_id,
-                       UE_id);
+        LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d), TBS %d, nb_rb %d\n",
+              eNB_UE_stats->dlsch_mcs1, mcs, TBS, nb_rb);
 
-        for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
-          // FIXME: I think that some of these checks are redundant
-          if (allocation_mask[CC_id][rbg] == 0) continue;
+        int post_padding = TBS - header_length_total - sdu_length_total - ta_len > 2;
+        int padding = post_padding ? 0 : TBS - header_length_total - sdu_length_total - ta_len;
 
-          if (rballoc_sub[CC_id][rbg] != 0) continue;
+        const int offset = generate_dlsch_header((unsigned char *) UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+                                                 num_sdus,    //num_sdus
+                                                 sdu_lengths,    //
+                                                 sdu_lcids,
+                                                 255,    // no drx
+                                                 ta_update,    // timing advance
+                                                 NULL,    // contention res id
+                                                 padding,
+                                                 post_padding);
 
-          if (ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] != 0) continue;
+        //#ifdef DEBUG_eNB_SCHEDULER
+        if (ta_update != 31) {
+          LOG_D(MAC,
+                "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n",
+                module_idP,
+                frameP,
+                UE_id,
+                CC_id,
+                sdu_length_total,
+                num_sdus,
+                sdu_lengths[0],
+                sdu_lcids[0],
+                offset,
+                ta_update,
+                padding,
+                post_padding,
+                mcs,
+                TBS,
+                nb_rb,
+                header_length_total);
+        }
 
-          if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue;
+        //#endif
+#ifdef DEBUG_eNB_SCHEDULER
+        LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
 
-          if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue;
+        for (int i = 0; i < 16; i++) {
+          LOG_T(MAC, "%x.",
+                dlsch_buffer[i]);
+        }
 
-          if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue;
+        LOG_T(MAC, "\n");
+#endif
+        // cycle through SDUs and place in dlsch_buffer
+        DLSCH_PDU *dlsch_pdu = &UE_info->DLSCH_pdu[CC_id][0][UE_id];
+        memcpy(&dlsch_pdu->payload[0][offset], dlsch_buffer, sdu_length_total);
 
-          if ((rbg == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
-            // Allocating last, smaller RBG
-            if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) {
-              rballoc_sub[CC_id][rbg] = 1;
-              free_rbgs_map[CC_id][rbg] = -1;
-              ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1;
-              MIMO_mode_indicator[CC_id][rbg] = 1;
+        // fill remainder of DLSCH with 0
+        for (int j = 0; j < TBS - sdu_length_total - offset; j++) {
+          dlsch_pdu->payload[0][offset + sdu_length_total + j] = 0;
+        }
 
-              if (tm == 5) {
-                ue_sched_ctl->dl_pow_off[CC_id] = 1;
-              }
+        trace_pdu(DIRECTION_DOWNLINK,
+                  (uint8_t *) dlsch_pdu->payload[0],
+                  TBS,
+                  module_idP,
+                  WS_C_RNTI,
+                  UE_RNTI(module_idP,
+                          UE_id),
+                  eNB->frame,
+                  eNB->subframe,
+                  0,
+                  0);
+        T(T_ENB_MAC_UE_DL_PDU_WITH_DATA,
+          T_INT(module_idP),
+          T_INT(CC_id),
+          T_INT(rnti),
+          T_INT(frameP),
+          T_INT(subframeP),
+          T_INT(harq_pid),
+          T_BUFFER(dlsch_pdu->payload[0],
+                   TBS));
+        ue_template->nb_rb[harq_pid] = nb_rb;
+        // store stats
+        eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total;
+        eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1;
+        eNB_UE_stats->rbs_used = nb_rb;
+        eNB_UE_stats->num_mac_sdu_tx = num_sdus;
+        eNB_UE_stats->total_rbs_used += nb_rb;
+        eNB_UE_stats->dlsch_mcs2 = mcs;
+        eNB_UE_stats->TBS = TBS;
+        eNB_UE_stats->overhead_bytes = TBS - sdu_length_total;
+        eNB_UE_stats->total_sdu_bytes += sdu_length_total;
+        eNB_UE_stats->total_pdu_bytes += TBS;
+        eNB_UE_stats->total_num_pdus += 1;
+
+        if (cc[CC_id].tdd_Config != NULL) { // TDD
+          ue_template->DAI++;
+          update_ul_dci(module_idP,
+                        CC_id,
+                        rnti,
+                        ue_template->DAI,
+                        subframeP);
+        }
 
-              nb_rbs_remaining[CC_id][UE_id] -= (min_rb_unit - 1);
-              ue_sched_ctl->pre_nb_available_rbs[CC_id] += (min_rb_unit - 1);
+        // do PUCCH power control
+        // this is the snr
+        // unit is not dBm, it's special from nfapi
+        // converting to dBm
+        int snr = (5 * ue_sched_ctrl->pucch1_snr[CC_id] - 640) / 10;
+        int target_snr = eNB->puCch10xSnr / 10;
+        // this assumes accumulated tpc
+        // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
+        int32_t framex10psubframe = ue_template->pucch_tpc_tx_frame * 10 + ue_template->pucch_tpc_tx_subframe;
+
+        int tpc = 1;
+        if (framex10psubframe + 10 <= (frameP * 10) + subframeP ||  //normal case
+            (framex10psubframe > (frameP * 10) + subframeP && 10240 - framex10psubframe + (frameP * 10) + subframeP >= 10)) { //frame wrap-around
+          if (ue_sched_ctrl->pucch1_cqi_update[CC_id] == 1) {
+            ue_sched_ctrl->pucch1_cqi_update[CC_id] = 0;
+            ue_template->pucch_tpc_tx_frame = frameP;
+            ue_template->pucch_tpc_tx_subframe = subframeP;
+
+            if (snr > target_snr + 4) {
+              tpc = 0;  //-1
+            } else if (snr < target_snr - 4) {
+              tpc = 2;  //+1
+            } else {
+              tpc = 1;  //0
             }
-          } else {
-            // Allocating a standard-sized RBG
-            if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) {
-              rballoc_sub[CC_id][rbg] = 1;
-              free_rbgs_map[CC_id][rbg] = -1;
-              ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1;
-              MIMO_mode_indicator[CC_id][rbg] = 1;
-
-              if (tm == 5) {
-                ue_sched_ctl->dl_pow_off[CC_id] = 1;
-              }
 
-              nb_rbs_remaining[CC_id][UE_id] -= min_rb_unit;
-              ue_sched_ctl->pre_nb_available_rbs[CC_id] += min_rb_unit;
-            }
-          }
+            LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d (normal case)\n",
+                  module_idP,
+                  frameP,
+                  subframeP,
+                  harq_pid,
+                  tpc,
+                  snr,
+                  target_snr);
+          } // Po_PUCCH has been updated
         }
-      }
-    }
-  }
 
-  return;
-}
+        nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dci_dl_pdu_idx];
+        dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;    // equal to RS power
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc;    // dont adjust power when retransmitting
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - ue_template->oldNDI[harq_pid];
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
+        //deactivate second codeword
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rbc;
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
+
+        if (cc[CC_id].tdd_Config != NULL) {    //TDD
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3;
+          LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
+                module_idP,
+                CC_id,
+                harq_pid,
+                (ue_template->DAI - 1),
+                mcs);
+        } else {
+          LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
+                module_idP,
+                CC_id,
+                harq_pid,
+                mcs);
+        }
 
-//------------------------------------------------------------------------------
-void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP)
-//------------------------------------------------------------------------------
-{
-  // int UE_id;
-  int CC_id, i;
-  // UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
-  //UE_sched_ctrl *ue_sched_ctl;
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    for (i = 0; i < sli->n_dl; i++) {
-      // Sort UE again
-      // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it
-      sort_UEs(Mod_id,
-               (uint8_t)i,
-               frameP,
-               subframeP);
-      /*
-      for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-        //ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-        // TODO: Do something here
-        // ue_sched_ctl->pre_nb_available_rbs[CC_id];
+        LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n",
+              dl_req->number_pdu);
+
+        ue_sched_ctrl->round[CC_id][harq_pid] = 0;
+        dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+        eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP;
+        eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
+        /* CDRX */
+        ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
+
+        if (ue_sched_ctrl->cdrx_configured) {
+          ue_sched_ctrl->drx_inactivity_timer = 1; // restart drx inactivity timer when new transmission
+          ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission
+          /*
+           * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop.
+           */
+          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) ue_sched_ctrl->drx_inactivity_timer);
+
+          if (harq_pid == 0) {
+            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]);
+          }
+        }
+
+        // Toggle NDI for next time
+        LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
+              CC_id,
+              frameP,
+              subframeP,
+              UE_id,
+              rnti,
+              harq_pid,
+              ue_template->oldNDI[harq_pid]);
+        ue_template->oldNDI[harq_pid] = 1 - ue_template->oldNDI[harq_pid];
+        ue_template->oldmcs1[harq_pid] = mcs;
+        ue_template->oldmcs2[harq_pid] = 0;
+        AssertFatal(ue_template->physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n");
+        AssertFatal(ue_template->physicalConfigDedicated->pdsch_ConfigDedicated != NULL,
+                    "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
+        fill_nfapi_dlsch_config(&dl_req->dl_config_pdu_list[dci_dl_pdu_idx + 1],
+                                TBS,
+                                eNB->pdu_index[CC_id],
+                                rnti,
+                                0, // type 0 allocation from 7.1.6 in 36.213
+                                0,  // virtual_resource_block_assignment_flag, unused here
+                                rbc,// resource_block_coding
+                                getQm(mcs),
+                                0,  // redundancy version
+                                1,  // transport blocks
+                                0,  // transport block to codeword swap flag
+                                cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
+                                1,  // number of layers
+                                1,  // number of subbands
+                                //                       uint8_t codebook_index,
+                                4,  // UE category capacity
+                                ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
+                                0,  // delta_power_offset for TM5
+                                0,  // ngap
+                                0,  // nprb
+                                cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
+                                0,  //number of PRBs treated as one subband, not used here
+                                0); // number of beamforming vectors, not used here
+        eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
+                                    (frameP * 10) + subframeP,
+                                    TBS,
+                                    eNB->pdu_index[CC_id],
+                                    dlsch_pdu->payload[0]);
+        LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",
+              eNB->pdu_index[CC_id]);
+        eNB->pdu_index[CC_id]++;
+        program_dlsch_acknak(module_idP,
+                             CC_id,
+                             UE_id,
+                             frameP,
+                             subframeP,
+                             dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
       }
-      */
     }
-  }
+  }     // UE_id loop
+  stop_meas(&eNB->schedule_dlsch);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
+                                          VCD_FUNCTION_OUT);
 }
 
 //------------------------------------------------------------------------------
@@ -1886,7 +1234,7 @@ schedule_ue_spec_br(module_id_t module_idP,
   unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
   eNB_MAC_INST *mac = RC.mac[module_idP];
   COMMON_channels_t *cc = mac->common_channels;
-  UE_list_t *UE_list = &mac->UE_list;
+  UE_info_t *UE_info = &mac->UE_info;
   UE_TEMPLATE *UE_template = NULL;
   UE_sched_ctrl_t *ue_sched_ctl = NULL;
   nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL;
@@ -1951,7 +1299,7 @@ schedule_ue_spec_br(module_id_t module_idP,
     }
   }
 
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+  for (UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
     int harq_pid = 0;
     rnti = UE_RNTI(module_idP, UE_id);
 
@@ -1959,8 +1307,8 @@ schedule_ue_spec_br(module_id_t module_idP,
       continue;
     }
 
-    ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]);
-    UE_template  = &(UE_list->UE_template[CC_id][UE_id]);
+    ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
+    UE_template  = &UE_info->UE_template[CC_id][UE_id];
 
     if (UE_template->rach_resource_type == 0) {
       continue;
@@ -2031,7 +1379,6 @@ schedule_ue_spec_br(module_id_t module_idP,
                                           ENB_FLAG_YES,
                                           MBMS_FLAG_NO,
                                           DCCH,
-                                          (TBS-ta_len-header_len_dcch),
                                           0,
                                           0); // transport block set size
           sdu_lengths[0] = 0;
@@ -2049,7 +1396,7 @@ schedule_ue_spec_br(module_id_t module_idP,
                                               ENB_FLAG_YES,
                                               MBMS_FLAG_NO,
                                               DCCH,
-                                              TBS, //not used
+                                              TBS-ta_len-header_len_dcch,
                                               (char *)&dlsch_buffer[0],
                                               0,
                                               0);
@@ -2068,8 +1415,8 @@ schedule_ue_spec_br(module_id_t module_idP,
                   sdu_lengths[0]);
             sdu_length_total = sdu_lengths[0];
             sdu_lcids[0] = DCCH;
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1;
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0];
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1;
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0];
             num_sdus = 1;
           } else {
             header_len_dcch = 0;
@@ -2087,7 +1434,6 @@ schedule_ue_spec_br(module_id_t module_idP,
                                           ENB_FLAG_YES,
                                           MBMS_FLAG_NO,
                                           DCCH + 1,
-                                          (TBS-ta_len-header_len_dcch-sdu_length_total),
                                           0,
                                           0); // transport block set size less allocations for timing advance and DCCH SDU
           sdu_lengths[num_sdus] = 0;
@@ -2105,7 +1451,7 @@ schedule_ue_spec_br(module_id_t module_idP,
                                      ENB_FLAG_YES,
                                      MBMS_FLAG_NO,
                                      DCCH+1,
-                                     TBS, //not used
+                                     TBS-ta_len-header_len_dcch-sdu_length_total,
                                      (char *)&dlsch_buffer[sdu_length_total],
                                      0,
                                      0);
@@ -2121,8 +1467,8 @@ schedule_ue_spec_br(module_id_t module_idP,
             sdu_lcids[num_sdus] = DCCH1;
             sdu_length_total += sdu_lengths[num_sdus];
             header_len_dcch += 2;
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1;
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1;
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
             num_sdus++;
           }
         }
@@ -2152,7 +1498,6 @@ schedule_ue_spec_br(module_id_t module_idP,
                                             ENB_FLAG_YES,
                                             MBMS_FLAG_NO,
                                             lcid,
-                                            TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch,
                                             0,
                                             0);
 
@@ -2183,7 +1528,7 @@ schedule_ue_spec_br(module_id_t module_idP,
                                       ENB_FLAG_YES,
                                       MBMS_FLAG_NO,
                                       lcid,
-                                      TBS, //not used
+                                      TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch,
                                       (char *) &dlsch_buffer[sdu_length_total],
                                       0,
                                       0);
@@ -2274,7 +1619,7 @@ schedule_ue_spec_br(module_id_t module_idP,
             post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header
           }
 
-          offset = generate_dlsch_header((unsigned char *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+          offset = generate_dlsch_header((unsigned char *)UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                                          num_sdus,              //num_sdus
                                          sdu_lengths,  //
                                          sdu_lcids,
@@ -2307,15 +1652,15 @@ schedule_ue_spec_br(module_id_t module_idP,
           }
 
           /* Cycle through SDUs and place in dlsch_buffer */
-          memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total);
+          memcpy(&UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total);
 
           /* Fill remainder of DLSCH with random data */
           for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
-            UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff);
+            UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff);
           }
 
           trace_pdu(DIRECTION_DOWNLINK,
-                    (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+                    (uint8_t *)UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                     TBS,
                     module_idP,
                     3,
@@ -2331,7 +1676,7 @@ schedule_ue_spec_br(module_id_t module_idP,
             T_INT(frameP),
             T_INT(subframeP),
             T_INT(harq_pid),
-            T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
+            T_BUFFER(UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
           /* Do PUCCH power control */
           /* This is the snr */
           /* unit is not dBm, it's special from nfapi, convert to dBm */
@@ -2339,15 +1684,15 @@ schedule_ue_spec_br(module_id_t module_idP,
           target_snr = mac->puCch10xSnr / 10;
           /* This assumes accumulated tpc */
           /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */
-          int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
+          int32_t framex10psubframe = UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
 
           if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
               ((framex10psubframe > (frameP * 10 + subframeP)) &&
                (((10240 - framex10psubframe +frameP * 10 + subframeP) >= 10)))) { // frame wrap-around
             if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) {
               ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
-              UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP;
-              UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP;
+              UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP;
+              UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP;
 
               if (snr > target_snr + 4) {
                 tpc = 0; //-1
@@ -2481,7 +1826,7 @@ schedule_ue_spec_br(module_id_t module_idP,
       TX_req->pdu_index = mac->pdu_index[CC_id]++;
       TX_req->num_segments = 1;
       TX_req->segments[0].segment_length = TX_req->pdu_length;
-      TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0];
+      TX_req->segments[0].segment_data = mac->UE_info.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0];
       mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
       ackNAK_absSF = absSF + 4;
       ul_req = &mac->UL_req_tmp[CC_id][ackNAK_absSF % 10].ul_config_request_body;
@@ -2515,9 +1860,9 @@ schedule_ue_spec_br(module_id_t module_idP,
         T_INT (frameP),
         T_INT (subframeP),
         T_INT (0 /* harq_pid always 0? */ ),
-        T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length));
+        T_BUFFER (&mac->UE_info.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length));
       trace_pdu(1,
-                (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0],
+                (uint8_t *) mac->UE_info.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0],
                 TX_req->pdu_length,
                 UE_id,
                 3,
@@ -2530,101 +1875,6 @@ schedule_ue_spec_br(module_id_t module_idP,
   } // end loop on UE_id
 }
 
-//------------------------------------------------------------------------------
-void
-fill_DLSCH_dci(module_id_t module_idP,
-               frame_t frameP,
-               sub_frame_t subframeP,
-               int *mbsfn_flagP)
-//------------------------------------------------------------------------------
-{
-  // loop over all allocated UEs and compute frequency allocations for PDSCH
-  int UE_id = -1;
-  uint8_t /* first_rb, */ nb_rb = 3;
-  rnti_t rnti;
-  //unsigned char *vrb_map;
-  uint8_t rballoc_sub[25];
-  //uint8_t number_of_subbands=13;
-  //unsigned char round;
-  unsigned char harq_pid;
-  int i;
-  int CC_id;
-  eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
-  int N_RBG;
-  int N_RB_DL;
-  COMMON_channels_t *cc;
-  eNB_DLSCH_INFO *dlsch_info;
-  UE_TEMPLATE *ue_template;
-  start_meas(&eNB->fill_DLSCH_dci);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
-                                          VCD_FUNCTION_IN);
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
-    LOG_D(MAC, "Doing fill DCI for CC_id %d\n",
-          CC_id);
-
-    if (mbsfn_flagP[CC_id] > 0)
-      continue;
-
-    cc = &eNB->common_channels[CC_id];
-    N_RBG = to_rbg(cc->mib->message.dl_Bandwidth);
-    N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
-
-    // UE specific DCIs
-    for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-      dlsch_info = &eNB_dlsch_info[module_idP][CC_id][UE_id];
-      LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n",
-            CC_id,
-            UE_id,
-            dlsch_info->status);
-
-      if (dlsch_info->status == S_DL_SCHEDULED) {
-        // clear scheduling flag
-        dlsch_info->status = S_DL_WAITING;
-        rnti = UE_RNTI(module_idP, UE_id);
-        harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,
-                                               subframeP);
-        ue_template = &UE_list->UE_template[CC_id][UE_id];
-        nb_rb = ue_template->nb_rb[harq_pid];
-
-        /// Synchronizing rballoc with rballoc_sub
-        for (i = 0; i < N_RBG; i++) {
-          rballoc_sub[i] = ue_template->rballoc_subband[harq_pid][i];
-        }
-
-        nfapi_dl_config_request_body_t *dl_config_request_body = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body;
-        nfapi_dl_config_request_pdu_t *dl_config_pdu;
-
-        for (i = 0; i < dl_config_request_body->number_pdu; i++) {
-          dl_config_pdu = &dl_config_request_body->dl_config_pdu_list[i];
-
-          if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE &&
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti &&
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1) {
-            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,
-                N_RB_DL,
-                N_RBG,
-                rballoc_sub);
-            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
-          } else if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE &&
-                     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti &&
-                     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0) {
-            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,
-                N_RB_DL,
-                N_RBG,
-                rballoc_sub);
-          }
-        }
-      }
-    }
-  }
-
-  stop_meas(&eNB->fill_DLSCH_dci);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
-                                          VCD_FUNCTION_OUT);
-}
-
 //------------------------------------------------------------------------------
 unsigned char *get_dlsch_sdu(module_id_t module_idP,
                              int CC_id,
@@ -2661,7 +1911,7 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
           CC_id,
           rntiP,
           UE_id);
-    return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]);
+    return ((unsigned char *) &eNB->UE_info.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]);
   }
 
   LOG_E(MAC, "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n",
@@ -2706,61 +1956,61 @@ set_ue_dai(sub_frame_t subframeP,
            int UE_id,
            uint8_t CC_id,
            uint8_t tdd_config,
-           UE_list_t *UE_list)
+           UE_info_t *UE_info)
 //------------------------------------------------------------------------------
 {
   switch (tdd_config) {
     case 0:
       if (subframeP == 0 || subframeP == 1 || subframeP == 3 || subframeP == 5 || subframeP == 6 || subframeP == 8) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 1:
       if (subframeP == 0 || subframeP == 4 || subframeP == 5 || subframeP == 9) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 2:
       if (subframeP == 4 || subframeP == 5) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 3:
       if (subframeP == 5 || subframeP == 7 || subframeP == 9) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 4:
       if (subframeP == 0 || subframeP == 6) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 5:
       if (subframeP == 9) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     case 6:
       if (subframeP == 0 || subframeP == 1 || subframeP == 5 || subframeP == 6 || subframeP == 9) {
-        UE_list->UE_template[CC_id][UE_id].DAI = 0;
+        UE_info->UE_template[CC_id][UE_id].DAI = 0;
       }
 
       break;
 
     default:
-      UE_list->UE_template[CC_id][UE_id].DAI = 0;
+      UE_info->UE_template[CC_id][UE_id].DAI = 0;
       LOG_I(MAC, "unknown TDD config %d\n",
             tdd_config);
       break;
@@ -3158,37 +2408,3 @@ schedule_PCH(module_id_t module_idP,
   stop_meas(&eNB->schedule_pch);
   return;
 }
-
-static int
-slice_priority_compare(const void *_a,
-                       const void *_b,
-                       void *_c) {
-  const int slice_id1 = *(const int *) _a;
-  const int slice_id2 = *(const int *) _b;
-  const module_id_t Mod_id = *(int *)  _c;
-  const slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
-
-  if (sli->dl[slice_id1].prio > sli->dl[slice_id2].prio) {
-    return -1;
-  }
-
-  return 1;
-}
-
-void
-slice_priority_sort(module_id_t Mod_id,
-                    int slice_list[MAX_NUM_SLICES]) {
-  int i;
-  int n_dl = RC.mac[Mod_id]->slice_info.n_dl;
-
-  for (i = 0; i < n_dl; i++) {
-    slice_list[i] = i;
-  }
-
-  qsort_r(slice_list,
-          n_dl,
-          sizeof(int),
-          slice_priority_compare,
-          &Mod_id);
-  return;
-}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
index 260d8a7417c..00fd40109db 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
@@ -120,7 +120,7 @@ void pre_scd_nb_rbs_required(    module_id_t     module_idP,
   if(N_RB_DL==100) step_size=4;
 
   memset(nb_rbs_required, 0, sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
-  UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[module_idP]->UE_info;
 
   for (UE_id = 0; UE_id <NUMBER_OF_UE_MAX; UE_id++) {
     if (pre_scd_activeUE[UE_id] != TRUE)
@@ -134,7 +134,7 @@ void pre_scd_nb_rbs_required(    module_id_t     module_idP,
     for (lc_id = DCCH; lc_id <= DTCH; lc_id++) {
       rlc_status =
         mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP,
-                           ENB_FLAG_YES, MBMS_FLAG_NO, lc_id, 0,0, 0
+                           ENB_FLAG_YES, MBMS_FLAG_NO, lc_id, 0, 0
                           );
       UE_template.dl_buffer_total += rlc_status.bytes_in_buffer; //storing the total dlsch buffer
     }
@@ -144,7 +144,7 @@ void pre_scd_nb_rbs_required(    module_id_t     module_idP,
     // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
     //update CQI information across component carriers
     eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id];
-    eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
+    eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
 
     if (UE_template.dl_buffer_total > 0) {
       nb_rbs_required[CC_id][UE_id] = search_rbs_required(eNB_UE_stats->dlsch_mcs1, UE_template.dl_buffer_total, N_RB_DL, step_size);
@@ -175,7 +175,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
   DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]) {
   eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
   COMMON_channels_t              *cc       = eNB->common_channels;
-  UE_list_t                      *UE_list  = &eNB->UE_list;
+  UE_info_t                      *UE_info  = &eNB->UE_info;
   UE_sched_ctrl_t                  *ue_sched_ctl;
   uint8_t                        CC_id;
   int                            UE_id;
@@ -208,7 +208,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
     DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
 
     for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
-      if (UE_list->active[UE_id] == FALSE) {
+      if (UE_info->active[UE_id] == FALSE) {
         continue;
       }
 
@@ -222,12 +222,12 @@ void dlsch_scheduler_pre_ue_select_fairRR(
         continue;
       }
 
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
       harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP,subframeP);
       round = ue_sched_ctl->round[CC_id][harq_pid];
 
       if (round != 8) {  // retransmission
-        if(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0) {
+        if(UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0) {
           continue;
         }
 
@@ -266,7 +266,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type         = (format_flag == 0)?2:1;
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
           DL_req->number_pdu++;
-          nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+          nb_rbs_required[CC_id][UE_id] = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
           // Insert DLSCH(retransmission) UE into selected UE list
           dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
           dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_RETRANS;
@@ -284,7 +284,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
                         UE_id,
                         CC_id,
                         cc[CC_id].tdd_Config->subframeAssignment,
-                        UE_list);
+                        UE_info);
             // update UL DAI after DLSCH scheduling
             set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
           }
@@ -324,7 +324,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
         break;
       }
 
-      if (UE_list->active[UE_id] == FALSE) {
+      if (UE_info->active[UE_id] == FALSE) {
         continue;
       }
 
@@ -337,7 +337,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
         continue;
       }
 
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
 
       for(i = 0; i<dlsch_ue_select[CC_id].ue_num; i++) {
         if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id) {
@@ -408,7 +408,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
                         UE_id,
                         CC_id,
                         cc[CC_id].tdd_Config->subframeAssignment,
-                        UE_list);
+                        UE_info);
             // update UL DAI after DLSCH scheduling
             set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
           }
@@ -448,7 +448,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
         break;
       }
 
-      if (UE_list->active[UE_id] == FALSE) {
+      if (UE_info->active[UE_id] == FALSE) {
         continue;
       }
 
@@ -461,7 +461,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
         continue;
       }
 
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
 
       for(i = 0; i<dlsch_ue_select[CC_id].ue_num; i++) {
         if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id) {
@@ -532,7 +532,7 @@ void dlsch_scheduler_pre_ue_select_fairRR(
                         UE_id,
                         CC_id,
                         cc[CC_id].tdd_Config->subframeAssignment,
-                        UE_list);
+                        UE_info);
             // update UL DAI after DLSCH scheduling
             set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
           }
@@ -558,7 +558,331 @@ void dlsch_scheduler_pre_ue_select_fairRR(
   return;
 }
 
+void dlsch_scheduler_pre_processor_reset_fairRR(
+    module_id_t module_idP,
+    frame_t frameP,
+    sub_frame_t subframeP,
+    int min_rb_unit[NFAPI_CC_MAX],
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
+    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) {
+  int UE_id;
+  uint8_t CC_id;
+  int i, j;
+  UE_info_t *UE_info;
+  UE_sched_ctrl_t *ue_sched_ctl;
+  int N_RB_DL, RBGsize, RBGsize_last;
+  int N_RBG[NFAPI_CC_MAX];
+  rnti_t rnti;
+  uint8_t *vrb_map;
+  COMMON_channels_t *cc;
+
+  //
+  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
+    // initialize harq_pid and round
+    cc = &RC.mac[module_idP]->common_channels[CC_id];
+    N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
+    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
+
+    for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) {
+      UE_info = &RC.mac[module_idP]->UE_info;
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
+      rnti = UE_RNTI(module_idP, UE_id);
+
+      if (rnti == NOT_A_RNTI)
+        continue;
+
+      if (UE_info->active[UE_id] != TRUE)
+        continue;
+
+      LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti);
+
+      // initialize harq_pid and round
+      if (ue_sched_ctl->ta_timer)
+        ue_sched_ctl->ta_timer--;
+
+      /*
+         eNB_UE_stats *eNB_UE_stats;
+
+         if (eNB_UE_stats == NULL)
+         return;
+
+
+         mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,
+         frameP,subframeP,
+         &ue_sched_ctl->harq_pid[CC_id],
+         &ue_sched_ctl->round[CC_id],
+         openair_harq_DL);
+
+
+         if (ue_sched_ctl->ta_timer == 0) {
+
+         // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
+
+         ue_sched_ctl->ta_timer = 20;  // wait 20 subframes before taking TA measurement from PHY
+         switch (N_RB_DL) {
+         case 6:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update;
+         break;
+
+         case 15:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2;
+         break;
+
+         case 25:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4;
+         break;
+
+         case 50:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8;
+         break;
 
+         case 75:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12;
+         break;
+
+         case 100:
+         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16;
+         break;
+         }
+         // clear the update in case PHY does not have a new measurement after timer expiry
+         eNB_UE_stats->timing_advance_update =  0;
+         }
+         else {
+         ue_sched_ctl->ta_timer--;
+         ue_sched_ctl->ta_update =0; // don't trigger a timing advance command
+         }
+
+
+         if (UE_id==0) {
+         VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update);
+         }
+       */
+      nb_rbs_required[CC_id][UE_id] = 0;
+      ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
+      ue_sched_ctl->dl_pow_off[CC_id] = 2;
+
+      for (i = 0; i < N_RBG[CC_id]; i++) {
+        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
+      }
+    }
+
+    N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
+
+    switch (N_RB_DL) {
+      case 6:
+        RBGsize = 1;
+        RBGsize_last = 1;
+        break;
+
+      case 15:
+        RBGsize = 2;
+        RBGsize_last = 1;
+        break;
+
+      case 25:
+        RBGsize = 2;
+        RBGsize_last = 1;
+        break;
+
+      case 50:
+        RBGsize = 3;
+        RBGsize_last = 2;
+        break;
+
+      case 75:
+        RBGsize = 4;
+        RBGsize_last = 3;
+        break;
+
+      case 100:
+        RBGsize = 4;
+        RBGsize_last = 4;
+        break;
+
+      default:
+        AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
+    }
+
+    vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
+
+    // Initialize Subbands according to VRB map
+    for (i = 0; i < N_RBG[CC_id]; i++) {
+      int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize;
+
+      // for SI-RNTI,RA-RNTI and P-RNTI allocations
+      for (j = 0; j < rb_size; j++) {
+        if (vrb_map[j + (i*RBGsize)] != 0) {
+          rballoc_sub[CC_id][i] = 1;
+          LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize));
+          break;
+        }
+      }
+
+      //LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",
+      //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]);
+      MIMO_mode_indicator[CC_id][i] = 2;
+    }
+  }
+}
+
+// This function returns the estimated number of RBs required by each UE for downlink scheduling
+void assign_rbs_required_fairRR(
+    module_id_t Mod_id,
+    frame_t frameP,
+    sub_frame_t subframe,
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) {
+  uint16_t TBS = 0;
+  int UE_id, n, i, j, CC_id, pCCid, tmp;
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+  eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
+  int N_RB_DL;
+
+  // clear rb allocations across all CC_id
+  for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
+    if (UE_info->active[UE_id] != TRUE)
+      continue;
+
+    pCCid = UE_PCCID(Mod_id, UE_id);
+
+    // update CQI information across component carriers
+    for (n = 0; n < UE_info->numactiveCCs[UE_id]; n++) {
+      CC_id = UE_info->ordered_CCids[n][UE_id];
+      eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
+      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
+    }
+
+    // provide the list of CCs sorted according to MCS
+    for (i = 0; i < UE_info->numactiveCCs[UE_id]; ++i) {
+      eNB_UE_stats_i =
+          &UE_info->eNB_UE_stats[UE_info->ordered_CCids[i][UE_id]][UE_id];
+
+      for (j = i + 1; j < UE_info->numactiveCCs[UE_id]; j++) {
+        DevAssert(j < NFAPI_CC_MAX);
+        eNB_UE_stats_j =
+            &UE_info->eNB_UE_stats[UE_info->ordered_CCids[j][UE_id]][UE_id];
+
+        if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) {
+          tmp = UE_info->ordered_CCids[i][UE_id];
+          UE_info->ordered_CCids[i][UE_id] = UE_info->ordered_CCids[j][UE_id];
+          UE_info->ordered_CCids[j][UE_id] = tmp;
+        }
+      }
+    }
+
+    if (UE_info->UE_template[pCCid][UE_id].dl_buffer_total > 0) {
+      LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
+
+      for (i = 0; i < UE_info->numactiveCCs[UE_id]; i++) {
+        CC_id = UE_info->ordered_CCids[i][UE_id];
+        eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
+        const int min_rb_unit = get_min_rb_unit(Mod_id, CC_id);
+
+        if (eNB_UE_stats->dlsch_mcs1 == 0) {
+          nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
+        } else {
+          nb_rbs_required[CC_id][UE_id] = min_rb_unit;
+        }
+
+        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]);
+        LOG_D(MAC,
+              "[preprocessor] start RB assignement for UE %d CC_id %d dl "
+              "buffer %d (RB unit %d, MCS %d, TBS %d) \n",
+              UE_id,
+              CC_id,
+              UE_info->UE_template[pCCid][UE_id].dl_buffer_total,
+              nb_rbs_required[CC_id][UE_id],
+              eNB_UE_stats->dlsch_mcs1,
+              TBS);
+        N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+
+        /* calculating required number of RBs for each UE */
+        while (TBS < UE_info->UE_template[pCCid][UE_id].dl_buffer_total) {
+          nb_rbs_required[CC_id][UE_id] += min_rb_unit;
+
+          if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) {
+            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, N_RB_DL);
+            nb_rbs_required[CC_id][UE_id] = N_RB_DL;
+            break;
+          }
+
+          TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
+                           nb_rbs_required[CC_id][UE_id]);
+        } // end of while
+
+        LOG_D(MAC,
+              "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d,  nb_required RB "
+              "%d (TBS %d, mcs %d)\n",
+              Mod_id,
+              frameP,
+              UE_id,
+              CC_id,
+              min_rb_unit,
+              nb_rbs_required[CC_id][UE_id],
+              TBS,
+              eNB_UE_stats->dlsch_mcs1);
+      }
+    }
+  }
+}
+
+void dlsch_scheduler_pre_processor_allocate_fairRR(
+    module_id_t Mod_id,
+    int UE_id,
+    uint8_t CC_id,
+    int N_RBG,
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) {
+  int i;
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+  UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
+  int N_RB_DL =
+      to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+  const int min_rb_unit = get_min_rb_unit(Mod_id, CC_id);
+
+  for (i = 0; i < N_RBG; i++) {
+    if (rballoc_sub[CC_id][i] != 0)
+      continue;
+
+    if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0)
+      continue;
+
+    if (nb_rbs_remaining[CC_id][UE_id] <= 0)
+      continue;
+
+    if (ue_sched_ctl->pre_nb_available_rbs[CC_id]
+        >= nb_rbs_required[CC_id][UE_id])
+      continue;
+
+    if (ue_sched_ctl->dl_pow_off[CC_id] == 0)
+      continue;
+
+    if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
+      // Allocating last, smaller RBG
+      if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) {
+        rballoc_sub[CC_id][i] = 1;
+        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
+
+        nb_rbs_remaining[CC_id][UE_id] =
+            nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1;
+        ue_sched_ctl->pre_nb_available_rbs[CC_id] =
+            ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
+      }
+    } else {
+      // Allocating a standard-sized RBG
+      if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) {
+        rballoc_sub[CC_id][i] = 1;
+        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
+
+        nb_rbs_remaining[CC_id][UE_id] =
+            nb_rbs_remaining[CC_id][UE_id] - min_rb_unit;
+        ue_sched_ctl->pre_nb_available_rbs[CC_id] =
+            ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
+      }
+    }
+  }
+}
 
 // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
 void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
@@ -570,9 +894,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
   uint16_t                temp_total_rbs_count;
   unsigned char           temp_total_ue_count;
   unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
-  uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX];
   int                     UE_id, i;
-  uint16_t                j,c;
+  uint16_t                j;
   uint16_t                nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
   uint16_t                nb_rbs_required_remaining[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
   //  uint16_t                nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
@@ -581,7 +904,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
   int                min_rb_unit[MAX_NUM_CCs];
   //  uint16_t r1=0;
   uint8_t CC_id;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
   int N_RB_DL;
   UE_sched_ctrl_t *ue_sched_ctl;
   //  int rrc_status           = RRC_IDLE;
@@ -607,29 +930,27 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
     min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
 
     for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
-      if (UE_list->active[i] != TRUE)
+      if (UE_info->active[i] != TRUE)
         continue;
 
       UE_id = i;
       // Initialize scheduling information for all active UEs
-      dlsch_scheduler_pre_processor_reset(Mod_id,
-                                          0,
-                                          frameP,
-                                          subframeP,
-                                          min_rb_unit,
-                                          (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required,
-                                          rballoc_sub,
-                                          MIMO_mode_indicator,
-                                          mbsfn_flag);
+      dlsch_scheduler_pre_processor_reset_fairRR(
+          Mod_id,
+          frameP,
+          subframeP,
+          min_rb_unit,
+          (uint16_t(*)[MAX_MOBILES_PER_ENB])nb_rbs_required,
+          rballoc_sub,
+          MIMO_mode_indicator);
     }
   }
 
 #if (!defined(PRE_SCD_THREAD))
-  // Store the DLSCH buffer for each logical channel
-  store_dlsch_buffer(Mod_id,0, frameP, subframeP);
+  // Store the DLSCH buffer for each logical channel and for PCCID (assume 0)
+  store_dlsch_buffer(Mod_id, 0, frameP, subframeP);
   // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
-  assign_rbs_required(Mod_id, 0, frameP, subframeP, nb_rbs_required,
-                      min_rb_unit);
+  assign_rbs_required_fairRR(Mod_id, frameP, subframeP, nb_rbs_required);
 #else
   memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*MAX_MOBILES_PER_ENB);
 #endif
@@ -678,7 +999,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
       }
 
       rnti = dlsch_ue_select[CC_id].list[i].rnti;
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
       harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
       Round    = ue_sched_ctl->round[CC_id][harq_pid];
 
@@ -689,23 +1010,15 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
         nb_rbs_required_remaining[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], dlsch_ue_select[CC_id].list[i].nb_rb);
       }
 
-      /* slicing support has been introduced into the scheduler. Provide dummy
-       * data so that the preprocessor "simply works" */
-      for (c = 0; c < MAX_NUM_CCs; ++c)
-        for (j = 0; j < N_RBG_MAX; ++j)
-          slice_allocation[c][j] = 1;
-
       LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n ");
-      dlsch_scheduler_pre_processor_allocate (Mod_id,
-                                              UE_id,
-                                              CC_id,
-                                              N_RBG[CC_id],
-                                              min_rb_unit[CC_id],
-                                              (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required,
-                                              (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required_remaining,
-                                              rballoc_sub,
-                                              slice_allocation,
-                                              MIMO_mode_indicator);
+      dlsch_scheduler_pre_processor_allocate_fairRR(
+          Mod_id,
+          UE_id,
+          CC_id,
+          N_RBG[CC_id],
+          (uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required,
+          (uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining,
+          rballoc_sub);
       temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
       temp_total_ue_count--;
 
@@ -782,7 +1095,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
       }
 
       UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
-      ue_sched_ctl = &RC.mac[Mod_id]->UE_list.UE_sched_ctrl[UE_id];
+      ue_sched_ctl = &RC.mac[Mod_id]->UE_info.UE_sched_ctrl[UE_id];
       //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
 
       if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
@@ -835,7 +1148,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
   uint16_t sdu_length_total = 0;
   eNB_MAC_INST *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc = eNB->common_channels;
-  UE_list_t *UE_list = &eNB->UE_list;
+  UE_info_t *UE_info = &eNB->UE_info;
   // int continue_flag = 0;
   int32_t snr, target_snr;
   int32_t tpc = 1;
@@ -933,7 +1246,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
 
     N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth);
     // store the global enb stats:
-    eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs;
+    eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_info->num_UEs;
     eNB->eNB_stats[CC_id].available_prbs =
       total_nb_available_rb[CC_id];
     eNB->eNB_stats[CC_id].total_available_prbs +=
@@ -973,12 +1286,12 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
       rnti = UE_RNTI(module_idP,UE_id);
 
       if (rnti==NOT_A_RNTI) {
-        LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
+        LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_info->num_UEs);
         continue;
       }
 
-      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
+      ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
 
       /*
             switch(get_tmode(module_idP,CC_id,UE_id)){
@@ -1005,7 +1318,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                     UE_id,
                     CC_id,
                     cc[CC_id].tdd_Config->subframeAssignment,
-                    UE_list);
+                    UE_info);
         // update UL DAI after DLSCH scheduling
         set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
       }
@@ -1013,18 +1326,16 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
       nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
       harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
       round = ue_sched_ctl->round[CC_id][harq_pid];
-      UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
-      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status =
-        mac_eNB_get_rrc_status(module_idP, rnti);
-      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
-      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
+      UE_info->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
+      UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
+      UE_info->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
+      UE_info->eNB_UE_stats[CC_id][UE_id].harq_round = round;
 
-      if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_RECONFIGURED) {
-        UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+      if (UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_RECONFIGURED) {
+        UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
       }
 
-      if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status <
-          RRC_CONNECTED)
+      if (UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED)
         continue;
 
       sdu_length_total = 0;
@@ -1043,13 +1354,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
       //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
 
       // store stats
-      //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
+      //UE_info->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
 
       // initializing the rb allocation indicator for each UE
       for (j = 0; j < N_RBG[CC_id]; j++) {
-        UE_list->
-        UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]
-          = 0;
+        UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
       }
 
       LOG_D(MAC,
@@ -1057,33 +1366,31 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
             module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round,
             nb_available_rb, ue_sched_ctl->dl_cqi[CC_id],
             eNB_UE_stats->dlsch_mcs1,
-            UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
+            UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status);
 
       /* process retransmission  */
 
       if (round != 8) {
         // get freq_allocation
-        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+        nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
         TBS =
-          get_TBS_DL(UE_list->
-                     UE_template[CC_id][UE_id].oldmcs1[harq_pid],
+          get_TBS_DL(UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid],
                      nb_rb);
 
         if (nb_rb <= nb_available_rb) {
           if (cc[CC_id].tdd_Config != NULL) {
-            UE_list->UE_template[CC_id][UE_id].DAI++;
+            UE_info->UE_template[CC_id][UE_id].DAI++;
             update_ul_dci(module_idP, CC_id, rnti,
-                          UE_list->UE_template[CC_id][UE_id].
-                          DAI,subframeP);
+                          UE_info->UE_template[CC_id][UE_id].DAI,subframeP);
             LOG_D(MAC,
                   "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
                   CC_id, subframeP, UE_id,
-                  UE_list->UE_template[CC_id][UE_id].DAI);
+                  UE_info->UE_template[CC_id][UE_id].DAI);
           }
 
           if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
             for (j = 0; j < N_RBG[CC_id]; j++) {  // for indicating the rballoc for each sub-band
-              UE_list->UE_template[CC_id][UE_id].
+              UE_info->UE_template[CC_id][UE_id].
               rballoc_subband[harq_pid][j] =
                 ue_sched_ctl->rballoc_sub_UE[CC_id][j];
             }
@@ -1094,16 +1401,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
             while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
               if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
                   1) {
-                if (UE_list->
-                    UE_template[CC_id]
-                    [UE_id].rballoc_subband[harq_pid][j])
-                  printf
-                  ("WARN: rballoc_subband not free for retrans?\n");
+                if (UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j])
+                  LOG_W(MAC, "WARN: rballoc_subband not free for retrans?\n");
 
-                UE_list->
-                UE_template[CC_id]
-                [UE_id].rballoc_subband[harq_pid][j] =
-                  ue_sched_ctl->rballoc_sub_UE[CC_id][j];
+                UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
 
                 if ((j == N_RBG[CC_id] - 1) &&
                     ((N_RB_DL[CC_id] == 25) ||
@@ -1127,7 +1428,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
              eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
 
              for(j=0; j<N_RBG[CC_id]; j++) {
-             eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
+             eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
              }
            */
 
@@ -1164,36 +1465,23 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
               harq_process = harq_pid;
               dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1;  // dont adjust power when retransmitting
               dl_config_pdu->dci_dl_pdu.
-              dci_dl_pdu_rel8.new_data_indicator_1 =
-                UE_list->UE_template[CC_id][UE_id].
-                oldNDI[harq_pid];
-              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 =
-                UE_list->UE_template[CC_id][UE_id].
-                oldmcs1[harq_pid];
-              dl_config_pdu->dci_dl_pdu.
-              dci_dl_pdu_rel8.redundancy_version_1 =
-                round & 3;
+              dci_dl_pdu_rel8.new_data_indicator_1 = UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid];
+              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3;
 
               if (cc[CC_id].tdd_Config != NULL) { //TDD
                 dl_config_pdu->dci_dl_pdu.
-                dci_dl_pdu_rel8.downlink_assignment_index =
-                  (UE_list->UE_template[CC_id][UE_id].DAI -
-                   1) & 3;
+                dci_dl_pdu_rel8.downlink_assignment_index = (UE_info->UE_template[CC_id][UE_id].DAI - 1) & 3;
                 LOG_D(MAC,
                       "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                       module_idP, CC_id, harq_pid, round,
-                      (UE_list->UE_template[CC_id][UE_id].DAI -
-                       1),
-                      UE_list->
-                      UE_template[CC_id][UE_id].oldmcs1
-                      [harq_pid]);
+                      UE_info->UE_template[CC_id][UE_id].DAI - 1,
+                      UE_info-> UE_template[CC_id][UE_id].oldmcs1[harq_pid]);
               } else {
                 LOG_D(MAC,
                       "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                       module_idP, CC_id, harq_pid, round,
-                      UE_list->
-                      UE_template[CC_id][UE_id].oldmcs1
-                      [harq_pid]);
+                      UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid]);
               }
 
               if (!CCE_allocation_infeasible
@@ -1205,12 +1493,14 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                 dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
                 eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
                 eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
-                fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1
+                fill_nfapi_dlsch_config(&dl_req->dl_config_pdu_list[dl_req->number_pdu],
+                                        TBS,
+                                        -1
                                         /* retransmission, no pdu_index */
                                         , rnti, 0,  // type 0 allocation from 7.1.6 in 36.213
                                         0,  // virtual_resource_block_assignment_flag, unused here
                                         0,  // resource_block_coding, to be filled in later
-                                        getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version
+                                        getQm(UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version
                                         1,  // transport blocks
                                         0,  // transport block to codeword swap flag
                                         cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
@@ -1218,13 +1508,14 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                                         1,  // number of subbands
                                         //                      uint8_t codebook_index,
                                         4,  // UE category capacity
-                                        UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0,  // delta_power_offset for TM5
+                                        UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0,  // delta_power_offset for TM5
                                         0,  // ngap
                                         0,  // nprb
                                         cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
                                         0,  //number of PRBs treated as one subband, not used here
                                         0 // number of beamforming vectors, not used here
                                        );
+                dl_req->number_pdu++;
                 LOG_D(MAC,
                       "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
                       eNB->pdu_index[CC_id], round);
@@ -1248,16 +1539,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                             S_DL_SCHEDULED,
                             rnti);
           //eNB_UE_stats->dlsch_trials[round]++;
-          UE_list->eNB_UE_stats[CC_id][UE_id].
-          num_retransmission += 1;
-          UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx =
-            nb_rb;
-          UE_list->eNB_UE_stats[CC_id][UE_id].
-          total_rbs_used_retx += nb_rb;
-          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 =
-            eNB_UE_stats->dlsch_mcs1;
-          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 =
-            eNB_UE_stats->dlsch_mcs1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb;
+          UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
         } else {
           LOG_D(MAC,
                 "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
@@ -1289,7 +1575,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
         header_len_dcch = 2;  // 2 bytes DCCH SDU subheader
 
         if (TBS - ta_len - header_len_dcch > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch),0, 0); // transport block set size
+          rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, 0, 0); // transport block set size
           sdu_lengths[0] = 0;
 
           if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit
@@ -1297,7 +1583,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                   "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                   module_idP, frameP, subframeP, CC_id,
                   TBS - header_len_dcch);
-            sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS,  //not used
+            sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
+                                              TBS - ta_len - header_len_dcch,
                                               (char *) &dlsch_buffer[0],0, 0
                                              );
 
@@ -1369,11 +1656,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                   module_idP, CC_id, frameP, subframeP, UE_id, rnti, sdu_lengths[0],rlc_status.bytes_in_buffer,rrc_release_info.num_UEs);
             sdu_length_total = sdu_lengths[0];
             sdu_lcids[0] = DCCH;
-            UE_list->eNB_UE_stats[CC_id][UE_id].
-            num_pdu_tx[DCCH] += 1;
-            UE_list->
-            eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]
-            += sdu_lengths[0];
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1;
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0];
             num_sdus = 1;
 #ifdef DEBUG_eNB_SCHEDULER
             LOG_T(MAC,
@@ -1394,7 +1678,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
 
         // check for DCCH1 and update header information (assume 2 byte sub-header)
         if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) {
-          rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total),0, 0
+          rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, 0, 0
                                          ); // transport block set size less allocations for timing advance and
           // DCCH SDU
           sdu_lengths[num_sdus] = 0;
@@ -1404,7 +1688,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                   "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                   module_idP, frameP, CC_id,
                   TBS - header_len_dcch - sdu_length_total);
-            sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS,  //not used
+            sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
+                                                      TBS - ta_len - header_len_dcch - sdu_length_total,
                                      (char *) &dlsch_buffer[sdu_length_total],0, 0
                                                      );
             T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
@@ -1414,11 +1699,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
             sdu_lcids[num_sdus] = DCCH1;
             sdu_length_total += sdu_lengths[num_sdus];
             header_len_dcch += 2;
-            UE_list->eNB_UE_stats[CC_id][UE_id].
-            num_pdu_tx[DCCH1] += 1;
-            UE_list->
-            eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]
-            += sdu_lengths[num_sdus];
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1;
+            UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
             num_sdus++;
 #ifdef DEBUG_eNB_SCHEDULER
             LOG_T(MAC,
@@ -1460,7 +1742,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                                             ENB_FLAG_YES,
                                             MBMS_FLAG_NO,
                                             lcid,
-                                            TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch, 0, 0
+                                            0, 0
                                            );
 
             if (rlc_status.bytes_in_buffer > 0) {
@@ -1477,7 +1759,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                                       ENB_FLAG_YES,
                                       MBMS_FLAG_NO,
                                       lcid,
-                                      TBS,  //not used
+                                      TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch,
                                       (char *)&dlsch_buffer[sdu_length_total], 0, 0
                                                       );
               T(T_ENB_MAC_UE_DL_SDU,
@@ -1495,8 +1777,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                     lcid);
               sdu_lcids[num_sdus] = lcid;
               sdu_length_total += sdu_lengths[num_sdus];
-              UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
-              UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
+              UE_info->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
+              UE_info->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
 
               if (sdu_lengths[num_sdus] < 128) {
                 header_len_dtch--;
@@ -1504,7 +1786,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
               }
 
               num_sdus++;
-              UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+              UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
             } else { // no data for this LCID
               header_len_dtch -= 3;
             }
@@ -1557,9 +1839,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
 
           if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
             for (j = 0; j < N_RBG[CC_id]; j++) {  // for indicating the rballoc for each sub-band
-              UE_list->UE_template[CC_id][UE_id].
-              rballoc_subband[harq_pid][j] =
-                ue_sched_ctl->rballoc_sub_UE[CC_id][j];
+              UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
             }
           } else {
             nb_rb_temp = nb_rb;
@@ -1568,10 +1848,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
             while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
               if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
                   1) {
-                UE_list->
-                UE_template[CC_id]
-                [UE_id].rballoc_subband[harq_pid][j] =
-                  ue_sched_ctl->rballoc_sub_UE[CC_id][j];
+                UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
 
                 if ((j == N_RBG[CC_id] - 1) &&
                     ((N_RB_DL[CC_id] == 25) ||
@@ -1650,7 +1927,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           }
 
 #endif
-          offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus,  //num_sdus
+          offset = generate_dlsch_header((unsigned char *) UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus,  //num_sdus
                                          sdu_lengths, //
                                          sdu_lcids, 255,  // no drx
                                          ta_update, // timing advance
@@ -1679,20 +1956,20 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           LOG_T(MAC, "\n");
 #endif
           // cycle through SDUs and place in dlsch_buffer
-          memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total);
+          memcpy(&UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total);
           // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
 
           // fill remainder of DLSCH with random data
           for (j=0; j<(TBS-sdu_length_total-offset); j++) {
-            UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
+            UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
           }
 
-          trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+          trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                     TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id),
                     eNB->frame, eNB->subframe,0,0);
           T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
-            T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
-          UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
+            T_INT(harq_pid), T_BUFFER(UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
+          UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
           add_ue_dlsch_info(module_idP,
                             CC_id,
                             UE_id,
@@ -1702,37 +1979,37 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           // store stats
           eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total;
           eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1;
-          UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
-          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
-          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs;
-          UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS;
-          UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total;
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total;
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS;
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
+          UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs;
+          UE_info->eNB_UE_stats[CC_id][UE_id].TBS = TBS;
+          UE_info->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total;
+          UE_info->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total;
+          UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS;
+          UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1;
 
           if (cc[CC_id].tdd_Config != NULL) { // TDD
-            UE_list->UE_template[CC_id][UE_id].DAI++;
-            update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI,subframeP);
+            UE_info->UE_template[CC_id][UE_id].DAI++;
+            update_ul_dci(module_idP,CC_id,rnti,UE_info->UE_template[CC_id][UE_id].DAI,subframeP);
           }
 
           // do PUCCH power control
           // this is the snr
-          eNB_UE_stats =  &UE_list->eNB_UE_stats[CC_id][UE_id];
+          eNB_UE_stats =  &UE_info->eNB_UE_stats[CC_id][UE_id];
           /* Unit is not dBm, it's special from nfapi */
           snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10;
           target_snr = eNB->puCch10xSnr / 10;
           // this assumes accumulated tpc
           // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
-          int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
+          int32_t framex10psubframe = UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
 
           if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
               ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
             if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) {
               ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
-              UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP;
-              UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP;
+              UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP;
+              UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP;
 
               if (snr > target_snr + 4) {
                 tpc = 0; //-1
@@ -1767,7 +2044,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power          = 6000; // equal to RS power
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                = harq_pid;
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                         = tpc; // dont adjust power when retransmitting
-          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1-UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid];
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = mcs;
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 0;
           //deactivate second codeword
@@ -1775,10 +2052,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
           dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2        = 1;
 
           if (cc[CC_id].tdd_Config != NULL) { //TDD
-            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
+            dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_info->UE_template[CC_id][UE_id].DAI-1)&3;
             LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
                   module_idP,CC_id,harq_pid,
-                  (UE_list->UE_template[CC_id][UE_id].DAI-1),
+                  (UE_info->UE_template[CC_id][UE_id].DAI-1),
                   mcs);
           } else {
             LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
@@ -1797,13 +2074,13 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
             // Toggle NDI for next time
             LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
                   CC_id, frameP,subframeP,UE_id,
-                  rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
-            UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
-            UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
-            UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
-            AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
-            AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
-            fill_nfapi_dlsch_config(eNB,dl_req,
+                  rnti,harq_pid,UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
+            UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+            UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
+            UE_info->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
+            AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
+            AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
+            fill_nfapi_dlsch_config(&dl_req->dl_config_pdu_list[dl_req->number_pdu],
                                     TBS,
                                     eNB->pdu_index[CC_id],
                                     rnti,
@@ -1819,7 +2096,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                                     1, // number of subbands
                                     //           uint8_t codebook_index,
                                     4, // UE category capacity
-                                    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
+                                    UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
                                     0, // delta_power_offset for TM5
                                     0, // ngap
                                     0, // nprb
@@ -1827,11 +2104,12 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
                                     0, //number of PRBs treated as one subband, not used here
                                     0 // number of beamforming vectors, not used here
                                    );
+            dl_req->number_pdu++;
             eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
                                         (frameP*10)+subframeP,
                                         TBS,
                                         eNB->pdu_index[CC_id],
-                                        eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
+                                        eNB->UE_info.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
             LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]);
             eNB->pdu_index[CC_id]++;
             program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
@@ -1876,7 +2154,7 @@ fill_DLSCH_dci_fairRR(
   int               i;
   int               CC_id;
   eNB_MAC_INST      *eNB  =RC.mac[module_idP];
-  UE_list_t         *UE_list = &eNB->UE_list;
+  UE_info_t         *UE_info = &eNB->UE_info;
   int               N_RBG;
   int               N_RB_DL;
   COMMON_channels_t *cc;
@@ -1912,11 +2190,11 @@ fill_DLSCH_dci_fairRR(
         eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING;
         rnti = UE_RNTI(module_idP,UE_id);
         harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
-        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+        nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
 
         /// Synchronizing rballoc with rballoc_sub
         for(i=0; i<N_RBG; i++) {
-          rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i];
+          rballoc_sub[i] = UE_info->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i];
         }
 
         nfapi_dl_config_request_t      *DL_req         = &RC.mac[module_idP]->DL_req[0];
@@ -1962,7 +2240,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
   uint8_t first_ue_total[MAX_NUM_CCs][20];
   uint8_t first_ue_id[MAX_NUM_CCs][20];
   uint8_t ul_inactivity_num[MAX_NUM_CCs];
-  uint8_t ul_inactivity_id[MAX_NUM_CCs][20];
+  uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={0};
   //  LTE_DL_FRAME_PARMS *frame_parms;
   uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
   uint16_t saved_ulsch_dci[MAX_NUM_CCs];
@@ -1970,7 +2248,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
   UE_sched_ctrl_t *UE_sched_ctl = NULL;
   uint8_t cc_id_flag[MAX_NUM_CCs];
   uint8_t harq_pid = 0,round = 0;
-  UE_list_t *UE_list= &eNB->UE_list;
+  UE_info_t *UE_info= &eNB->UE_info;
   uint8_t                        aggregation;
   int                            format_flag;
   nfapi_hi_dci0_request_body_t   *HI_DCI0_req;
@@ -1989,7 +2267,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
   // UE round >0
   for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) {
-    if (UE_list->active[UE_id] == FALSE)
+    if (UE_info->active[UE_id] == FALSE)
       continue;
 
     rnti = UE_RNTI(module_idP,UE_id);
@@ -1999,10 +2277,10 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
     CC_id = UE_PCCID(module_idP,UE_id);
 
-    if (UE_list->UE_template[CC_id][UE_id].configured == FALSE)
+    if (UE_info->UE_template[CC_id][UE_id].configured == FALSE)
       continue;
 
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
+    if (UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
       continue;
 
     // UL DCI
@@ -2026,12 +2304,12 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     //harq_pid
     harq_pid = subframe2harqpid(cc,(frameP+(sched_subframeP<subframeP ? 1 : 0)),sched_subframeP);
     //round
-    round = UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
+    round = UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
 
     if ( round > 0 ) {
       hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
       format_flag = 2;
-      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
+      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
 
       if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
         cc_id_flag[CC_id] = 1;
@@ -2042,8 +2320,8 @@ void ulsch_scheduler_pre_ue_select_fairRR(
         hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
         HI_DCI0_req->number_of_dci++;
         ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_RETRANS;
-        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = eNB->UE_list.UE_template[CC_id][UE_id].first_rb_ul[harq_pid];
-        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = eNB->UE_list.UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
+        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = eNB->UE_info.UE_template[CC_id][UE_id].first_rb_ul[harq_pid];
+        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = eNB->UE_info.UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
         ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id;
         ulsch_ue_select[CC_id].ue_num++;
         continue;
@@ -2051,7 +2329,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     }
 
     //
-    int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes;
+    int bytes_to_schedule = UE_info->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes;
 
     if (bytes_to_schedule < 0) bytes_to_schedule = 0;
 
@@ -2063,14 +2341,14 @@ void ulsch_scheduler_pre_ue_select_fairRR(
         continue;
       }
 
-      if ( UE_list->UE_template[CC_id][UE_id].ul_SR > 0 ) {
+      if ( UE_info->UE_template[CC_id][UE_id].ul_SR > 0 ) {
         first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
         first_ue_total[CC_id] [ue_first_num[CC_id]] = 0;
         ue_first_num[CC_id]++;
         continue;
       }
 
-      UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
       rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
 
       if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0))  ||
@@ -2083,7 +2361,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
       }
 
       /*if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id] ) < ulsch_ue_max_num[CC_id] ) {
-          UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+          UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
           uint8_t ul_period = 0;
           if (cc->tdd_Config) {
             ul_period = 50;
@@ -2113,7 +2391,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
       hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
       format_flag = 2;
       rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]);
-      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0);
+      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_info->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0);
 
       if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
         cc_id_flag[CC_id] = 1;
@@ -2132,7 +2410,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
   }
 
   for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) {
-    if (UE_list->active[UE_id] == FALSE)
+    if (UE_info->active[UE_id] == FALSE)
       continue;
 
     rnti = UE_RNTI(module_idP,UE_id);
@@ -2145,10 +2423,10 @@ void ulsch_scheduler_pre_ue_select_fairRR(
     if (UE_id > last_ulsch_ue_id[CC_id])
       continue;
 
-    if (UE_list->UE_template[CC_id][UE_id].configured == FALSE)
+    if (UE_info->UE_template[CC_id][UE_id].configured == FALSE)
       continue;
 
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
+    if (UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
       continue;
 
     if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
@@ -2176,19 +2454,19 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
     HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
     //SR BSR
-    UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-    int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes;
+    UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
+    int bytes_to_schedule = UE_info->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes;
 
     if (bytes_to_schedule < 0) bytes_to_schedule = 0;
     rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
 
-    if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) ||
+    if ( (bytes_to_schedule > 0) || (UE_info->UE_template[CC_id][UE_id].ul_SR > 0) ||
          ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0))  ||
          ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) ||
          ((UE_sched_ctl->cqi_req_timer>300)&&((rrc_status >= RRC_CONNECTED))) ) {
       hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
       format_flag = 2;
-      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
+      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
 
       if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
         cc_id_flag[CC_id] = 1;
@@ -2202,7 +2480,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
         if(bytes_to_schedule > 0)
           ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = bytes_to_schedule;
-        else if(UE_list->UE_template[CC_id][UE_id].ul_SR > 0)
+        else if(UE_info->UE_template[CC_id][UE_id].ul_SR > 0)
           ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0;
 
         ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id;
@@ -2213,7 +2491,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
 
     //inactivity UE
     /*    if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id]) < ulsch_ue_max_num[CC_id] ) {
-            UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+            UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
             uint8_t ul_period = 0;
             if (cc->tdd_Config) {
               ul_period = 50;
@@ -2242,7 +2520,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
       hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
       format_flag = 2;
       rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]);
-      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[ul_inactivity_id[CC_id][temp]].dl_cqi[CC_id],format0);
+      aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_info->UE_sched_ctrl[ul_inactivity_id[CC_id][temp]].dl_cqi[CC_id],format0);
 
       if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
         cc_id_flag[CC_id] = 1;
@@ -2284,7 +2562,7 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
     ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) {
   int                CC_id,ulsch_ue_num;
   eNB_MAC_INST       *eNB = RC.mac[module_idP];
-  UE_list_t          *UE_list= &eNB->UE_list;
+  UE_info_t          *UE_info= &eNB->UE_info;
   UE_TEMPLATE        *UE_template = NULL;
   LTE_DL_FRAME_PARMS *frame_parms = NULL;
   uint8_t            ue_num_temp;
@@ -2383,9 +2661,9 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
           }
         }
       } else {
-        UE_template = &UE_list->UE_template[CC_id][UE_id];
+        UE_template = &UE_info->UE_template[CC_id][UE_id];
 
-        if ( UE_list->UE_sched_ctrl[UE_id].phr_received == 1 ) {
+        if ( UE_info->UE_sched_ctrl[UE_id].phr_received == 1 ) {
           mcs = 20;
         } else {
           mcs = 10;
@@ -2421,9 +2699,9 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
             if ( rb_table[rb_table_index] <= average_rbs ) {
               // assigne RBS( nb_rb)
               first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index];
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index];
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
-              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = rb_table[rb_table_index];
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
             }
 
             if ( rb_table[rb_table_index] > average_rbs ) {
@@ -2437,31 +2715,31 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
               }
 
               first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index];
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index];
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
-              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = rb_table[rb_table_index];
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
             }
           } else {
             if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) {
               // assigne RBS( 6 RBs)
               first_rb[CC_id] = first_rb[CC_id] + 6;
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 6;
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 5;
-              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 6;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 5;
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
             } else {
               // assigne RBS( 3 RBs)
               first_rb[CC_id] = first_rb[CC_id] + 3;
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
-              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
-              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 3;
+              UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
+              UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
             }
           }
         } else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority  == SCH_UL_INACTIVE ) {
           // assigne RBS( 3 RBs)
           first_rb[CC_id] = first_rb[CC_id] + 3;
-          UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
-          UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
-          UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+          UE_info->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul = 3;
+          UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
+          UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
         }
       }
 
@@ -2641,7 +2919,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
   int               N_RB_UL;
   eNB_MAC_INST      *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc;
-  UE_list_t         *UE_list=&eNB->UE_list;
+  UE_info_t         *UE_info=&eNB->UE_info;
   UE_TEMPLATE       *UE_template;
   UE_sched_ctrl_t     *UE_sched_ctrl;
   int               sched_frame=frameP;
@@ -2750,8 +3028,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
         continue;
       }
 
-      UE_template   = &UE_list->UE_template[CC_id][UE_id];
-      UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+      UE_template   = &UE_info->UE_template[CC_id][UE_id];
+      UE_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
       harq_pid      = subframe2harqpid(cc,sched_frame,sched_subframeP);
       rnti = UE_RNTI(CC_id,UE_id);
       aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
@@ -2844,9 +3122,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
               UE_sched_ctrl->cqi_req_timer);
         ndi = 1-UE_template->oldNDI_UL[harq_pid];
         UE_template->oldNDI_UL[harq_pid]=ndi;
-        UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
-        UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
-        UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
+        UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
+        UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+        UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
         UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
 
         if (UE_template->pre_allocated_rb_table_index_ul >=0) {
@@ -2856,10 +3134,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
           rb_table_index=5; // for PHR
         }
 
-        UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid];
+        UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid];
         UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]);
-        UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
-        UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
+        UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
+        UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
         T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
           T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
           T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi));
@@ -2877,7 +3155,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
         UE_template->cqi_req[harq_pid] = cqi_req;
         UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
 
-        if (UE_id == UE_list->head)
+        if (UE_id == UE_info->list.head)
           VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
 
         // adjust total UL buffer status by TBS, wait for UL sdus to do final update
@@ -3019,8 +3297,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
         T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
           T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb),
           T_INT(round));
-        UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
-        UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+        UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
+        UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
         uint8_t mcs_rv = 0;
 
         if(rvidx_tab[round&3]==1) {
@@ -3032,7 +3310,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
         }
 
         UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb);
-        UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
+        UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
 
         if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
           LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d)\n",
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h
index 5355a614a6c..880e60ec199 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h
@@ -85,6 +85,30 @@ void dlsch_scheduler_pre_ue_select_fairRR(
     uint16_t        nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB],
     DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]);
 
+void dlsch_scheduler_pre_processor_reset_fairRR(
+    module_id_t module_idP,
+    frame_t frameP,
+    sub_frame_t subframeP,
+    int min_rb_unit[NFAPI_CC_MAX],
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
+    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
+
+void assign_rbs_required_fairRR(
+    module_id_t Mod_id,
+    frame_t frameP,
+    sub_frame_t subframe,
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]);
+
+void dlsch_scheduler_pre_processor_allocate_fairRR(
+    module_id_t Mod_id,
+    int UE_id,
+    uint8_t CC_id,
+    int N_RBG,
+    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
+    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]);
+
 void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
                                     frame_t       frameP,
                                     sub_frame_t   subframeP,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index 2953c8e70b4..eb5d78fd3f4 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -714,13 +714,11 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 	mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
 
 	rlc_status =
-	    mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP,
+	    mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
 			       module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
 				cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
 			       //MTCH,
-			       TBS - header_len_mcch - header_len_msi -
-			       sdu_length_total - header_len_mtch
-                                    ,0, 0
+                                     0, 0
                                     );
 	bytes_in_buffer = rlc_status.bytes_in_buffer;
 
@@ -773,7 +771,8 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 		  TBS - header_len_mcch - header_len_msi -
 		  sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
 
-	    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0/*0xfffd*/, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, 0,	//not used
+      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
+                                               TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
 						     (char *)
 						     &mch_buffer[sdu_length_total]
                                 ,0,
@@ -1554,13 +1553,11 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 	mbms_rab_id = cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9;
 
 	rlc_status =
-	    mac_rlc_status_ind(module_idP, 0/*0xfffd*/, frameP, subframeP,
+	    mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
 			       module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
 				cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
 			       //MTCH,
-			       TBS - header_len_mcch - header_len_msi -
-			       sdu_length_total - header_len_mtch
-                                    ,0, 0
+                                     0, 0
                                     );
 	bytes_in_buffer = rlc_status.bytes_in_buffer;
 
@@ -1579,7 +1576,8 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 		  TBS - header_len_mcch - header_len_msi -
 		  sdu_length_total - header_len_mtch, header_len_mtch, rlc_status.bytes_in_buffer);
 
-	    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0/*0xfffd*/, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9, 0,	//not used
+      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0xfffd, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES,cc->mbms_SessionList[0]->list.array[0]->logicalChannelIdentity_r9,
+                                               TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch,
 						     (char *)
 						     &mch_buffer[sdu_length_total]
                                 ,0,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index 647db3f6249..689db8e208d 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -133,16 +133,15 @@ schedule_ue_spec_phy_test(
       /*
       LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
       CC_id, frameP,subframeP,UE_id,
-      rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
+      rnti,harq_pid,UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
 
-      UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
-      UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
-      UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
-      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
-      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
+      UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_info->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+      UE_info->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
+      UE_info->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
+      AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
+      AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
       */
-      fill_nfapi_dlsch_config(eNB,
-                              dl_req,
+      fill_nfapi_dlsch_config(&dl_req->dl_config_pdu_list[dl_req->number_pdu],
                               TBS,
                               eNB->pdu_index[CC_id],
                               rnti,
@@ -166,11 +165,12 @@ schedule_ue_spec_phy_test(
                               0, //number of PRBs treated as one subband, not used here
                               0 // number of beamforming vectors, not used here
                              );
+      dl_req->number_pdu++;
       eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
                                   (frameP*10)+subframeP,
                                   TBS,
                                   eNB->pdu_index[CC_id],
-                                  eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
+                                  eNB->UE_info.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
     } else {
       LOG_W(MAC,"[eNB_scheduler_phytest] DCI allocation infeasible!\n");
     }
@@ -192,7 +192,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
   int               N_RB_UL;
   eNB_MAC_INST      *mac = RC.mac[module_idP];
   COMMON_channels_t *cc  = &mac->common_channels[0];
-  UE_list_t         *UE_list=&mac->UE_list;
+  UE_info_t         *UE_info=&mac->UE_info;
   UE_TEMPLATE       *UE_template;
   UE_sched_ctrl_t     *UE_sched_ctrl;
   int               sched_frame=frameP;
@@ -231,8 +231,8 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
     first_rb[CC_id] = 1;
     // loop over all active UEs
     //      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
-    UE_template   = &UE_list->UE_template[CC_id][UE_id];
-    UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+    UE_template   = &UE_info->UE_template[CC_id][UE_id];
+    UE_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     harq_pid      = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframe);
     RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->TBS_UL[harq_pid];
     //power control
@@ -242,15 +242,15 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
     // new transmission
     ndi = 1-UE_template->oldNDI_UL[harq_pid];
     UE_template->oldNDI_UL[harq_pid]=ndi;
-    UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
-    UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
-    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
+    UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
+    UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+    UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
     UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
-    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
+    UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
     //            buffer_occupancy = UE_template->ul_total_buffer;
     UE_template->TBS_UL[harq_pid] = get_TBS_UL(mcs,nb_rb);
-    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += nb_rb;
-    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = get_TBS_UL(mcs,nb_rb);
+    UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += nb_rb;
+    UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = get_TBS_UL(mcs,nb_rb);
     //            buffer_occupancy -= TBS;
     // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
     //store for possible retransmission
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index e76e6b24ba7..78d6f6a3d76 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -1169,14 +1169,14 @@ program_dlsch_acknak(module_id_t module_idP,
 {
   eNB_MAC_INST                           *eNB                         = RC.mac[module_idP];
   COMMON_channels_t                      *cc                          = eNB->common_channels;
-  UE_list_t                              *UE_list                     = &eNB->UE_list;
+  UE_info_t                              *UE_info                     = &eNB->UE_info;
   rnti_t                                 rnti                         = UE_RNTI(module_idP, UE_idP);
   nfapi_ul_config_request_body_t         *ul_req;
   nfapi_ul_config_request_pdu_t          *ul_config_pdu;
   int                                    use_simultaneous_pucch_pusch = 0;
   nfapi_ul_config_ulsch_harq_information *ulsch_harq_information      = NULL;
   nfapi_ul_config_harq_information       *harq_information            = NULL;
-  struct LTE_PhysicalConfigDedicated__ext2 *ext2 = UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2;
+  struct LTE_PhysicalConfigDedicated__ext2 *ext2 = UE_info->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2;
 
   if (ext2 &&
       ext2->pucch_ConfigDedicated_v1020 &&
@@ -1363,12 +1363,12 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
 {
   eNB_MAC_INST *eNB     = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
-  UE_list_t *UE_list    = &eNB->UE_list;
+  UE_info_t *UE_info    = &eNB->UE_info;
   int UE_id = find_UE_id(module_idP, rntiP);
   nfapi_ul_config_ulsch_harq_information_rel10_t *harq_information_rel10 = &harq_information->harq_information_rel10;
   AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n");
-  AssertFatal(UE_list != NULL, "UE_list is null\n");
-  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated;
+  AssertFatal(UE_info != NULL, "UE_info is null\n");
+  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated;
   AssertFatal(physicalConfigDedicated != NULL, "physicalConfigDedicated for rnti %x is null\n",
               rntiP);
   struct LTE_PUSCH_ConfigDedicated *puschConfigDedicated = physicalConfigDedicated->pusch_ConfigDedicated;
@@ -1468,14 +1468,14 @@ fill_nfapi_harq_information(module_id_t                      module_idP,
 {
   eNB_MAC_INST *eNB     = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
-  UE_list_t *UE_list    = &eNB->UE_list;
+  UE_info_t *UE_info    = &eNB->UE_info;
   int UE_id = find_UE_id(module_idP,
                          rntiP);
   AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n");
-  AssertFatal(UE_list != NULL, "UE_list is null\n");
+  AssertFatal(UE_info != NULL, "UE_info is null\n");
   harq_information->harq_information_rel11.tl.tag        = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG;
   harq_information->harq_information_rel11.num_ant_ports = 1;
-  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated;
+  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated;
   struct LTE_PUCCH_ConfigDedicated *pucch_ConfigDedicated = NULL;
 
   if (physicalConfigDedicated != NULL) pucch_ConfigDedicated = physicalConfigDedicated->pucch_ConfigDedicated;
@@ -1489,7 +1489,7 @@ fill_nfapi_harq_information(module_id_t                      module_idP,
     case 6:
     case 7:
       if (cc->tdd_Config != NULL) {
-        //      AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL,
+        //      AssertFatal(UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL,
         //      "pucch_ConfigDedicated is null for TDD!\n");
         if (physicalConfigDedicated != NULL && pucch_ConfigDedicated != NULL &&
             pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL &&
@@ -1619,15 +1619,14 @@ fill_nfapi_mch_config(nfapi_dl_config_request_body_t *dl_req,
 
 //------------------------------------------------------------------------------
 void
-fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
-                        nfapi_dl_config_request_body_t *dl_req,
+fill_nfapi_dlsch_config(nfapi_dl_config_request_pdu_t *dl_config_pdu,
                         uint16_t length,
                         int16_t pdu_index,
                         uint16_t rnti,
                         uint8_t resource_allocation_type,
                         uint8_t
                         virtual_resource_block_assignment_flag,
-                        uint16_t resource_block_coding,
+                        uint32_t resource_block_coding,
                         uint8_t modulation,
                         uint8_t redundancy_version,
                         uint8_t transport_blocks,
@@ -1646,7 +1645,6 @@ fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
                         uint8_t num_bf_vector)
 //------------------------------------------------------------------------------
 {
-  nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
   memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
   dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
   dl_config_pdu->pdu_size                                                        = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
@@ -1673,7 +1671,6 @@ fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
   dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = transmission_mode;
   dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = num_bf_prb_per_subband;
   dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = num_bf_vector;
-  dl_req->number_pdu++;
   return;
 }
 
@@ -1879,8 +1876,7 @@ mpdcch_sf_condition(eNB_MAC_INST *eNB,
       break;
 
     case TYPEUESPEC:
-      epdcch_setconfig_r11 =
-        eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
+      epdcch_setconfig_r11 = eNB->UE_info.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
       AssertFatal(epdcch_setconfig_r11 != NULL, " epdcch_setconfig_r11 is null for UE specific \n");
       AssertFatal(epdcch_setconfig_r11->ext2 != NULL, " ext2 doesn't exist in epdcch config ' \n");
 
@@ -1988,11 +1984,11 @@ find_UE_id(module_id_t mod_idP,
 //------------------------------------------------------------------------------
 {
   int UE_id;
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
 
   for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-    if (UE_list->active[UE_id] == TRUE) {
-      if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == rntiP) {
+    if (UE_info->active[UE_id] == TRUE) {
+      if (UE_info->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == rntiP) {
         return UE_id;
       }
     }
@@ -2027,7 +2023,7 @@ find_RA_id(module_id_t mod_idP,
 
 //------------------------------------------------------------------------------
 int
-UE_num_active_CC(UE_list_t *listP,
+UE_num_active_CC(UE_info_t *listP,
                  int ue_idP)
 //------------------------------------------------------------------------------
 {
@@ -2040,7 +2036,7 @@ UE_PCCID(module_id_t mod_idP,
          int ue_idP)
 //------------------------------------------------------------------------------
 {
-  return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]);
+  return (RC.mac[mod_idP]->UE_info.pCC_id[ue_idP]);
 }
 
 //------------------------------------------------------------------------------
@@ -2051,7 +2047,7 @@ UE_RNTI(module_id_t mod_idP,
 {
   if (!RC.mac || !RC.mac[mod_idP]) return 0;
 
-  rnti_t rnti = RC.mac[mod_idP]->UE_list.UE_template[UE_PCCID(mod_idP,
+  rnti_t rnti = RC.mac[mod_idP]->UE_info.UE_template[UE_PCCID(mod_idP,
                 ue_idP)][ue_idP].rnti;
 
   if (rnti > 0) {
@@ -2069,7 +2065,7 @@ is_UE_active(module_id_t mod_idP,
              int ue_idP)
 //------------------------------------------------------------------------------
 {
-  return (RC.mac[mod_idP]->UE_list.active[ue_idP]);
+  return (RC.mac[mod_idP]->UE_info.active[ue_idP]);
 }
 
 //------------------------------------------------------------------------------
@@ -2122,28 +2118,46 @@ get_aggregation(uint8_t bw_index,
 
 //------------------------------------------------------------------------------
 /*
- * Dump the UL or DL UE_list into LOG_T(MAC)
+ * Dump the UE_list into LOG_T(MAC)
  */
 void
-dump_ue_list(UE_list_t *listP,
-             int ul_flag)
+dump_ue_list(UE_list_t *listP) {
+  for (int j = listP->head; j >= 0; j = listP->next[j])
+    LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]);
+}
+
 //------------------------------------------------------------------------------
-{
-  if (ul_flag == 0) {
-    for (int j = listP->head; j >= 0; j = listP->next[j]) {
-      LOG_T(MAC, "DL list node %d => %d\n",
-            j,
-            listP->next[j]);
-    }
+/*
+ * Add a UE to UE_list listP
+ */
+inline void add_ue_list(UE_list_t *listP, int UE_id) {
+  if (listP->head == -1) {
+    listP->head = UE_id;
+    listP->next[UE_id] = -1;
   } else {
-    for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) {
-      LOG_T(MAC, "UL list node %d => %d\n",
-            j,
-            listP->next_ul[j]);
-    }
+    int i = listP->head;
+    while (listP->next[i] >= 0)
+      i = listP->next[i];
+    listP->next[i] = UE_id;
+    listP->next[UE_id] = -1;
+  }
+}
+
+//------------------------------------------------------------------------------
+/*
+ * Remove a UE from the UE_list listP, return the previous element
+ */
+inline int remove_ue_list(UE_list_t *listP, int UE_id) {
+  listP->next[UE_id] = -1;
+  if (listP->head == UE_id) {
+    listP->head = listP->next[UE_id];
+    return -1;
   }
 
-  return;
+  int previous = prev(listP, UE_id);
+  if (previous != -1)
+    listP->next[previous] = listP->next[UE_id];
+  return previous;
 }
 
 //------------------------------------------------------------------------------
@@ -2158,50 +2172,47 @@ add_new_ue(module_id_t mod_idP,
 {
   int UE_id;
   int i, j;
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
-  LOG_D(MAC, "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
+  LOG_D(MAC, "[eNB %d, CC_id %d] Adding UE with rnti %x (prev. num_UEs %d)\n",
         mod_idP,
         cc_idP,
         rntiP,
-        UE_list->avail,
-        UE_list->num_UEs);
-  dump_ue_list(UE_list, 0);
+        UE_info->num_UEs);
 
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
-    if (UE_list->active[i] == TRUE)
+    if (UE_info->active[i] == TRUE)
       continue;
 
     UE_id = i;
-    memset(&UE_list->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE));
-    UE_list->UE_template[cc_idP][UE_id].rnti = rntiP;
-    UE_list->UE_template[cc_idP][UE_id].configured = FALSE;
-    UE_list->numactiveCCs[UE_id] = 1;
-    UE_list->numactiveULCCs[UE_id] = 1;
-    UE_list->pCC_id[UE_id] = cc_idP;
-    UE_list->ordered_CCids[0][UE_id] = cc_idP;
-    UE_list->ordered_ULCCids[0][UE_id] = cc_idP;
-    UE_list->num_UEs++;
-    UE_list->active[UE_id] = TRUE;
+    memset(&UE_info->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE));
+    UE_info->UE_template[cc_idP][UE_id].rnti = rntiP;
+    UE_info->UE_template[cc_idP][UE_id].configured = FALSE;
+    UE_info->numactiveCCs[UE_id] = 1;
+    UE_info->numactiveULCCs[UE_id] = 1;
+    UE_info->pCC_id[UE_id] = cc_idP;
+    UE_info->ordered_CCids[0][UE_id] = cc_idP;
+    UE_info->ordered_ULCCids[0][UE_id] = cc_idP;
+    UE_info->num_UEs++;
+    UE_info->active[UE_id] = TRUE;
+    add_ue_list(&UE_info->list, UE_id);
+    dump_ue_list(&UE_info->list);
     if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ?
-      UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0;
-    UE_list->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type;
-    memset((void *) &UE_list->UE_sched_ctrl[UE_id],
+      UE_info->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0;
+    UE_info->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type;
+    memset((void *) &UE_info->UE_sched_ctrl[UE_id],
            0,
            sizeof(UE_sched_ctrl_t));
-    memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id],
+    memset((void *) &UE_info->eNB_UE_stats[cc_idP][UE_id],
            0,
            sizeof(eNB_UE_STATS));
-    UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
-    /* default slice in case there was something different */
-    UE_list->assoc_dl_slice_idx[UE_id] = 0;
-    UE_list->assoc_ul_slice_idx[UE_id] = 0;
-    UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
+    UE_info->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
+    UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
 
     for (j = 0; j < 8; j++) {
-      UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = 0;
-      UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0;
-      UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8;
-      UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0;
+      UE_info->UE_template[cc_idP][UE_id].oldNDI[j] = 0;
+      UE_info->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0;
+      UE_info->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8;
+      UE_info->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0;
     }
 
     eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
@@ -2211,15 +2222,11 @@ add_new_ue(module_id_t mod_idP,
           UE_id,
           cc_idP,
           rntiP);
-    dump_ue_list(UE_list,
-                 0);
     return (UE_id);
   }
 
-  // printf("MAC: cannot add new UE for rnti %x\n", rntiP);
   LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
-  dump_ue_list(UE_list,
-               0);
+  dump_ue_list(&UE_info->list);
   return -1;
 }
 
@@ -2232,7 +2239,7 @@ rrc_mac_remove_ue(module_id_t mod_idP,
                   rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
   int UE_id = find_UE_id(mod_idP, rntiP);
   eNB_UE_STATS *ue_stats = NULL;
   int pCC_id = -1;
@@ -2248,37 +2255,14 @@ rrc_mac_remove_ue(module_id_t mod_idP,
         UE_id,
         pCC_id,
         rntiP);
-  dump_ue_list(UE_list, 0); // DL list displayed in LOG_T(MAC)
-  UE_list->active[UE_id] = FALSE;
-  UE_list->num_UEs--;
-
-  /* If present, remove UE from DL list */
-  if (UE_list->head == UE_id) {
-    UE_list->head = UE_list->next[UE_id];
-  } else {
-    int previous = prev(UE_list, UE_id, 0);
+  UE_info->active[UE_id] = FALSE;
+  UE_info->num_UEs--;
 
-    if (previous != -1) {
-      UE_list->next[previous] = UE_list->next[UE_id];
-    }
-  }
-
-  /* If present, remove UE from UL list */
-  if (UE_list->head_ul == UE_id) {
-    UE_list->head_ul = UE_list->next_ul[UE_id];
-  } else {
-    int previous = prev(UE_list, UE_id, 1);
-
-    if (previous != -1) {
-      UE_list->next_ul[previous] = UE_list->next_ul[UE_id];
-    }
-  }
+  remove_ue_list(&UE_info->list, UE_id);
 
   /* Clear all remaining pending transmissions */
-  memset(&UE_list->UE_template[pCC_id][UE_id],
-         0,
-         sizeof(UE_TEMPLATE));
-  ue_stats = &UE_list->eNB_UE_stats[pCC_id][UE_id];
+  memset(&UE_info->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE));
+  ue_stats = &UE_info->eNB_UE_stats[pCC_id][UE_id];
   ue_stats->total_rbs_used = 0;
   ue_stats->total_rbs_used_retx = 0;
 
@@ -2355,166 +2339,19 @@ rrc_mac_remove_ue(module_id_t mod_idP,
 /*
  * Returns the previous UE_id in the scheduling list in UL or DL
  */
-int
-prev(UE_list_t *listP,
-     int nodeP,
-     int ul_flag)
-//------------------------------------------------------------------------------
-{
-  if (ul_flag == 0) {
-    if (nodeP == listP->head) {
-      return nodeP;
-    }
+inline int prev(UE_list_t *listP, int nodeP) {
+  if (nodeP == listP->head)
+      return -1; /* there is no previous of the head */
 
-    for (int j = listP->head; j >= 0; j = listP->next[j]) {
-      if (listP->next[j] == nodeP) {
-        return j;
-      }
-    }
-  } else {
-    if (nodeP == listP->head_ul) {
-      return nodeP;
-    }
+  for (int j = listP->head; j >= 0; j = listP->next[j])
+    if (listP->next[j] == nodeP)
+      return j;
 
-    for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) {
-      if (listP->next_ul[j] == nodeP) {
-        return j;
-      }
-    }
-  }
-
-  LOG_E(MAC, "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
-        nodeP,
-        (ul_flag == 0) ? "DL" : "UL");
-  dump_ue_list(listP,
-               ul_flag);
+  LOG_E(MAC, "%s(): could not find previous to %d in UE_list\n", __func__, nodeP);
+  dump_ue_list(listP);
   return -1;
 }
 
-//------------------------------------------------------------------------------
-void
-swap_UEs(UE_list_t *listP,
-         int nodeiP,
-         int nodejP,
-         int ul_flag)
-//------------------------------------------------------------------------------
-{
-  int prev_i, prev_j, next_i, next_j;
-  LOG_T(MAC, "Swapping UE %d,%d\n",
-        nodeiP,
-        nodejP);
-  dump_ue_list(listP,
-               ul_flag);
-  prev_i = prev(listP,
-                nodeiP,
-                ul_flag);
-  prev_j = prev(listP,
-                nodejP,
-                ul_flag);
-  AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem");
-
-  if (ul_flag == 0) {
-    next_i = listP->next[nodeiP];
-    next_j = listP->next[nodejP];
-  } else {
-    next_i = listP->next_ul[nodeiP];
-    next_j = listP->next_ul[nodejP];
-  }
-
-  LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n",
-        (ul_flag == 0) ? "DL" : "UL",
-        next_i,
-        next_j,
-        listP->head);
-
-  if (ul_flag == 0) {
-    if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
-      LOG_T(MAC, "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
-      listP->next[nodeiP] = next_j;
-      listP->next[nodejP] = nodeiP;
-
-      if (nodeiP == listP->head) {  // case i j n(j)
-        listP->head = nodejP;
-      } else {
-        listP->next[prev_i] = nodejP;
-      }
-    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
-      LOG_T(MAC, "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
-      listP->next[nodejP] = next_i;
-      listP->next[nodeiP] = nodejP;
-
-      if (nodejP == listP->head) {  // case j i n(i)
-        listP->head = nodeiP;
-      } else {
-        listP->next[prev_j] = nodeiP;
-      }
-    } else {    // case ...  p(i) i n(i) ... p(j) j n(j) ...
-      listP->next[nodejP] = next_i;
-      listP->next[nodeiP] = next_j;
-
-      if (nodeiP == listP->head) {
-        LOG_T(MAC, "changing head to %d\n",
-              nodejP);
-        listP->head = nodejP;
-        listP->next[prev_j] = nodeiP;
-      } else if (nodejP == listP->head) {
-        LOG_D(MAC, "changing head to %d\n",
-              nodeiP);
-        listP->head = nodeiP;
-        listP->next[prev_i] = nodejP;
-      } else {
-        listP->next[prev_i] = nodejP;
-        listP->next[prev_j] = nodeiP;
-      }
-    }
-  } else {      // ul_flag
-    if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
-      LOG_T(MAC, "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
-      listP->next_ul[nodeiP] = next_j;
-      listP->next_ul[nodejP] = nodeiP;
-
-      if (nodeiP == listP->head_ul) { // case i j n(j)
-        listP->head_ul = nodejP;
-      } else {
-        listP->next_ul[prev_i] = nodejP;
-      }
-    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
-      LOG_T(MAC, "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
-      listP->next_ul[nodejP] = next_i;
-      listP->next_ul[nodeiP] = nodejP;
-
-      if (nodejP == listP->head_ul) { // case j i n(i)
-        listP->head_ul = nodeiP;
-      } else {
-        listP->next_ul[prev_j] = nodeiP;
-      }
-    } else {    // case ...  p(i) i n(i) ... p(j) j n(j) ...
-      listP->next_ul[nodejP] = next_i;
-      listP->next_ul[nodeiP] = next_j;
-
-      if (nodeiP == listP->head_ul) {
-        LOG_T(MAC, "[UL]changing head to %d\n",
-              nodejP);
-        listP->head_ul = nodejP;
-        listP->next_ul[prev_j] = nodeiP;
-      } else if (nodejP == listP->head_ul) {
-        LOG_T(MAC, "[UL]changing head to %d\n",
-              nodeiP);
-        listP->head_ul = nodeiP;
-        listP->next_ul[prev_i] = nodejP;
-      } else {
-        listP->next_ul[prev_i] = nodejP;
-        listP->next_ul[prev_j] = nodeiP;
-      }
-    }
-  }
-
-  LOG_T(MAC, "After swap\n");
-  dump_ue_list(listP,
-               ul_flag);
-  return;
-}
-
 // This has to be updated to include BSR information
 //------------------------------------------------------------------------------
 uint8_t
@@ -2523,8 +2360,8 @@ UE_is_to_be_scheduled(module_id_t module_idP,
                       uint8_t UE_id)
 //------------------------------------------------------------------------------
 {
-  UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id];
-  UE_sched_ctrl_t *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id];
+  UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_info.UE_template[CC_id][UE_id];
+  UE_sched_ctrl_t *UE_sched_ctl = &RC.mac[module_idP]->UE_info.UE_sched_ctrl[UE_id];
   int rrc_status;
 
   // do not schedule UE if UL is not working
@@ -2566,7 +2403,7 @@ get_tmode(module_id_t module_idP,
 {
   eNB_MAC_INST *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
-  struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = eNB->UE_list.UE_template[CC_idP][UE_idP].physicalConfigDedicated;
+  struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = eNB->UE_info.UE_template[CC_idP][UE_idP].physicalConfigDedicated;
 
   if (physicalConfigDedicated == NULL) {  // RRCConnectionSetup not received by UE yet
     AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n",
@@ -2776,19 +2613,21 @@ get_min_rb_unit(module_id_t module_id,
   int N_RB_DL = to_prb(RC.mac[module_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
 
   switch (N_RB_DL) {
-    case 6:     // 1.4 MHz
+    case 6:       // 1.4MHz
       min_rb_unit = 1;
       break;
 
-    case 25:      // 5HMz
+    case 15:      // 3MHz
+    case 25:      // 5MHz
       min_rb_unit = 2;
       break;
 
-    case 50:      // 10HMz
+    case 50:      // 10MHz
       min_rb_unit = 3;
       break;
 
-    case 100:     // 20HMz
+    case 75:      // 15MHz
+    case 100:     // 20MHz
       min_rb_unit = 4;
       break;
 
@@ -2809,7 +2648,7 @@ uint32_t
 allocate_prbs_sub(int nb_rb,
                   int N_RB_DL,
                   int N_RBG,
-                  uint8_t *rballoc)
+                  const uint8_t *rballoc)
 //------------------------------------------------------------------------------
 {
   int check = 0;    //check1=0,check2=0;
@@ -3482,7 +3321,7 @@ try_again:
 
       if (fCCE == -1) {
         if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
-          LOG_I(MAC, "subframe %d: Dropping Allocation for RNTI %x\n",
+          LOG_D(MAC, "subframe %d: Dropping Allocation for RNTI %x\n",
                 subframeP,
                 dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti);
 
@@ -3671,6 +3510,121 @@ CCE_allocation_infeasible(int module_idP,
   return res;
 }
 
+int CCE_try_allocate_dlsch(int module_id,
+                           int CC_id,
+                           int subframe,
+                           int UE_id,
+                           uint8_t dl_cqi) {
+  const rnti_t rnti = RC.mac[module_id]->UE_info.UE_template[CC_id][UE_id].rnti;
+  nfapi_dl_config_request_body_t *DL_req       = &RC.mac[module_id]->DL_req[CC_id].dl_config_request_body;
+
+  if (DL_req->number_pdu >= MAX_NUM_DL_PDU) {
+    LOG_W(MAC, "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", subframe, rnti);
+    return -1;
+  }
+
+  int aggregation = 2;
+  const uint8_t tm = get_tmode(module_id, CC_id, UE_id);
+  switch (tm) {
+    case 1:
+    case 2:
+    case 7:
+      aggregation = get_aggregation(get_bw_index(module_id, CC_id),
+                                    dl_cqi,
+                                    format1);
+      break;
+
+    case 3:
+      aggregation = get_aggregation(get_bw_index(module_id, CC_id),
+                                    dl_cqi,
+                                    format2A);
+      break;
+
+    default:
+      AssertFatal(0, "Unsupported transmission mode %d\n", tm);
+      break;
+  }
+
+  nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+  memset(dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag            = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
+  dl_config_pdu->pdu_type                                     = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti              = rnti;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type         = 1;
+  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
+  DL_req->number_pdu++;
+  LOG_D(MAC, "Subframe %d: Checking CCE feasibility format 1: (%x,%d) \n",
+        subframe, rnti, aggregation);
+
+  if (allocate_CCEs(module_id, CC_id, 0, subframe, 0) < 0) {
+    DL_req->number_pdu--;
+    return -1;
+  }
+
+  DL_req->number_dci++;
+  nfapi_dl_config_request_pdu_t *dl_dlsch_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+  dl_dlsch_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
+  dl_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
+  dl_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
+  DL_req->number_pdu++;
+
+  return DL_req->number_pdu - 2;
+}
+
+int CCE_try_allocate_ulsch(int module_id,
+                           int CC_id,
+                           int subframe,
+                           int UE_id,
+                           uint8_t dl_cqi) {
+  const rnti_t rnti = RC.mac[module_id]->UE_info.UE_template[CC_id][UE_id].rnti;
+  nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_id]->HI_DCI0_req[CC_id][subframe].hi_dci0_request_body;
+
+  if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi >= MAX_NUM_HI_DCI0_PDU) {
+    LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", subframe, rnti);
+    return -1;
+  }
+
+  int aggregation = 2;
+  const uint8_t tm = get_tmode(module_id, CC_id, UE_id);
+  switch (tm) {
+    case 1:
+    case 2:
+    case 7:
+      aggregation = get_aggregation(get_bw_index(module_id, CC_id),
+                                    dl_cqi,
+                                    format1);
+      break;
+
+    case 3:
+      aggregation = get_aggregation(get_bw_index(module_id, CC_id),
+                                    dl_cqi,
+                                    format2A);
+      break;
+
+    default:
+      AssertFatal(0, "Unsupported transmission mode %d\n", tm);
+      break;
+  }
+
+  const int idx = HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi;
+  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[idx];
+  memset(hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
+  hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+  hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
+  hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
+  hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
+  HI_DCI0_req->number_of_dci++;
+  LOG_D(MAC, "%s() sf %d: Checking CCE feasibility format 2: RNTI %04x, agg %d\n",
+        __func__, subframe, rnti, aggregation);
+
+  if (allocate_CCEs(module_id, CC_id, 0, subframe, 0) < 0) {
+    HI_DCI0_req->number_of_dci--;
+    return -1;
+  }
+
+  return idx;
+}
+
 //------------------------------------------------------------------------------
 void
 get_retransmission_timing(LTE_TDD_Config_t *tdd_Config,
@@ -3931,15 +3885,15 @@ extract_harq(module_id_t mod_idP,
 //------------------------------------------------------------------------------
 {
   eNB_MAC_INST *eNB = RC.mac[mod_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
-  UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  UE_info_t *UE_info = &eNB->UE_info;
+  UE_sched_ctrl_t *sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
   rnti_t rnti = UE_RNTI(mod_idP, UE_id);
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
   nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd;
   nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd;
   uint16_t num_ack_nak;
-  int numCC = UE_list->numactiveCCs[UE_id];
-  int pCCid = UE_list->pCC_id[UE_id];
+  int numCC = UE_info->numactiveCCs[UE_id];
+  int pCCid = UE_info->pCC_id[UE_id];
   int spatial_bundling = 0;
   int tmode[5];
   int i, j, m;
@@ -3947,7 +3901,7 @@ extract_harq(module_id_t mod_idP,
   sub_frame_t subframe_tx;
   int frame_tx;
   uint8_t harq_pid;
-  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated;
+  LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_info->UE_template[pCCid][UE_id].physicalConfigDedicated;
 
   if (physicalConfigDedicated != NULL && physicalConfigDedicated->pucch_ConfigDedicated != NULL &&
       physicalConfigDedicated->ext7 != NULL && physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13 != NULL &&
@@ -4081,7 +4035,7 @@ extract_harq(module_id_t mod_idP,
           sched_ctl->round[CC_idP][harq_pid]);
 
     // use 1 HARQ proces of BL/CE UE for now
-    if (UE_list->UE_template[pCCid][UE_id].rach_resource_type > 0) harq_pid = 0;
+    if (UE_info->UE_template[pCCid][UE_id].rach_resource_type > 0) harq_pid = 0;
 
     switch (harq_indication_fdd->mode) {
       case 0:   // Format 1a/b (10.1.2.1)
@@ -4567,18 +4521,18 @@ extract_pucch_csi(module_id_t mod_idP,
                   uint8_t length)
 //------------------------------------------------------------------------------
 {
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
-  UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
+  UE_sched_ctrl_t *sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
   COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
   int no_pmi;
   uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 };
   uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 };
   int feedback_cnt;
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
+  AssertFatal(UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
               UE_id);
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
+  AssertFatal(UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
               UE_id);
-  struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;
+  struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic;
   AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null for UE %d\n",
               UE_id);
   // determine feedback mode
@@ -4678,9 +4632,9 @@ extract_pusch_csi(module_id_t mod_idP,
                   uint8_t length)
 //------------------------------------------------------------------------------
 {
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
   COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
-  UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  UE_sched_ctrl_t *sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
   int Ntab[6] = { 0, 4, 7, 9, 10, 13 };
   int Ntab_uesel[6] = { 0, 8, 13, 17, 19, 25 };
   int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 };
@@ -4689,12 +4643,12 @@ extract_pusch_csi(module_id_t mod_idP,
   int i;
   uint64_t p = *(uint64_t *) pdu;
   int curbyte, curbit;
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
+  AssertFatal(UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",
               UE_id);
-  AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
+  AssertFatal(UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n",
               UE_id);
   LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic
-    = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
+    = UE_info->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic;
   AssertFatal(cqi_ReportModeAperiodic  != NULL, "cqi_ReportModeAperiodic is null for UE %d\n",
               UE_id);
   int N = Ntab[cc->mib->message.dl_Bandwidth];
@@ -4964,14 +4918,14 @@ cqi_indication(module_id_t mod_idP,
 //------------------------------------------------------------------------------
 {
   int UE_id = find_UE_id(mod_idP, rntiP);
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
 
   if (UE_id == -1) {
     LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP);
     return;
   }
 
-  UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  UE_sched_ctrl_t *sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
 
   if (UE_id >= 0) {
     LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n",
@@ -5037,11 +4991,11 @@ SR_indication(module_id_t mod_idP,
     T_INT(subframeP),
     T_INT(rntiP));
   int UE_id = find_UE_id(mod_idP, rntiP);
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
   UE_sched_ctrl_t *UE_scheduling_ctrl = NULL;
 
   if (UE_id != -1) {
-    UE_scheduling_ctrl = &(UE_list->UE_sched_ctrl[UE_id]);
+    UE_scheduling_ctrl = &(UE_info->UE_sched_ctrl[UE_id]);
 
     if ((UE_scheduling_ctrl->cdrx_configured == TRUE) &&
         (UE_scheduling_ctrl->dci0_ongoing_timer > 0)  &&
@@ -5065,8 +5019,8 @@ SR_indication(module_id_t mod_idP,
               cc_idP);
       }
 
-      UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
-      UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
+      UE_info->UE_template[cc_idP][UE_id].ul_SR = 1;
+      UE_info->UE_template[cc_idP][UE_id].ul_active = TRUE;
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0);
     }
@@ -5093,7 +5047,7 @@ UL_failure_indication(module_id_t mod_idP,
 //------------------------------------------------------------------------------
 {
   int UE_id = find_UE_id(mod_idP, rntiP);
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
 
   if (UE_id != -1) {
     LOG_D(MAC, "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n",
@@ -5104,9 +5058,9 @@ UL_failure_indication(module_id_t mod_idP,
           subframeP,
           UE_id,
           cc_idP,
-          UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
+          UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
 
-    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
+    if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer == 0) UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
   } else {
     //     AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
     //    AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
@@ -5169,8 +5123,8 @@ harq_indication(module_id_t mod_idP,
     return;
   }
 
-  UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
-  UE_sched_ctrl_t *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info;
+  UE_sched_ctrl_t *sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
   COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
   // extract HARQ Information
 
@@ -5201,51 +5155,3 @@ harq_indication(module_id_t mod_idP,
 
   return;
 }
-
-// Flexran Slicing functions
-//------------------------------------------------------------------------------
-uint16_t
-nb_rbs_allowed_slice(float rb_percentage,
-                     int total_rbs)
-//------------------------------------------------------------------------------
-{
-  return (uint16_t) floor(rb_percentage * total_rbs);
-}
-
-//------------------------------------------------------------------------------
-int
-ue_dl_slice_membership(module_id_t mod_id,
-                       int UE_id,
-                       int slice_idx)
-//------------------------------------------------------------------------------
-{
-  eNB_MAC_INST *eNB = RC.mac[mod_id];
-
-  if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_dl) {
-    LOG_W(MAC, "out of range slice index %d (slice ID %d)\n",
-          slice_idx,
-          eNB->slice_info.dl[slice_idx].id);
-    return 0;
-  }
-
-  return eNB->UE_list.active[UE_id] == TRUE && eNB->UE_list.assoc_dl_slice_idx[UE_id] == slice_idx;
-}
-
-//------------------------------------------------------------------------------
-int
-ue_ul_slice_membership(module_id_t mod_id,
-                       int UE_id,
-                       int slice_idx)
-//------------------------------------------------------------------------------
-{
-  eNB_MAC_INST *eNB = RC.mac[mod_id];
-
-  if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_ul) {
-    LOG_W(MAC, "out of range slice index %d (slice ID %d)\n",
-          slice_idx,
-          eNB->slice_info.dl[slice_idx].id);
-    return 0;
-  }
-
-  return eNB->UE_list.active[UE_id] == TRUE && eNB->UE_list.assoc_ul_slice_idx[UE_id] == slice_idx;
-}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 7c3b536de21..3062e5c9647 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -123,17 +123,15 @@ rx_sdu(const module_id_t enb_mod_idP,
   unsigned short rx_lengths[NB_RB_MAX];
   uint8_t lcgid = 0;
   int lcgid_updated[4] = {0, 0, 0, 0};
-  eNB_MAC_INST *mac = NULL;
-  UE_list_t *UE_list = NULL;
+  eNB_MAC_INST *mac = RC.mac[enb_mod_idP];
+  UE_info_t *UE_info = &mac->UE_info;
   rrc_eNB_ue_context_t *ue_contextP = NULL;
   UE_sched_ctrl_t *UE_scheduling_control = NULL;
   UE_TEMPLATE *UE_template_ptr = NULL;
   /* Init */
   current_rnti = rntiP;
   UE_id = find_UE_id(enb_mod_idP, current_rnti);
-  mac = RC.mac[enb_mod_idP];
   harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP);
-  UE_list = &mac->UE_list;
   memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char));
   memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char));
   memset(rx_lengths, 0, NB_RB_MAX * sizeof(unsigned short));
@@ -142,8 +140,8 @@ rx_sdu(const module_id_t enb_mod_idP,
   trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0);
 
   if (UE_id != -1) {
-    UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
-    UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
+    UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
+    UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id];
     LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
           enb_mod_idP,
           harq_pid,
@@ -182,7 +180,7 @@ rx_sdu(const module_id_t enb_mod_idP,
         UE_template_ptr->scheduled_ul_bytes = 0;
       }
     } else {  // sduP == NULL => error
-      LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n",
+      LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
             enb_mod_idP,
             harq_pid,
             CC_idP,
@@ -191,7 +189,8 @@ rx_sdu(const module_id_t enb_mod_idP,
             UE_scheduling_control->round_UL[CC_idP][harq_pid],
             ul_cqi,
             UE_id,
-            current_rnti);
+            current_rnti,
+	    sdu_lenP);
 
       if (ul_cqi > 200) { // too high energy pattern
         UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi;
@@ -413,8 +412,8 @@ rx_sdu(const module_id_t enb_mod_idP,
             UE_id = old_UE_id;
             current_rnti = old_rnti;
             /* Clear timer */
-            UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
-            UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
+            UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
+            UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id];
             UE_scheduling_control->uplane_inactivity_timer = 0;
             UE_scheduling_control->ul_inactivity_timer = 0;
             UE_scheduling_control->ul_failure_timer = 0;
@@ -430,7 +429,7 @@ rx_sdu(const module_id_t enb_mod_idP,
 
             UE_template_ptr->ul_SR = 1;
             UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1;
-            UE_list->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1;
+            UE_info->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1;
             cancel_ra_proc(enb_mod_idP,
                            CC_idP,
                            frameP,
@@ -480,8 +479,8 @@ rx_sdu(const module_id_t enb_mod_idP,
                 ra->crnti_rrc_mui = rrc_eNB_mui-1;
                 ra->crnti_harq_pid = -1;
                 /* Clear timer */
-                UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
-                UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
+                UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
+                UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id];
                 UE_scheduling_control->uplane_inactivity_timer = 0;
                 UE_scheduling_control->ul_inactivity_timer = 0;
                 UE_scheduling_control->ul_failure_timer = 0;
@@ -532,7 +531,7 @@ rx_sdu(const module_id_t enb_mod_idP,
             UE_template_ptr->ul_buffer_info[LCGID3];
           RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f);
 
-          if (UE_id == UE_list->head) {
+          if (UE_id == UE_info->list.head) {
             VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f));
           }
 
@@ -689,8 +688,8 @@ rx_sdu(const module_id_t enb_mod_idP,
                     frameP,
                     ra->rnti,
                     UE_id);
-              UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
-              UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
+              UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
+              UE_template_ptr = &UE_info->UE_template[CC_idP][UE_id];
             }
           } else {
             LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
@@ -779,11 +778,11 @@ rx_sdu(const module_id_t enb_mod_idP,
                 enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id,
                 rx_lcids[i]);
           mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);  //(unsigned int*)crc_status);
-          UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
-          UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
+          UE_info->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
+          UE_info->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
 
           if (mac_eNB_get_rrc_status(enb_mod_idP, current_rnti) < RRC_RECONFIGURED) {
-            UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+            UE_info->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
           }
         }
 
@@ -840,8 +839,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 
             if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) {  // MAX SIZE OF transport block
               mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);
-              UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
-              UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
+              UE_info->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
+              UE_info->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
               /* Clear uplane_inactivity_timer */
               UE_scheduling_control->uplane_inactivity_timer = 0;
               /* Reset RRC inactivity timer after uplane activity */
@@ -856,7 +855,7 @@ rx_sdu(const module_id_t enb_mod_idP,
                       current_rnti);
               }
             } else {  /* rx_length[i] Max size */
-              UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1;
+              UE_info->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1;
               LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
                     enb_mod_idP,
                     CC_idP,
@@ -921,12 +920,12 @@ rx_sdu(const module_id_t enb_mod_idP,
   /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
   if ((num_sdu == 0) && (num_ce == 0)) {
     if (UE_id != -1)
-      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1;
+      UE_info->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1;
   } else {
     if (UE_id != -1) {
-      UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx        = sdu_lenP;
-      UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP;
-      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx  += 1;
+      UE_info->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx        = sdu_lenP;
+      UE_info->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP;
+      UE_info->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx  += 1;
     }
   }
 
@@ -1101,16 +1100,12 @@ schedule_ulsch(module_id_t module_idP,
                sub_frame_t subframeP)
 //-----------------------------------------------------------------------------
 {
-  uint16_t first_rb[NFAPI_CC_MAX];
   eNB_MAC_INST *mac = NULL;
-  slice_info_t *sli = NULL;
   COMMON_channels_t *cc = NULL;
   int sched_subframe;
   int sched_frame;
   /* Init */
   mac = RC.mac[module_idP];
-  sli = &(mac->slice_info);
-  memset(first_rb, 0, NFAPI_CC_MAX * sizeof(uint16_t));
   start_meas(&(mac->schedule_ulsch));
   sched_subframe = (subframeP + 4) % 10;
   sched_frame = frameP;
@@ -1217,60 +1212,53 @@ schedule_ulsch(module_id_t module_idP,
 
   /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
   for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) {
-    first_rb[CC_id] = (emtc_active[CC_id] == 1) ? 7 : 1;
-    RA_t *ra_ptr = cc->ra;
-
-    /* From Louis-Adrien to François:
-     * The comment bloc below is to configure with a command line.
-     * I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c).
-     * As said in the meeting, it seems to work only for small TBS.
-     * The cause of false RA still present with this fix is to investigate.
-     *
-     * Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c
-     * I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4.
-     * To confirm.
-     */
-    /*
-    int start_rb = 0;
-    int nb_rb = 6;
-    LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms);
-
-    if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) {
-      start_rb = get_prach_prb_offset(frame_parms,
-                                      frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
-                                      frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
-                                      0, // tdd_mapindex
-                                      sched_frame); // Nf
-
-      first_rb[CC_id] = start_rb + nb_rb;
+    LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_id]->frame_parms;
+    if (is_prach_subframe(frame_parms, sched_frame, sched_subframe)) {
+      int start_rb = get_prach_prb_offset(
+          frame_parms,
+          frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+          frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
+          0, // tdd_mapindex
+          sched_frame); // Nf
+      for (int i = 0; i < 6; i++)
+        cc[CC_id].vrb_map_UL[start_rb + i] = 1;
     }
-    */
 
-    /*
-     * Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3
-     * Msg3 is using 1 PRB so we need to increase first_rb accordingly
-     * Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?)
+    /* HACK: let's remove the PUCCH from available RBs
+     * we suppose PUCCH size is:
+     * - for 25 RBs: 1 RB (top and bottom of ressource grid)
+     * - for 50:     2 RBs
+     * - for 100:    3 RBs
+     * This is totally arbitrary and might even be wrong.
      */
-    for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) {
-      if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) {
-        if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) {
-          first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb;
-        }
+    switch (to_prb(cc[CC_id].ul_Bandwidth)) {
+      case 25:
+        cc[CC_id].vrb_map_UL[0] = 1;
+        cc[CC_id].vrb_map_UL[24] = 1;
+        break;
 
-        /* Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling
-         * on the same time resources. Also the performance improvement of breaking is low,
-         * since we will loop until the end, most of the time.
-         * I'm letting the break as a reminder, in case of misunderstanding the spec.
-         */
-        // break;
-      }
+      case 50:
+        cc[CC_id].vrb_map_UL[0] = 1;
+        cc[CC_id].vrb_map_UL[1] = 1;
+        cc[CC_id].vrb_map_UL[48] = 1;
+        cc[CC_id].vrb_map_UL[49] = 1;
+        break;
+
+      case 100:
+        cc[CC_id].vrb_map_UL[0] = 1;
+        cc[CC_id].vrb_map_UL[1] = 1;
+        cc[CC_id].vrb_map_UL[2] = 1;
+        cc[CC_id].vrb_map_UL[97] = 1;
+        cc[CC_id].vrb_map_UL[98] = 1;
+        cc[CC_id].vrb_map_UL[99] = 1;
+        break;
+
+      default:
+        LOG_E(MAC, "RBs setting not handled. Todo.\n");
+        exit(1);
     }
-  }
 
-  /* Run each enabled slice-specific schedulers one by one */
-  for (int i = 0; i < sli->n_ul; i++) {
-    /* By default the scheduler is schedule_ulsch_rnti (see below) */
-    sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb);
+    schedule_ulsch_rnti(module_idP, CC_id, frameP, subframeP, sched_subframe);
   }
 
   stop_meas(&mac->schedule_ulsch);
@@ -1282,48 +1270,20 @@ schedule_ulsch(module_id_t module_idP,
 */
 void
 schedule_ulsch_rnti(module_id_t   module_idP,
-                    int           slice_idx,
+                    int           CC_id,
                     frame_t       frameP,
                     sub_frame_t   subframeP,
-                    unsigned char sched_subframeP,
-                    uint16_t      *first_rb)
-//-----------------------------------------------------------------------------
-{
-  rnti_t rnti = -1;
-  uint8_t aggregation = 2;
-  uint8_t round_index = 0;
-  uint8_t harq_pid = 0;
-  uint8_t status = 0;
-  uint8_t rb_table_index = -1;
-  uint8_t dlsch_flag = 0;
-  uint16_t ul_req_index = 0;
-  uint32_t cqi_req = 0;
-  uint32_t cshift = 0;
-  uint32_t ndi = 0;
-  uint32_t tpc = 0;
-  int32_t snr = 0;
-  int32_t target_snr = 0;
-  int32_t framex10psubframe = 0;
+                    unsigned char sched_subframeP) {
+  /* TODO: does this need to be static? */
   static int32_t tpc_accumulated = 0;
-  int sched_frame = 0;
-  int CC_id = 0;
-  eNB_MAC_INST *mac = NULL;
-  COMMON_channels_t *cc = NULL;
-  UE_list_t *UE_list = NULL;
-  slice_info_t *sli = NULL;
-  UE_TEMPLATE *UE_template_ptr = NULL;
-  UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL;
-  int rvidx_tab[4] = {0, 2, 3, 1};
-  int first_rb_slice[NFAPI_CC_MAX];
-  int n_rb_ul_tab[NFAPI_CC_MAX];
-  /* Init */
-  mac = RC.mac[module_idP];
-  cc = mac->common_channels;
-  UE_list = &(mac->UE_list);
-  sli = &(mac->slice_info);
-  memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int));
-  memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int));
-  sched_frame = frameP;
+  /* values from 0 to 7 can be used for mapping the cyclic shift
+   * (36.211 , Table 5.5.2.1.1-1) */
+  const uint32_t cshift = 0;
+  eNB_MAC_INST *mac = RC.mac[module_idP];
+  COMMON_channels_t *cc = mac->common_channels;
+  UE_info_t *UE_info = &mac->UE_info;
+
+  int sched_frame = frameP;
 
   if (sched_subframeP < subframeP) {
     sched_frame++;
@@ -1339,63 +1299,23 @@ schedule_ulsch_rnti(module_id_t   module_idP,
   nfapi_ul_config_ulsch_harq_information *ulsch_harq_information;
   hi_dci0_req->sfn_sf = (frameP << 4) + subframeP;
 
-  /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
-    n_rb_ul_tab[CC_id] = to_prb(cc[CC_id].ul_Bandwidth); // return total number of PRB
-
-    /* HACK: let's remove the PUCCH from available RBs
-     * we suppose PUCCH size is:
-     * - for 25 RBs: 1 RB (top and bottom of ressource grid)
-     * - for 50:     2 RBs
-     * - for 100:    3 RBs
-     * This is totally arbitrary and might even be wrong.
-     * We suppose 'first_rb[]' has been correctly populated by the caller,
-     * so we only remove the top part of the resource grid.
-     */
-    switch (n_rb_ul_tab[CC_id]) {
-      case 25:
-        n_rb_ul_tab[CC_id] -= 1;
-        break;
-
-      case 50:
-        n_rb_ul_tab[CC_id] -= 2;
-        break;
-
-      case 100:
-        n_rb_ul_tab[CC_id] -= 3;
-        break;
-
-      default:
-        LOG_E(MAC, "RBs setting not handled. Todo.\n");
-        exit(1);
-    }
-
-    UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb);
-  }
-
   /*
    * ULSCH preprocessor: set UE_template->
    * pre_allocated_nb_rb_ul[slice_idx]
    * pre_assigned_mcs_ul
    * pre_allocated_rb_table_index_ul
    */
-  ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb);
+  ulsch_scheduler_pre_processor(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP);
 
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
-    first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx];
-  }
-
-  // loop over all active UEs until end of function
-  for (int UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) {
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    if (UE_info->UE_template[CC_id][UE_id].rach_resource_type > 0)
       continue;
-    }
-
-    if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].rach_resource_type > 0)  continue;
 
     // don't schedule if Msg5 is not received yet
-    if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) {
-      LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n",
+    if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) {
+      LOG_D(MAC,
+            "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping "
+            "UE scheduling \n",
             module_idP,
             frameP,
             subframeP,
@@ -1403,10 +1323,11 @@ schedule_ulsch_rnti(module_id_t   module_idP,
       continue;
     }
 
-    rnti = UE_RNTI(module_idP, UE_id);
+    const rnti_t rnti = UE_RNTI(module_idP, UE_id);
 
     if (rnti == NOT_A_RNTI) {
-      LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n",
+      LOG_W(MAC,
+            "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n",
             module_idP,
             frameP,
             subframeP,
@@ -1414,485 +1335,509 @@ schedule_ulsch_rnti(module_id_t   module_idP,
       continue;
     }
 
-    // loop over all active UL CC_ids for this UE until end of function
-    for (int n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      /* This is the actual CC_id in the list */
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      UE_template_ptr = &(UE_list->UE_template[CC_id][UE_id]);
-      UE_sched_ctrl_ptr = &(UE_list->UE_sched_ctrl[UE_id]);
-      harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP);
-      round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid];
-      AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n",
-                  round_index,
-                  UE_id,
-                  rnti);
-      LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
-            module_idP,
-            frameP,
-            subframeP,
-            sched_frame,
-            sched_subframeP,
-            harq_pid,
-            UE_id,
-            rnti,
-            CC_id,
-            aggregation,
-            n_rb_ul_tab[CC_id]);
-      /* Seems unused, only for debug */
-      RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer;
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer);
+    UE_TEMPLATE *UE_template_ptr = &UE_info->UE_template[CC_id][UE_id];
+    UE_sched_ctrl_t *UE_sched_ctrl_ptr = &UE_info->UE_sched_ctrl[UE_id];
+    const uint8_t harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP);
+    uint8_t round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid];
+    AssertFatal(round_index < 8,
+                "round %d > 7 for UE %d/%x\n",
+                round_index,
+                UE_id,
+                rnti);
 
-      /*
-       * If there is information on BSR of DCCH, DTCH or if there is UL_SR,
-       * or if there is a packet to retransmit, or we want to schedule a periodic feedback
-       */
-      if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) {
-        LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
-              module_idP,
-              harq_pid,
-              frameP,
-              subframeP,
-              UE_id,
-              rnti,
-              round_index,
-              UE_template_ptr->ul_SR,
-              UE_sched_ctrl_ptr->ul_inactivity_timer,
-              UE_sched_ctrl_ptr->ul_failure_timer,
-              UE_sched_ctrl_ptr->cqi_req_timer);
-        /* Reset the scheduling request */
-        UE_template_ptr->ul_SR = 0;
-        status = mac_eNB_get_rrc_status(module_idP, rnti);
-
-        /* New transmission */
-        if (round_index == 0) {
-          /* Be sure that there are some free RBs */
-          if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id]) {
-            LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
-                  module_idP,
-                  frameP,
-                  subframeP,
-                  UE_id,
-                  rnti,
-                  CC_id);
-            continue;
-          }
+    /* Seems unused, only for debug */
+    RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] =
+        UE_template_ptr->estimated_ul_buffer;
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,
+                                            UE_template_ptr->estimated_ul_buffer);
 
-          /* Should format_flag be 2 in CCE_allocation_infeasible??? */
-          /* This test seems to be way too long, can we provide an optimization? */
-          if (CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) {
-            LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: not enough CCE\n",
-                  module_idP,
-                  frameP,
-                  subframeP,
-                  UE_id,
-                  rnti,
-                  CC_id);
-            continue;
-          }
+    if (UE_template_ptr->pre_allocated_nb_rb_ul < 1)
+      continue;
 
-          /* Handle the aperiodic CQI report */
-          cqi_req = 0;
-          LOG_D(MAC,"RRC Conenction status %d, cqi_timer %d\n",status,UE_sched_ctrl_ptr->cqi_req_timer);
-
-          if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) {
-            if (UE_sched_ctrl_ptr->cqi_received == 0) {
-              cqi_req = 1;
-              LOG_D(MAC,
-                    "Setting CQI_REQ (timer %d)\n",
-                    UE_sched_ctrl_ptr->cqi_req_timer);
-
-              /* TDD: to be safe, do not ask CQI in special
-               * Subframes:36.213/7.2.3 CQI definition */
-              if (cc[CC_id].tdd_Config) {
-                switch (cc[CC_id].tdd_Config->subframeAssignment) {
-                  case 1:
-                    if (subframeP == 1 || subframeP == 6)
-                      cqi_req = 0;
-                    break;
-
-                  case 3:
-                    if (subframeP == 1)
-                      cqi_req = 0;
-                    break;
-
-                  default:
-                    LOG_E(MAC, " TDD config not supported\n");
-                    break;
-                }
-              }
+    int dci_ul_pdu_idx = UE_template_ptr->pre_dci_ul_pdu_idx;
+    if (dci_ul_pdu_idx < 0) {
+      dci_ul_pdu_idx = CCE_try_allocate_ulsch(
+          module_idP, CC_id, subframeP, UE_id, UE_sched_ctrl_ptr->dl_cqi[CC_id]);
+      if (dci_ul_pdu_idx < 0) {
+        LOG_W(MAC ,"%4d.%d: Dropping UL Allocation for RNTI 0x%04x/UE %d\n",
+              frameP, subframeP, rnti, UE_id);
+        continue;
+      }
+    }
 
-              if (cqi_req == 1) {
-                UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
-              }
-            } else {
-              LOG_D(MAC,"Clearing CQI request timer\n");
-              UE_sched_ctrl_ptr->cqi_req_flag = 0;
-              UE_sched_ctrl_ptr->cqi_received = 0;
-              UE_sched_ctrl_ptr->cqi_req_timer = 0;
-            }
-          }
+    /* verify it is the right UE */
+    hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[dci_ul_pdu_idx];
+    if (hi_dci0_pdu->pdu_type != NFAPI_HI_DCI0_DCI_PDU_TYPE
+        || hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti != rnti) {
+      LOG_E(MAC, "illegal hi_dci0_pdu_list index %d for UE %d/RNTI %04x\n",
+            dci_ul_pdu_idx,
+            UE_id,
+            rnti);
+      continue;
+    }
 
-          /* Power control */
-          /*
-           * Compute the expected ULSCH RX snr (for the stats)
-           * This is the normalized RX snr and this should be constant (regardless of mcs)
-           * Is not in dBm, unit from nfapi, converting to dBm
-           */
-          snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10;
-          target_snr = mac->puSch10xSnr / 10;
-          /*
-           * This assumes accumulated tpc
-           * Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
-           */
-          framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->pusch_tpc_tx_subframe;
+    LOG_D(MAC,
+          "[eNB %d][PUSCH %d] %d.%d Scheduling UE %d/%x in "
+          "round %d (SR %d, UL_inactivity timer %d, UL_failure timer "
+          "%d, cqi_req_timer %d)\n",
+          module_idP,
+          harq_pid,
+          frameP,
+          subframeP,
+          UE_id,
+          rnti,
+          round_index,
+          UE_template_ptr->ul_SR,
+          UE_sched_ctrl_ptr->ul_inactivity_timer,
+          UE_sched_ctrl_ptr->ul_failure_timer,
+          UE_sched_ctrl_ptr->cqi_req_timer);
+
+    /* Reset the scheduling request */
+    UE_template_ptr->ul_SR = 0;
+    const uint8_t status = mac_eNB_get_rrc_status(module_idP, rnti);
+
+    /* Power control */
+    /*
+     * Compute the expected ULSCH RX snr (for the stats)
+     * This is the normalized RX snr and this should be constant (regardless
+     * of mcs) Is not in dBm, unit from nfapi, converting to dBm
+     */
+    const int32_t snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10;
+    const int32_t target_snr = mac->puSch10xSnr / 10;
 
-          if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
-              ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around
-            UE_template_ptr->pusch_tpc_tx_frame = frameP;
-            UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
+    /*
+     * This assumes accumulated tpc
+     * Make sure that we are only sending a tpc update once a frame, otherwise
+     * the control loop will freak out
+     */
+    const int32_t fx10psf = (UE_template_ptr->pusch_tpc_tx_frame * 10)
+                            + UE_template_ptr->pusch_tpc_tx_subframe;
+    uint32_t tpc = 1;
+    if (((fx10psf + 10) <= (frameP * 10 + subframeP)) // normal case
+        || ((fx10psf > (frameP * 10 + subframeP))
+            && (((10240 - fx10psf + frameP * 10 + subframeP) >= 10)))) { // frame wrap-around
+      UE_template_ptr->pusch_tpc_tx_frame = frameP;
+      UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
+
+      if (snr > target_snr + 4) {
+        tpc = 0; // -1
+        tpc_accumulated--;
+      } else if (snr < target_snr - 4) {
+        tpc = 2; // +1
+        tpc_accumulated++;
+      }
+    }
+    if (tpc != 1) {
+      LOG_D(MAC,
+            "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, "
+            "tpc %d, accumulated %d, snr/target snr %d/%d\n",
+            module_idP,
+            frameP,
+            subframeP,
+            harq_pid,
+            tpc,
+            tpc_accumulated,
+            snr,
+            target_snr);
+    }
 
-            if (snr > target_snr + 4) {
-              tpc = 0; // -1
-              tpc_accumulated--;
-            } else if (snr < target_snr - 4) {
-              tpc = 2; // +1
-              tpc_accumulated++;
-            } else {
-              tpc = 1; // 0
-            }
-          } else {
-            tpc = 1; // 0
-          }
+    /* New transmission */
+    if (round_index == 0) {
+      /* Handle the aperiodic CQI report */
+      uint32_t cqi_req = 0;
+      LOG_D(MAC,
+            "RRC Connection status %d, cqi_timer %d\n",
+            status,
+            UE_sched_ctrl_ptr->cqi_req_timer);
+
+      if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) {
+        if (UE_sched_ctrl_ptr->cqi_received == 0) {
+          cqi_req = 1;
+          LOG_D(MAC,
+                "Setting CQI_REQ (timer %d)\n",
+                UE_sched_ctrl_ptr->cqi_req_timer);
 
-          if (tpc != 1) {
-            LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
-                  module_idP,
-                  frameP,
-                  subframeP,
-                  harq_pid,
-                  tpc,
-                  tpc_accumulated,
-                  snr,
-                  target_snr);
-          }
+          /* TDD: to be safe, do not ask CQI in special
+           * Subframes:36.213/7.2.3 CQI definition */
+          if (cc[CC_id].tdd_Config) {
+            switch (cc[CC_id].tdd_Config->subframeAssignment) {
+              case 1:
+                if (subframeP == 1 || subframeP == 6)
+                  cqi_req = 0;
+                break;
 
-          ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator
-          UE_template_ptr->oldNDI_UL[harq_pid] = ndi;
-          UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
-          UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
-          UE_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs);
-          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid];
-
-          /* CDRX */
-          if (UE_sched_ctrl_ptr->cdrx_configured) {
-            UE_sched_ctrl_ptr->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission
-            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl_ptr->drx_inactivity_timer);
-            UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1,
-            // see definition for more information
-          }
+              case 3:
+                if (subframeP == 1)
+                  cqi_req = 0;
+                break;
 
-          if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) {
-            rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul;
-          } else {
-            UE_template_ptr->mcs_UL[harq_pid] = 10;
-            rb_table_index = 5; // for PHR
+              default:
+                LOG_E(MAC, " TDD config not supported\n");
+                break;
+            }
           }
 
-          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid];
+          if (cqi_req == 1)
+            UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
+        } else {
+          LOG_D(MAC, "Clearing CQI request timer\n");
+          UE_sched_ctrl_ptr->cqi_req_flag = 0;
+          UE_sched_ctrl_ptr->cqi_received = 0;
+          UE_sched_ctrl_ptr->cqi_req_timer = 0;
+        }
+      }
 
-          while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) ||
-                  (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) {
-            rb_table_index--;
-          }
+      const uint8_t ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator
+      const uint8_t mcs = UE_template_ptr->pre_assigned_mcs_ul;
+      UE_template_ptr->oldNDI_UL[harq_pid] = ndi;
+      UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
+      UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+      UE_template_ptr->mcs_UL[harq_pid] = mcs;
+      UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
+
+      /* CDRX */
+      if (UE_sched_ctrl_ptr->cdrx_configured) {
+        // reset drx inactivity timer when new transmission
+        UE_sched_ctrl_ptr->drx_inactivity_timer = 1;
+        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(
+            VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY,
+            (unsigned long)UE_sched_ctrl_ptr->drx_inactivity_timer);
+        // when set the UE_template_ptr->ul_SR cannot be set to 1,
+        // see definition for more information
+        UE_sched_ctrl_ptr->dci0_ongoing_timer = 1;
+      }
 
-          UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]);
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index];
-          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid];
-          UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->TBS_UL[harq_pid];
-          T(T_ENB_MAC_UE_UL_SCHEDULE,
-            T_INT(module_idP),
-            T_INT(CC_id),
-            T_INT(rnti),
-            T_INT(frameP),
-            T_INT(subframeP),
-            T_INT(harq_pid),
-            T_INT(UE_template_ptr->mcs_UL[harq_pid]),
-            T_INT(first_rb_slice[CC_id]),
-            T_INT(rb_table[rb_table_index]),
-            T_INT(UE_template_ptr->TBS_UL[harq_pid]),
-            T_INT(ndi));
-          /* Store information for possible retransmission */
-          UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
-          UE_template_ptr->first_rb_ul[harq_pid] = first_rb_slice[CC_id];
-          UE_template_ptr->cqi_req[harq_pid] = cqi_req;
-          UE_sched_ctrl_ptr->ul_scheduled |= (1 << harq_pid);
-
-          if (UE_id == UE_list->head) {
-            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl_ptr->ul_scheduled);
-          }
+      uint8_t rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul;
+
+      UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
+
+      while (rb_table[rb_table_index] > 45 && rb_table_index > 0)
+        rb_table_index--;
+
+      UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(mcs, rb_table[rb_table_index]);
+      UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index];
+      UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid];
+      UE_info->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->TBS_UL[harq_pid];
+      T(T_ENB_MAC_UE_UL_SCHEDULE,
+        T_INT(module_idP),
+        T_INT(CC_id),
+        T_INT(rnti),
+        T_INT(frameP),
+        T_INT(subframeP),
+        T_INT(harq_pid),
+        T_INT(mcs),
+        T_INT(rb_table[rb_table_index]),
+        T_INT(UE_template_ptr->TBS_UL[harq_pid]),
+        T_INT(ndi));
+      /* Store information for possible retransmission */
+      UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
+      UE_template_ptr->first_rb_ul[harq_pid] = UE_template_ptr->pre_first_nb_rb_ul;
+      UE_template_ptr->cqi_req[harq_pid] = cqi_req;
+      UE_sched_ctrl_ptr->ul_scheduled |= (1 << harq_pid);
+
+      if (UE_id == UE_info->list.head) {
+        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(
+            VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,
+            UE_sched_ctrl_ptr->ul_scheduled);
+      }
 
-          /* Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update */
-          LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n",
-                module_idP,
-                CC_id,
-                UE_id,
-                rnti,
-                UE_template_ptr->scheduled_ul_bytes,
-                UE_template_ptr->TBS_UL[harq_pid]);
-          UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid];
-          LOG_D(MAC, "scheduled_ul_bytes, new %d\n",
-                UE_template_ptr->scheduled_ul_bytes);
-          /* Cyclic shift for DM-RS */
-          cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
-          /* Save it for a potential retransmission */
-          UE_template_ptr->cshift[harq_pid] = cshift;
-          /* Setting DCI0 NFAPI struct */
-          hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
-          memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t));
-          hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
-          hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu);
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id];
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index];
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template_ptr->mcs_UL[harq_pid];
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP];
-          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid;
-          hi_dci0_req_body->number_of_dci++;
-          hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0);
-          hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
-          hi_dci0_req->sfn_sf = frameP << 4 | subframeP;
-          hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
-          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
-                harq_pid,
+      /* Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update */
+      LOG_D(MAC,
+            "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old "
+            "%d, TBS %d\n",
+            module_idP,
+            CC_id,
+            UE_id,
+            rnti,
+            UE_template_ptr->scheduled_ul_bytes,
+            UE_template_ptr->TBS_UL[harq_pid]);
+      UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid];
+      LOG_D(MAC,
+            "scheduled_ul_bytes, new %d\n",
+            UE_template_ptr->scheduled_ul_bytes);
+      /* Cyclic shift for DM-RS */
+      /* Save it for a potential retransmission */
+      UE_template_ptr->cshift[harq_pid] = cshift;
+      /* Setting DCI0 NFAPI struct */
+      hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[dci_ul_pdu_idx];
+      hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu);
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = UE_template_ptr->pre_first_nb_rb_ul;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block =
+          rb_table[rb_table_index];
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index =
+          UE_template_ptr->DAI_ul[sched_subframeP];
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid;
+      hi_dci0_req_body->sfnsf =
+          sfnsf_add_subframe(sched_frame, sched_subframeP, 0);
+      hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
+      hi_dci0_req->sfn_sf = frameP << 4 | subframeP;
+      hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
+      LOG_D(MAC,
+            "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE "
+            "%d/%x, ulsch_frame %d, ulsch_subframe %d\n",
+            harq_pid,
+            frameP,
+            subframeP,
+            UE_id,
+            rnti,
+            sched_frame,
+            sched_subframeP);
+      uint16_t ul_req_index = 0;
+      uint8_t dlsch_flag = 0;
+
+      for (ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
+        if (ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
+            ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
+          dlsch_flag = 1;
+          LOG_D(MAC,
+                "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI "
+                "HARQ to ULSCH HARQ(first)\n",
                 frameP,
                 subframeP,
-                UE_id,
                 rnti,
-                sched_frame,
-                sched_subframeP);
-          ul_req_index = 0;
-          dlsch_flag = 0;
-
-          for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
-            if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
-                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
-              dlsch_flag = 1;
-              LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
-                    frameP,
-                    subframeP,
-                    rnti,
-                    ul_req_index);
-              break;
-            }
-          }
+                ul_req_index);
+          break;
+        }
+      }
 
-          /* Add UL_config PDUs */
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
-                                               cqi_req,
-                                               cc,
-                                               UE_template_ptr->physicalConfigDedicated,
-                                               get_tmode(module_idP, CC_id, UE_id),
-                                               mac->ul_handle,
-                                               rnti,
-                                               first_rb_slice[CC_id],     // resource_block_start
-                                               rb_table[rb_table_index],  // number_of_resource_blocks
-                                               UE_template_ptr->mcs_UL[harq_pid],
-                                               cshift,    // cyclic_shift_2_for_drms
-                                               0,         // frequency_hopping_enabled_flag
-                                               0,         // frequency_hopping_bits
-                                               ndi,       // new_data_indication
-                                               0,         // redundancy_version
-                                               harq_pid,  // harq_process_number
-                                               0,         // ul_tx_mode
-                                               0,         // current_tx_nb
-                                               0,         // n_srs
-                                               get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]));
-
-          /* This is a BL/CE UE allocation */
-          if (UE_template_ptr->rach_resource_type > 0) {
-            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
-                                                 UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
-                                                 1,  // total_number_of_repetitions
-                                                 1,  // repetition_number
-                                                 (frameP * 10) + subframeP);
-          }
+      /* Add UL_config PDUs */
+      fill_nfapi_ulsch_config_request_rel8(
+          &ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+          cqi_req,
+          cc,
+          UE_template_ptr->physicalConfigDedicated,
+          get_tmode(module_idP, CC_id, UE_id),
+          mac->ul_handle,
+          rnti,
+          UE_template_ptr->pre_first_nb_rb_ul, // resource_block_start
+          rb_table[rb_table_index], // number_of_resource_blocks
+          mcs,
+          cshift, // cyclic_shift_2_for_drms
+          0, // frequency_hopping_enabled_flag
+          0, // frequency_hopping_bits
+          ndi, // new_data_indication
+          0, // redundancy_version
+          harq_pid, // harq_process_number
+          0, // ul_tx_mode
+          0, // current_tx_nb
+          0, // n_srs
+          get_TBS_UL(mcs, rb_table[rb_table_index]));
+
+      /* This is a BL/CE UE allocation */
+      if (UE_template_ptr->rach_resource_type > 0) {
+        fill_nfapi_ulsch_config_request_emtc(
+            &ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+            UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
+            1, // total_number_of_repetitions
+            1, // repetition_number
+            (frameP * 10) + subframeP);
+      }
 
-          if (dlsch_flag == 1) {
-            if (cqi_req == 1) {
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
-              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
-                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
-                rb_table[rb_table_index];
-            } else {
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
-              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
-                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
-            }
+      if (dlsch_flag == 1) {
+        if (cqi_req == 1) {
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+          ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+        } else {
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+          ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+        }
 
-            fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
-          } else {
-            ul_req_tmp_body->number_of_pdus++;
-          }
+        fill_nfapi_ulsch_harq_information(module_idP, CC_id, rnti, ulsch_harq_information, subframeP);
+      } else {
+        ul_req_tmp_body->number_of_pdus++;
+      }
 
-          ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
-          ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
-          mac->ul_handle++;
-          ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP;
-          add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED);
-          LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
-                module_idP,
-                CC_id,
-                frameP,
-                subframeP,
-                UE_id);
-          LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n",
-                harq_pid,
-                frameP,
-                subframeP,
-                sched_frame,
-                sched_subframeP,
-                cqi_req,
-                UE_id,
-                rnti);
-          /* Increment first rb for next UE allocation */
-          first_rb_slice[CC_id] += rb_table[rb_table_index];
-        } else { // round_index > 0 => retransmission
-          T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
-            T_INT(module_idP),
-            T_INT(CC_id),
-            T_INT(rnti),
-            T_INT(frameP),
-            T_INT(subframeP),
-            T_INT(harq_pid),
-            T_INT(UE_template_ptr->mcs_UL[harq_pid]),
-            T_INT(UE_template_ptr->first_rb_ul[harq_pid]),
-            T_INT(UE_template_ptr->nb_rb_ul[harq_pid]),
-            T_INT(round_index));
-          /* Add UL_config PDUs */
-          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
-                harq_pid,
+      ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
+      ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
+      mac->ul_handle++;
+      ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP;
+      add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED);
+      LOG_D(MAC,
+            "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for "
+            "next UE_id %d, format 0\n",
+            module_idP,
+            CC_id,
+            frameP,
+            subframeP,
+            UE_id);
+      LOG_D(
+          MAC,
+          "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n",
+          harq_pid,
+          frameP,
+          subframeP,
+          sched_frame,
+          sched_subframeP,
+          cqi_req,
+          UE_id,
+          rnti);
+    } else { // round_index > 0 => retransmission
+      uint8_t mcs_rv = 0;
+      const int rvidx_tab[4] = {0, 2, 3, 1};
+      uint8_t round_UL = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid];
+      if (rvidx_tab[round_UL & 3] == 1) {
+        mcs_rv = 29;
+      } else if (rvidx_tab[round_UL & 3] == 2) {
+        mcs_rv = 30;
+      } else if (rvidx_tab[round_UL & 3] == 3) {
+        mcs_rv = 31;
+      }
+
+      const uint16_t first_rb = UE_template_ptr->pre_first_nb_rb_ul;
+      const uint8_t nb_rb = UE_template_ptr->pre_allocated_nb_rb_ul;
+      if (first_rb != UE_template_ptr->first_rb_ul[harq_pid]
+          || nb_rb != UE_template_ptr->nb_rb_ul[harq_pid])
+        LOG_D(MAC,
+              "%4d.%d UE %4x retx: change freq allocation to %d RBs start %d (from %d RBs start %d)\n",
+              frameP,
+              subframeP,
+              rnti,
+              nb_rb,
+              first_rb,
+              UE_template_ptr->nb_rb_ul[harq_pid],
+              UE_template_ptr->first_rb_ul[harq_pid]);
+      UE_template_ptr->first_rb_ul[harq_pid] = first_rb;
+      UE_template_ptr->nb_rb_ul[harq_pid] = nb_rb;
+
+      T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
+        T_INT(module_idP),
+        T_INT(CC_id),
+        T_INT(rnti),
+        T_INT(frameP),
+        T_INT(subframeP),
+        T_INT(harq_pid),
+        T_INT(mcs_rv),
+        T_INT(first_rb),
+        T_INT(nb_rb),
+        T_INT(round_index));
+      /* Add UL_config PDUs */
+      LOG_D(MAC,
+            "[PUSCH %d] %4d.%d: Adding UL CONFIG.Request for UE "
+            "%d/%x, ulsch_frame %d, ulsch_subframe %d\n",
+            harq_pid,
+            frameP,
+            subframeP,
+            UE_id,
+            rnti,
+            sched_frame,
+            sched_subframeP);
+
+      hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[dci_ul_pdu_idx];
+      hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu);
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = nb_rb;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs_rv;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = UE_template_ptr->oldNDI_UL[harq_pid];
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = UE_template_ptr->cqi_req[harq_pid];
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP];
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid;
+
+      uint16_t ul_req_index = 0;
+      uint8_t dlsch_flag = 0;
+      uint32_t cqi_req = UE_template_ptr->cqi_req[harq_pid];
+      for (ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
+        if (ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
+            ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
+          dlsch_flag = 1;
+          LOG_D(MAC,
+                "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI "
+                "HARQ to ULSCH HARQ(first)\n",
                 frameP,
                 subframeP,
-                UE_id,
                 rnti,
-                sched_frame,
-                sched_subframeP);
-          ul_req_index = 0;
-          dlsch_flag = 0;
-          cqi_req = UE_template_ptr->cqi_req[harq_pid];
-
-          for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
-            if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
-                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
-              dlsch_flag = 1;
-              LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
-                    frameP,
-                    subframeP,
-                    rnti,
-                    ul_req_index);
-              break;
-            }
-          }
+                ul_req_index);
+          break;
+        }
+      }
 
-          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
-                                               cqi_req,
-                                               cc,
-                                               UE_template_ptr->physicalConfigDedicated,
-                                               get_tmode(module_idP, CC_id, UE_id),
-                                               mac->ul_handle,
-                                               rnti,
-                                               UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start
-                                               UE_template_ptr->nb_rb_ul[harq_pid],    // number_of_resource_blocks
-                                               UE_template_ptr->mcs_UL[harq_pid],
-                                               cshift, // cyclic_shift_2_for_drms
-                                               0,      // frequency_hopping_enabled_flag
-                                               0,      // frequency_hopping_bits
-                                               UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication
-                                               rvidx_tab[round_index & 3],           // redundancy_version
-                                               harq_pid,  // harq_process_number
-                                               0, // ul_tx_mode
-                                               0, // current_tx_nb
-                                               0, // n_srs
-                                               UE_template_ptr->TBS_UL[harq_pid]);
-
-          /* This is a BL/CE UE allocation */
-          if (UE_template_ptr->rach_resource_type > 0) {
-            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
-                                                 UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
-                                                 1, // total_number_of_repetitions
-                                                 1, // repetition_number
-                                                 (frameP * 10) + subframeP);
-          }
+      fill_nfapi_ulsch_config_request_rel8(
+          &ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+          cqi_req,
+          cc,
+          UE_template_ptr->physicalConfigDedicated,
+          get_tmode(module_idP, CC_id, UE_id),
+          mac->ul_handle,
+          rnti,
+          first_rb, // resource_block_start
+          nb_rb, // number_of_resource_blocks
+          mcs_rv,
+          cshift, // cyclic_shift_2_for_drms
+          0, // frequency_hopping_enabled_flag
+          0, // frequency_hopping_bits
+          UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication
+          rvidx_tab[round_index & 3], // redundancy_version
+          harq_pid, // harq_process_number
+          0, // ul_tx_mode
+          0, // current_tx_nb
+          0, // n_srs
+          UE_template_ptr->TBS_UL[harq_pid]);
+
+      /* This is a BL/CE UE allocation */
+      if (UE_template_ptr->rach_resource_type > 0) {
+        fill_nfapi_ulsch_config_request_emtc(
+            &ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
+            UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
+            1, // total_number_of_repetitions
+            1, // repetition_number
+            (frameP * 10) + subframeP);
+      }
 
-          if(dlsch_flag == 1) {
-            if(cqi_req == 1) {
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
-              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=
-                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
-                UE_template_ptr->nb_rb_ul[harq_pid];
-            } else {
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
-              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
-                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
-              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
-                UE_template_ptr->nb_rb_ul[harq_pid];
-            }
+      if (dlsch_flag == 1) {
+        if (cqi_req == 1) {
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+          ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template_ptr->nb_rb_ul[harq_pid];
+        } else {
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+          ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured
+          ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template_ptr->nb_rb_ul[harq_pid];
+        }
 
-            fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP);
-          } else {
-            ul_req_tmp_body->number_of_pdus++;
-          }
+        fill_nfapi_ulsch_harq_information(module_idP, CC_id, rnti, ulsch_harq_information, subframeP);
+      } else {
+        ul_req_tmp_body->number_of_pdus++;
+      }
 
-          mac->ul_handle++;
-          ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
-          ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP;
-          ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
-          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n",
-                harq_pid,
-                frameP,
-                subframeP,
-                UE_id,
-                rnti,
-                sched_frame,
-                sched_subframeP,
-                cqi_req);
-
-          /* HACK: RBs used by retransmission have to be reserved.
-           * The current mechanism uses the notion of 'first_rb', so
-           * we skip all RBs below the ones retransmitted. This is
-           * not correct. Imagine only RB 23 is retransmitted, then all
-           * RBs < 23 will be marked unusable for new transmissions (case where round == 0).
-           * Note also that this code works only if the preprocessor orders
-           * UEs with retransmission with higher priority than UEs with new
-           * transmission.
-           * All this should be cleaned up properly.
-           */
-          if (first_rb_slice[CC_id] < UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid])
-            first_rb_slice[CC_id] = UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid];
-        }  // end of round > 0
-      }  // UE_is_to_be_scheduled
-    }  // loop over all active CC_ids
-  }  // loop over UE_ids
+      mac->ul_handle++;
+      ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
+      ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP;
+      ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
+      LOG_D(MAC,
+            "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE "
+            "%d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n",
+            harq_pid,
+            frameP,
+            subframeP,
+            UE_id,
+            rnti,
+            sched_frame,
+            sched_subframeP,
+            cqi_req);
+    } // end of round > 0
+  } // loop over UE_ids
 }
 
 
@@ -1926,7 +1871,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
   eNB_MAC_INST      *eNB = RC.mac[module_idP];
   eNB_RRC_INST      *rrc = RC.rrc[module_idP];
   COMMON_channels_t *cc  = eNB->common_channels;
-  UE_list_t         *UE_list = &(eNB->UE_list);
+  UE_info_t         *UE_info = &eNB->UE_info;
   UE_TEMPLATE       *UE_template = NULL;
   UE_sched_ctrl_t     *UE_sched_ctrl = NULL;
   uint8_t     Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13;
@@ -1944,8 +1889,8 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
   nfapi_ul_config_request_pdu_t  *ul_config_pdu_Rep;
 
   /* Loop over all active UEs */
-  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    UE_template = &(UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]);
+  for (UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    UE_template = &UE_info->UE_template[UE_PCCID(module_idP, UE_id)][UE_id];
 
     /* LTE-M device */
     if (UE_template->rach_resource_type == 0) {
@@ -1974,12 +1919,12 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
     }
 
     /* Loop over all active UL CC_ids for this UE */
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
+    for (n = 0; n < UE_info->numactiveULCCs[UE_id]; n++) {
       /* This is the actual CC_id in the list */
-      CC_id        = UE_list->ordered_ULCCids[n][UE_id];
+      CC_id        = UE_info->ordered_ULCCids[n][UE_id];
       N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
-      UE_template   = &(UE_list->UE_template[CC_id][UE_id]);
-      UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+      UE_template   = &UE_info->UE_template[CC_id][UE_id];
+      UE_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
       harq_pid      = 0;
       round_UL      = UE_sched_ctrl->round_UL[CC_id][harq_pid];
       AssertFatal(round_UL < 8,"round_UL %d > 7 for UE %d/%x\n",
@@ -2027,6 +1972,12 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                 UE_sched_ctrl->cqi_req_timer);
           /* Reset the scheduling request */
           emtc_active[CC_id] = 1;
+          cc[CC_id].vrb_map_UL[1] = 1;
+          cc[CC_id].vrb_map_UL[2] = 1;
+          cc[CC_id].vrb_map_UL[3] = 1;
+          cc[CC_id].vrb_map_UL[4] = 1;
+          cc[CC_id].vrb_map_UL[5] = 1;
+          cc[CC_id].vrb_map_UL[6] = 1;
           UE_template->ul_SR = 0;
           status = mac_eNB_get_rrc_status(module_idP,rnti);
           cqi_req = 0;
@@ -2074,12 +2025,12 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
             UE_template->oldNDI_UL[harq_pid] = ndi;
             UE_template->mcs_UL[harq_pid] = 4;
             UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6);
-            UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
-            UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
-            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4;
-            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid];
-            UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6;
-            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid];
+            UE_info->eNB_UE_stats[CC_id][UE_id].snr = snr;
+            UE_info->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
+            UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4;
+            UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid];
+            UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6;
+            UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid];
             T(T_ENB_MAC_UE_UL_SCHEDULE,
               T_INT(module_idP),
               T_INT(CC_id),
@@ -2096,7 +2047,7 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
             UE_template->nb_rb_ul[harq_pid]    = 6;
             UE_sched_ctrl->ul_scheduled |= (1 << harq_pid);
 
-            if (UE_id == UE_list->head) {
+            if (UE_id == UE_info->list.head) {
               VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled);
             }
 
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index ac9819cfe28..329e262c828 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -824,11 +824,16 @@ typedef struct {
   uint16_t cshift[8];   // num_max_harq
 
   /// Number of Allocated RBs by the ulsch preprocessor
-  uint8_t pre_allocated_nb_rb_ul[MAX_NUM_SLICES];
+  uint8_t pre_allocated_nb_rb_ul;
+  /// Start of Allocated RBs by the USLCH preprocessor
+  uint8_t pre_first_nb_rb_ul;
 
   /// index of Allocated RBs by the ulsch preprocessor
   int8_t pre_allocated_rb_table_index_ul;
 
+  /// index of allocated HI_DCI0
+  int pre_dci_ul_pdu_idx;
+
   /// total allocated RBs
   int8_t total_allocated_rbs;
 
@@ -852,10 +857,10 @@ typedef struct {
 
   // Logical channel info for link with RLC
 
-  /// LCGID mapping
+  /// LCGID mapping (UL)
   long lcgidmap[11];
 
-  ///UE logical channel priority
+  ///UE logical channel priority (UL)
   long lcgidpriority[11];
 
   /// phr information
@@ -913,31 +918,12 @@ typedef struct {
 
 /*! \brief scheduling control information set through an API (not used)*/
 typedef struct {
-  ///UL transmission bandwidth in RBs
-  uint8_t ul_bandwidth[MAX_NUM_LCID];
-  ///DL transmission bandwidth in RBs
-  uint8_t dl_bandwidth[MAX_NUM_LCID];
-
-  //To do GBR bearer
-  uint8_t min_ul_bandwidth[MAX_NUM_LCID];
-
-  uint8_t min_dl_bandwidth[MAX_NUM_LCID];
-
-  ///aggregated bit rate of non-gbr bearer per UE
-  uint64_t ue_AggregatedMaximumBitrateDL;
-  ///aggregated bit rate of non-gbr bearer per UE
-  uint64_t ue_AggregatedMaximumBitrateUL;
-  ///CQI scheduling interval in subframes.
-  uint16_t cqiSchedInterval;
-  ///Contention resolution timer used during random access
-  uint8_t mac_ContentionResolutionTimer;
-
-  uint16_t max_rbs_allowed_slice[NFAPI_CC_MAX][MAX_NUM_SLICES];
-  uint16_t max_rbs_allowed_slice_uplink[NFAPI_CC_MAX][MAX_NUM_SLICES];
-
-  uint8_t max_mcs[MAX_NUM_LCID];
-
-  uint16_t priority[MAX_NUM_LCID];
+  /// number of active DL LCs
+  uint8_t dl_lc_num;
+  /// order in which DLSCH scheduler should allocate LCs
+  uint8_t dl_lc_ids[MAX_NUM_LCID];
+  /// number of bytes to schedule for each LC
+  uint32_t dl_lc_bytes[MAX_NUM_LCID];
 
   // resource scheduling information
 
@@ -950,6 +936,7 @@ typedef struct {
   uint8_t dl_pow_off[NFAPI_CC_MAX];
   uint16_t pre_nb_available_rbs[NFAPI_CC_MAX];
   unsigned char rballoc_sub_UE[NFAPI_CC_MAX][N_RBG_MAX];
+  int pre_dci_dl_pdu_idx;
   uint16_t ta_timer;
   int16_t ta_update;
   uint16_t ul_consecutive_errors;
@@ -1130,7 +1117,15 @@ typedef struct {
   uint8_t sb_size;
   uint8_t nb_active_sb;
 } SBMAP_CONF;
-/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
+
+/*! \brief UE_list_t is a "list" of users within UE_info_t. Especial useful in
+ * the scheduler and to keep "classes" of users. */
+typedef struct {
+  int head;
+  int next[MAX_MOBILES_PER_ENB];
+} UE_list_t;
+
+/*! \brief UE info used by eNB to order UEs/CC for scheduling*/
 typedef struct {
 
   DLSCH_PDU DLSCH_pdu[NFAPI_CC_MAX][2][MAX_MOBILES_PER_ENB];
@@ -1152,21 +1147,13 @@ typedef struct {
   eNB_UE_STATS eNB_UE_stats[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
   /// scheduling control info
   UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_ENB];
-  int next[MAX_MOBILES_PER_ENB];
-  int head;
-  int next_ul[MAX_MOBILES_PER_ENB];
-  int head_ul;
-  int avail;
+  UE_list_t list;
   int num_UEs;
   boolean_t active[MAX_MOBILES_PER_ENB];
 
   /// Sorting criteria for the UE list in the MAC preprocessor
   uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM];
-  uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES];
-
-  int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB];
-  int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB];
-} UE_list_t;
+} UE_info_t;
 
 /*! \brief deleting control information*/
 typedef struct {
@@ -1184,20 +1171,6 @@ typedef struct {
   int tail_freelist; ///the tail position of the delete list
 } UE_free_list_t;
 
-/// Structure for saving the output of each pre_processor instance
-typedef struct {
-  uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  uint8_t  slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
-  uint8_t  MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX];
-
-  uint32_t bytes_lcid[MAX_MOBILES_PER_ENB][MAX_NUM_LCID];
-  uint32_t wb_pmi[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  uint8_t  mcs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-
-} pre_processor_results_t;
-
 /**
  * slice specific scheduler for the DL
  */
@@ -1289,12 +1262,18 @@ typedef struct {
   int      n_ul;
   slice_sched_conf_ul_t ul[MAX_NUM_SLICES];
 
-  pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
-
   /// common rb allocation list between slices
   uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX];
 } slice_info_t;
 
+/**
+ * describes contiguous RBs
+ */
+typedef struct {
+  int start;
+  int length;
+} contig_rbs_t;
+
 /*! \brief eNB common channels */
 typedef struct {
   int physCellId;
@@ -1414,7 +1393,7 @@ typedef struct eNB_MAC_INST_s {
   nfapi_ue_release_request_t UE_release_req;
   /// UL handle
   uint32_t ul_handle;
-  UE_list_t UE_list;
+  UE_info_t UE_info;
 
   /// slice-related configuration
   slice_info_t slice_info;
diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h
index dbf5b57b6b2..cee6066a9eb 100644
--- a/openair2/LAYER2/MAC/mac_extern.h
+++ b/openair2/LAYER2/MAC/mac_extern.h
@@ -60,7 +60,7 @@ extern uint16_t NB_THREAD_INST;
 extern unsigned char NB_RN_INST;
 extern unsigned short NODE_ID[1];
 
-extern int cqi_to_mcs[16];
+extern const int cqi_to_mcs[16];
 
 extern uint32_t RRC_CONNECTION_FLAG;
 
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index 476fb685848..2cb86c25af2 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -122,15 +122,14 @@ void schedule_ulsch(module_id_t module_idP, frame_t frameP,
 
 /** \brief ULSCH Scheduling per RNTI
 @param Mod_id Instance ID of eNB
-@param slice_idx Slice instance index for this eNB
+@param CC_id The component carrier to schedule
 @param frame Frame index
 @param subframe Subframe number on which to act
 @param sched_subframe Subframe number where PUSCH is transmitted (for DAI lookup)
 */
-void schedule_ulsch_rnti(module_id_t module_idP, int slice_idx, frame_t frameP,
+void schedule_ulsch_rnti(module_id_t module_idP, int CC_id, frame_t frameP,
                          sub_frame_t subframe,
-                         unsigned char sched_subframe,
-                         uint16_t *first_rb);
+                         unsigned char sched_subframe);
 
 void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                               frame_t       frameP,
@@ -138,14 +137,6 @@ void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
                               unsigned char sched_subframeP,
                               int          *emtc_active);
 
-/** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called.  This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY.  It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation.  It assumes localized allocation of type 0 (DCI.rah=0).  The allocation is done for tranmission modes 1,2,4.
-@param Mod_id Instance of eNB
-@param frame Frame index
-@param subframe Index of subframe
-@param mbsfn_flag Indicates that this subframe is for MCH/MCCH
-*/
-void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag);
-
 /** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
 @param Mod_id Instance ID of eNB
 @param frame Frame index
@@ -156,8 +147,10 @@ void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,i
 void schedule_dlsch(module_id_t module_idP, frame_t frameP,
                     sub_frame_t subframe, int *mbsfn_flag);
 
-void schedule_ue_spec(module_id_t module_idP, int slice_idxP,
-                      frame_t frameP,sub_frame_t subframe, int *mbsfn_flag);
+void schedule_ue_spec(module_id_t module_idP,
+                      int CC_id,
+                      frame_t frameP,
+                      sub_frame_t subframe);
 void schedule_ue_spec_br(module_id_t   module_idP,
                          frame_t       frameP,
                          sub_frame_t   subframeP);
@@ -192,7 +185,7 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
 
 //main.c
 
-void init_UE_list(UE_list_t *UE_list);
+void init_UE_info(UE_info_t *UE_info);
 
 void init_slice_info(slice_info_t *sli);
 
@@ -231,73 +224,9 @@ void clear_nfapi_information(eNB_MAC_INST *eNB, int CC_idP,
 
 
 void dlsch_scheduler_pre_processor(module_id_t module_idP,
-                                   int slice_idxP,
+                                   int CC_id,
                                    frame_t frameP,
-                                   sub_frame_t subframe,
-                                   int *mbsfn_flag,
-                                   uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]);
-
-void dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
-    int slice_idx,
-    frame_t frameP,
-    sub_frame_t subframeP,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
-    int *mbsfn_flag);
-
-void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
-    int slice_idx,
-    const uint8_t rbs_retx[NFAPI_CC_MAX]);
-
-void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
-    int slice_idx,
-    frame_t frameP,
-    sub_frame_t subframeP,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]);
-
-void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id,
-    int slice_idx,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
-
-void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
-    int slice_idx,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
-
-void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]);
-
-void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
-    int frameP,
-    sub_frame_t subframeP,
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]);
-
-void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id,
-                                      int frameP,
-                                      sub_frame_t subframeP);
-
-void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
-    int UE_id,
-    uint8_t CC_id,
-    int N_RBG,
-    int min_rb_unit,
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
+                                   sub_frame_t subframe);
 
 /* \brief Function to trigger the eNB scheduling procedure.  It is called by PHY at the beginning of each subframe, \f$n$\f
    and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f.
@@ -484,10 +413,23 @@ boolean_t CCE_allocation_infeasible(int module_idP,
                                     int common_flag,
                                     int subframe,
                                     int aggregation, int rnti);
+/* tries to allocate a CCE. If it succeeds, reserves NFAPI DCI and DLSCH config */
+int CCE_try_allocate_dlsch(int module_id,
+                           int CC_id,
+                           int subframe,
+                           int UE_id,
+                           uint8_t dl_cqi);
+
+/* tries to allocate a CCE for UL. If it succeeds, reserves the NFAPI DCI */
+int CCE_try_allocate_ulsch(int module_id,
+                           int CC_id,
+                           int subframe,
+                           int UE_id,
+                           uint8_t dl_cqi);
 
 void set_ue_dai(sub_frame_t subframeP,
                 int UE_id,
-                uint8_t CC_id, uint8_t tdd_config, UE_list_t *UE_list);
+                uint8_t CC_id, uint8_t tdd_config, UE_info_t *UE_info);
 
 uint8_t frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP);
 /** \brief First stage of PCH Scheduling. Gets a PCH SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length.  It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@@ -510,14 +452,6 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
 module_id_t schedule_next_ulue(module_id_t module_idP, int UE_id,
                                sub_frame_t subframe);
 
-/** \brief Round-robin scheduler for DLSCH traffic.
-@param Mod_id Instance ID for eNB
-@param subframe Subframe number on which to act
-@returns UE index that is to be scheduled if needed/room
-*/
-int schedule_next_dlue(module_id_t module_idP, int CC_id,
-                       sub_frame_t subframe);
-
 /* \brief Allocates a set of PRBS for a particular UE.  This is a simple function for the moment, later it should process frequency-domain CQI information and/or PMI information.  Currently it just returns the first PRBS that are available in the subframe based on the number requested.
 @param UE_id Index of UE on which to act
 @param nb_rb Number of PRBs allocated to UE by scheduler
@@ -721,13 +655,13 @@ int mac_init(void);
 int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid, uint8_t rach_resource_type);
 int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP);
 
-void store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP);
-void assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]);
+void store_dlsch_buffer(module_id_t Mod_id, int CC_id, frame_t frameP, sub_frame_t subframeP);
 
-void swap_UEs(UE_list_t *listP, int nodeiP, int nodejP, int ul_flag);
-int prev(UE_list_t *listP, int nodeP, int ul_flag);
-void dump_ue_list(UE_list_t *listP, int ul_flag);
-int UE_num_active_CC(UE_list_t *listP, int ue_idP);
+int prev(UE_list_t *listP, int nodeP);
+void add_ue_list(UE_list_t *listP, int UE_id);
+int remove_ue_list(UE_list_t *listP, int UE_id);
+void dump_ue_list(UE_list_t *listP);
+int UE_num_active_CC(UE_info_t *listP, int ue_idP);
 int UE_PCCID(module_id_t mod_idP, int ue_idP);
 rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
 
@@ -739,20 +673,14 @@ void set_ul_DAI(int module_idP,
                 int frameP,
                 int subframeP);
 
-void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP,
+void ulsch_scheduler_pre_processor(module_id_t module_idP,
+                                   int CC_id,
+                                   int frameP,
                                    sub_frame_t subframeP,
                                    int sched_frameP,
-                                   unsigned char sched_subframeP,
-                                   uint16_t *first_rb);
-void store_ulsch_buffer(module_id_t module_idP, int frameP,
-                        sub_frame_t subframeP);
-void assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP,
-                           sub_frame_t subframeP, uint16_t *first_rb);
-void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
-                     UE_TEMPLATE *UE_template);
+                                   unsigned char sched_subframeP);
 
 int phy_stats_exist(module_id_t Mod_id, int rnti);
-void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP);
 
 /*! \fn  UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index)
    \brief UE scheduler where all the ue background tasks are done.  This function performs the following:  1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures.
@@ -913,8 +841,7 @@ void add_common_dci(DCI_PDU *DCI_pdu,
                     uint8_t ra_flag);
 */
 
-uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG,
-                           uint8_t *rballoc);
+uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, const uint8_t *rballoc);
 
 void update_ul_dci(module_id_t module_idP, uint8_t CC_id, rnti_t rnti,
                    uint8_t dai, sub_frame_t subframe);
@@ -1176,14 +1103,13 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP,
                           frame_t frameP, sub_frame_t subframeP,
                           uint8_t cce_idx);
 
-void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
-                             nfapi_dl_config_request_body_t *dl_req,
+void fill_nfapi_dlsch_config(nfapi_dl_config_request_pdu_t *dl_config_pdu,
                              uint16_t length, int16_t pdu_index,
                              uint16_t rnti,
                              uint8_t resource_allocation_type,
                              uint8_t
                              virtual_resource_block_assignment_flag,
-                             uint16_t resource_block_coding,
+                             uint32_t resource_block_coding,
                              uint8_t modulation,
                              uint8_t redundancy_version,
                              uint8_t transport_blocks,
@@ -1277,11 +1203,6 @@ void pre_scd_nb_rbs_required(    module_id_t     module_idP,
                                  uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]);
 #endif
 
-/* Slice related functions */
-uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs);
-int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx);
-int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx);
-
 /* DRX Configuration */
 /* Configure local DRX timers and thresholds in UE context, following the drx_configuration input */
 void eNB_Config_Local_DRX(instance_t Mod_id, rrc_mac_drx_config_req_t *rrc_mac_drx_config_req);                        
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index fe8980101dc..1a88623a1f3 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -43,26 +43,18 @@
 
 extern RAN_CONTEXT_t RC;
 
-void init_UE_list(UE_list_t *UE_list)
+void init_UE_info(UE_info_t *UE_info)
 {
   int list_el;
-  UE_list->num_UEs = 0;
-  UE_list->head = -1;
-  UE_list->head_ul = -1;
-  UE_list->avail = 0;
-  for (list_el = 0; list_el < MAX_MOBILES_PER_ENB - 1; list_el++) {
-    UE_list->next[list_el] = list_el + 1;
-    UE_list->next_ul[list_el] = list_el + 1;
-  }
-  UE_list->next[list_el] = -1;
-  UE_list->next_ul[list_el] = -1;
-  memset(UE_list->DLSCH_pdu, 0, sizeof(UE_list->DLSCH_pdu));
-  memset(UE_list->UE_template, 0, sizeof(UE_list->UE_template));
-  memset(UE_list->eNB_UE_stats, 0, sizeof(UE_list->eNB_UE_stats));
-  memset(UE_list->UE_sched_ctrl, 0, sizeof(UE_list->UE_sched_ctrl));
-  memset(UE_list->active, 0, sizeof(UE_list->active));
-  memset(UE_list->assoc_dl_slice_idx, 0, sizeof(UE_list->assoc_dl_slice_idx));
-  memset(UE_list->assoc_ul_slice_idx, 0, sizeof(UE_list->assoc_ul_slice_idx));
+  UE_info->num_UEs = 0;
+  UE_info->list.head = -1;
+  for (list_el = 0; list_el < MAX_MOBILES_PER_ENB; list_el++)
+    UE_info->list.next[list_el] = -1;
+  memset(UE_info->DLSCH_pdu, 0, sizeof(UE_info->DLSCH_pdu));
+  memset(UE_info->UE_template, 0, sizeof(UE_info->UE_template));
+  memset(UE_info->eNB_UE_stats, 0, sizeof(UE_info->eNB_UE_stats));
+  memset(UE_info->UE_sched_ctrl, 0, sizeof(UE_info->UE_sched_ctrl));
+  memset(UE_info->active, 0, sizeof(UE_info->active));
 }
 
 void init_slice_info(slice_info_t *sli)
@@ -137,7 +129,7 @@ void mac_top_init_eNB(void)
 
     mac[i]->if_inst = IF_Module_init(i);
 
-    init_UE_list(&mac[i]->UE_list);
+    init_UE_info(&mac[i]->UE_info);
     init_slice_info(&mac[i]->slice_info);
   }
 
@@ -163,12 +155,12 @@ void mac_init_cell_params(int Mod_idP, int CC_idP)
 
     memset(&RC.mac[Mod_idP]->eNB_stats, 0, sizeof(eNB_STATS));
     UE_template =
-	(UE_TEMPLATE *) & RC.mac[Mod_idP]->UE_list.UE_template[CC_idP][0];
+	(UE_TEMPLATE *) & RC.mac[Mod_idP]->UE_info.UE_template[CC_idP][0];
 
     for (j = 0; j < MAX_MOBILES_PER_ENB; j++) {
 	UE_template[j].rnti = 0;
 	// initiallize the eNB to UE statistics
-	memset(&RC.mac[Mod_idP]->UE_list.eNB_UE_stats[CC_idP][j], 0,
+	memset(&RC.mac[Mod_idP]->UE_info.eNB_UE_stats[CC_idP][j], 0,
 	       sizeof(eNB_UE_STATS));
     }
 
@@ -263,4 +255,4 @@ void *mac_enb_task(void *arg)
   } // end while
 
   return NULL;
-}
\ No newline at end of file
+}
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index bd4e4de2a46..8569d8f1666 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -36,6 +36,7 @@
 #include "LAYER2/MAC/mac.h"
 #include "LAYER2/MAC/mac_proto.h"
 #include "LAYER2/MAC/mac_extern.h"
+#include <openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h>
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "UTIL/OPT/opt.h"
@@ -50,109 +51,247 @@
 
 extern RAN_CONTEXT_t RC;
 
-#define DEBUG_eNB_SCHEDULER 1
+#define DEBUG_eNB_SCHEDULER
 #define DEBUG_HEADER_PARSING 1
-//#define DEBUG_PACKET_TRACE 1
 
-//#define ICIC 0
+int next_ue_list_looped(UE_list_t* list, int UE_id) {
+  if (UE_id < 0)
+    return list->head;
+  return list->next[UE_id] < 0 ? list->head : list->next[UE_id];
+}
 
-void
-sort_ue_ul(module_id_t module_idP,
-           int slice_idx,
-           int sched_frameP,
-           sub_frame_t sched_subframeP,
-           rnti_t *rntiTable);
-
-/* this function checks that get_eNB_UE_stats returns
- * a non-NULL pointer for all the active CCs of an UE
- */
-/*
-int phy_stats_exist(module_id_t Mod_id, int rnti)
-{
-  int CC_id;
-  int i;
-  int UE_id          = find_UE_id(Mod_id, rnti);
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  if (UE_id == -1) {
-    LOG_W(MAC, "[eNB %d] UE %x not found, should be there (in phy_stats_exist)\n",
-    Mod_id, rnti);
-    return 0;
+int get_rbg_size_last(module_id_t Mod_id, int CC_id) {
+  const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
+  const int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+  if (N_RB_DL == 15 || N_RB_DL == 25 || N_RB_DL == 50 || N_RB_DL == 75)
+    return RBGsize - 1;
+  else
+    return RBGsize;
+}
+
+int g_start_ue_dl = -1;
+int round_robin_dl(module_id_t Mod_id,
+                   int CC_id,
+                   int frame,
+                   int subframe,
+                   UE_list_t *UE_list,
+                   int max_num_ue,
+                   int n_rbg_sched,
+                   uint8_t *rbgalloc_mask) {
+  DevAssert(UE_list->head >= 0);
+  DevAssert(n_rbg_sched > 0);
+  const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+  const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
+  const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id);
+  int num_ue_req = 0;
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+
+  int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request
+  memset(rb_required, 0, sizeof(rb_required));
+
+  int rbg = 0;
+  for (; !rbgalloc_mask[rbg]; rbg++)
+    ; /* fast-forward to first allowed RBG */
+
+  // Calculate the amount of RBs every UE wants to send.
+  for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+    // check whether there are HARQ retransmissions
+    const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+    const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe);
+    UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    const uint8_t round = ue_ctrl->round[CC_id][harq_pid];
+    if (round != 8) { // retransmission: allocate
+      const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+      if (nb_rb == 0)
+        continue;
+      int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize;
+      // needs more RBGs than we can allocate
+      if (nb_rbg > n_rbg_sched) {
+        LOG_D(MAC,
+              "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n",
+              UE_id, nb_rbg, n_rbg_sched);
+        continue;
+      }
+      // ensure that the number of RBs can be contained by the RBGs (!), i.e.
+      // if we allocate the last RBG this one should have the full RBGsize
+      if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched
+          && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) {
+        LOG_D(MAC,
+              "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n",
+              UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize);
+        continue;
+      }
+      const uint8_t cqi = ue_ctrl->dl_cqi[CC_id];
+      const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+      if (idx < 0)
+        continue; // cannot allocate CCE
+      ue_ctrl->pre_dci_dl_pdu_idx = idx;
+      // retransmissions: directly allocate
+      n_rbg_sched -= nb_rbg;
+      ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb;
+      for (; nb_rbg > 0; rbg++) {
+        if (!rbgalloc_mask[rbg])
+          continue;
+        ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+        nb_rbg--;
+      }
+      LOG_D(MAC,
+            "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d "
+            "round %d retx nb_rb %d pre_nb_available_rbs %d\n",
+            frame, subframe, n_rbg_sched, UE_id, round,
+            UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid],
+            ue_ctrl->pre_nb_available_rbs[CC_id]);
+      /* if there are no more RBG to give, return */
+      if (n_rbg_sched <= 0)
+        return 0;
+      max_num_ue--;
+      /* if there are no UEs that can be allocated anymore, return */
+      if (max_num_ue == 0)
+        return n_rbg_sched;
+      for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
+    } else {
+      const int dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
+      UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = dlsch_mcs1;
+      rb_required[UE_id] =
+          find_nb_rb_DL(dlsch_mcs1,
+                        UE_info->UE_template[CC_id][UE_id].dl_buffer_total,
+                        n_rbg_sched * RBGsize,
+                        RBGsize);
+      if (rb_required[UE_id] > 0)
+        num_ue_req++;
+      LOG_D(MAC,
+            "%d/%d UE_id %d rb_required %d n_rbg_sched %d\n",
+            frame,
+            subframe,
+            UE_id,
+            rb_required[UE_id],
+            n_rbg_sched);
+    }
+  }
+
+  if (num_ue_req == 0)
+    return n_rbg_sched; // no UE has a transmission
+
+  // after allocating retransmissions: build list of UE to allocate.
+  // if start_UE does not exist anymore (detach etc), start at first UE
+  if (g_start_ue_dl == -1)
+    g_start_ue_dl = UE_list->head;
+  int UE_id = g_start_ue_dl;
+  UE_list_t UE_sched;
+  int rb_required_total = 0;
+  int num_ue_sched = 0;
+  max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched);
+  int *cur_UE = &UE_sched.head;
+  while (num_ue_sched < max_num_ue) {
+    while (rb_required[UE_id] == 0)
+      UE_id = next_ue_list_looped(UE_list, UE_id);
+    const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
+    const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi);
+    if (idx < 0) {
+      LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id);
+      num_ue_req--;
+      max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched);
+      UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate
+      continue;
+    }
+    UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx;
+    *cur_UE = UE_id;
+    cur_UE = &UE_sched.next[UE_id];
+    rb_required_total += rb_required[UE_id];
+    num_ue_sched++;
+    UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate
   }
-  if (UE_list->numactiveCCs[UE_id] == 0) {
-    LOG_W(MAC, "[eNB %d] UE %x has no active CC (in phy_stats_exist)\n",
-    Mod_id, rnti);
-    return 0;
+  *cur_UE = -1;
+
+  /* for one UE after the next: allocate resources */
+  for (int UE_id = UE_sched.head; UE_id >= 0;
+       UE_id = next_ue_list_looped(&UE_sched, UE_id)) {
+    if (rb_required[UE_id] <= 0)
+      continue;
+    UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1;
+    const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize;
+    ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG;
+    rb_required[UE_id] -= sRBG;
+    rb_required_total -= sRBG;
+    if (rb_required_total <= 0)
+      break;
+    n_rbg_sched--;
+    if (n_rbg_sched <= 0)
+      break;
+    for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ;
   }
-  for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
-    CC_id = UE_list->ordered_CCids[i][UE_id];
-    if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL)
-      return 0;
+
+  /* if not all UEs could be allocated in this round */
+  if (num_ue_req > max_num_ue) {
+    /* go to the first one we missed */
+    for (int i = 0; i < max_num_ue; ++i)
+      g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl);
+  } else {
+    /* else, just start with the next UE next time */
+    g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl);
   }
-  return 1;
+
+  return n_rbg_sched;
 }
-*/
 
 // This function stores the downlink buffer for all the logical channels
 void
 store_dlsch_buffer(module_id_t Mod_id,
-                   int slice_idx,
+                   int CC_id,
                    frame_t frameP,
                    sub_frame_t subframeP) {
-  int UE_id, lcid;
-  rnti_t rnti;
-  mac_rlc_status_resp_t rlc_status;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  UE_TEMPLATE *UE_template;
-
-  for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-    if (UE_list->active[UE_id] != TRUE)
-      continue;
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
 
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx))
-      continue;
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
 
-    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id];
-    // clear logical channel interface variables
+    UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
+    UE_sched_ctrl_t *UE_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
     UE_template->dl_buffer_total = 0;
     UE_template->dl_pdus_total = 0;
 
-    for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) {
-      UE_template->dl_buffer_info[lcid] = 0;
-      UE_template->dl_pdus_in_buffer[lcid] = 0;
-      UE_template->dl_buffer_head_sdu_creation_time[lcid] = 0;
-      UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = 0;
-    }
-
-    rnti = UE_RNTI(Mod_id, UE_id);
-
-    for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) {    // loop over all the logical channels
-      rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
-                                      ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0,0, 0
-                                     );
-      UE_template->dl_buffer_info[lcid] = rlc_status.bytes_in_buffer;    //storing the dlsch buffer for each logical channel
+    /* loop over all activated logical channels */
+    for (int i = 0; i < UE_sched_ctrl->dl_lc_num; ++i) {
+      const int lcid = UE_sched_ctrl->dl_lc_ids[i];
+      const mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(Mod_id,
+                                                                  UE_template->rnti,
+                                                                  Mod_id,
+                                                                  frameP,
+                                                                  subframeP,
+                                                                  ENB_FLAG_YES,
+                                                                  MBMS_FLAG_NO,
+                                                                  lcid,
+                                                                  0,
+                                                                  0
+                                                                 );
+      UE_template->dl_buffer_info[lcid] = rlc_status.bytes_in_buffer;
       UE_template->dl_pdus_in_buffer[lcid] = rlc_status.pdus_in_buffer;
       UE_template->dl_buffer_head_sdu_creation_time[lcid] = rlc_status.head_sdu_creation_time;
       UE_template->dl_buffer_head_sdu_creation_time_max =
         cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time);
       UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = rlc_status.head_sdu_remaining_size_to_send;
       UE_template->dl_buffer_head_sdu_is_segmented[lcid] = rlc_status.head_sdu_is_segmented;
-      UE_template->dl_buffer_total += UE_template->dl_buffer_info[lcid];    //storing the total dlsch buffer
+      UE_template->dl_buffer_total += UE_template->dl_buffer_info[lcid];
       UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[lcid];
-#ifdef DEBUG_eNB_SCHEDULER
 
+      /* update the number of bytes in the UE_sched_ctrl. The DLSCH will use
+       * this to request the corresponding data from the RLC, and this might be
+       * limited in the preprocessor */
+      UE_sched_ctrl->dl_lc_bytes[i] = rlc_status.bytes_in_buffer;
+
+#ifdef DEBUG_eNB_SCHEDULER
       /* note for dl_buffer_head_sdu_remaining_size_to_send[lcid] :
        * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
        */
       if (UE_template->dl_buffer_info[lcid] > 0)
         LOG_D(MAC,
-              "[eNB %d][SLICE %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
-              Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, frameP,
+              "[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
+              Mod_id, frameP,
               subframeP, UE_id, lcid, UE_template->dl_pdus_in_buffer[lcid],
               UE_template->dl_buffer_info[lcid],
               UE_template->dl_buffer_head_sdu_creation_time[lcid],
               UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid],
               UE_template->dl_buffer_head_sdu_is_segmented[lcid]);
-
 #endif
     }
 
@@ -165,1914 +304,572 @@ store_dlsch_buffer(module_id_t Mod_id,
   }
 }
 
-int cqi2mcs(int cqi) {
-  return cqi_to_mcs[cqi];
-}
 
-// This function returns the estimated number of RBs required by each UE for downlink scheduling
+// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
 void
-assign_rbs_required(module_id_t Mod_id,
-                    int slice_idx,
-                    frame_t frameP,
-                    sub_frame_t subframe,
-                    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-                    int min_rb_unit[NFAPI_CC_MAX]) {
-  uint16_t TBS = 0;
-  int UE_id, n, i, j, CC_id, pCCid, tmp;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
-  eNB_UE_STATS *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
-  int N_RB_DL;
-
-  // clear rb allocations across all CC_id
-  for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) {
-    if (UE_list->active[UE_id] != TRUE) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    pCCid = UE_PCCID(Mod_id, UE_id);
-
-    //update CQI information across component carriers
-    for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
-      CC_id = UE_list->ordered_CCids[n][UE_id];
-      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
-      //      eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_idx].maxmcs);
-      eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_idx].maxmcs);
-    }
-
-    // provide the list of CCs sorted according to MCS
-    for (i = 0; i < UE_list->numactiveCCs[UE_id]; ++i) {
-      eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id];
-
-      for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) {
-        DevAssert(j < NFAPI_CC_MAX);
-        eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id];
-
-        if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) {
-          tmp = UE_list->ordered_CCids[i][UE_id];
-          UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id];
-          UE_list->ordered_CCids[j][UE_id] = tmp;
-        }
-      }
-    }
-
-    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total > 0) {
-      LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
-
-      for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
-        CC_id = UE_list->ordered_CCids[i][UE_id];
-        eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
-
-        if (eNB_UE_stats->dlsch_mcs1 == 0) {
-          nb_rbs_required[CC_id][UE_id] = 4;    // don't let the TBS get too small
-        } else {
-          nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
-        }
-
-        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]);
-        LOG_D(MAC,
-              "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
-              UE_id, CC_id,
-              UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
-              nb_rbs_required[CC_id][UE_id],
-              eNB_UE_stats->dlsch_mcs1, TBS);
-        N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
-        UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx] =
-          nb_rbs_allowed_slice(sli->dl[slice_idx].pct, N_RB_DL);
-
-        /* calculating required number of RBs for each UE */
-        while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
-          nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
-
-          if (nb_rbs_required[CC_id][UE_id] > UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]) {
-            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]);
-            nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx];
-            break;
-          }
-
-          TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]);
-        } // end of while
-
-        LOG_D(MAC,
-              "[eNB %d] Frame %d: UE %d on CC %d: RB unit %d,  nb_required RB %d (TBS %d, mcs %d)\n",
-              Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id],
-              nb_rbs_required[CC_id][UE_id], TBS,
-              eNB_UE_stats->dlsch_mcs1);
-        sli->pre_processor_results[slice_idx].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1;
-      }
-    }
-  }
-}
-
-
-// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
-int
-maxround(module_id_t Mod_id, uint16_t rnti, int frame,
-         sub_frame_t subframe) {
-  uint8_t round, round_max = 0, UE_id;
-  int CC_id, harq_pid;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  COMMON_channels_t *cc;
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    cc = &RC.mac[Mod_id]->common_channels[CC_id];
-    UE_id = find_UE_id(Mod_id, rnti);
-
-    if(UE_id == -1)
+dlsch_scheduler_pre_processor(module_id_t Mod_id,
+                              int CC_id,
+                              frame_t frameP,
+                              sub_frame_t subframeP) {
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+  const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
+  const int RBGsize = get_min_rb_unit(Mod_id, CC_id);
+
+  store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP);
+
+  UE_list_t UE_to_sched;
+  UE_to_sched.head = -1;
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
+    UE_to_sched.next[i] = -1;
+
+  int first = 1;
+  int last_UE_id = -1;
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+    const UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
+
+    /* initialize per-UE scheduling information */
+    ue_sched_ctrl->pre_nb_available_rbs[CC_id] = 0;
+    ue_sched_ctrl->dl_pow_off[CC_id] = 2;
+    memset(ue_sched_ctrl->rballoc_sub_UE[CC_id], 0, sizeof(ue_sched_ctrl->rballoc_sub_UE[CC_id]));
+    ue_sched_ctrl->pre_dci_dl_pdu_idx = -1;
+
+    const rnti_t rnti = UE_RNTI(Mod_id, UE_id);
+    if (rnti == NOT_A_RNTI) {
+      LOG_E(MAC, "UE %d has RNTI NOT_A_RNTI!\n", UE_id);
       continue;
-
-    harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame,subframe);
-    round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
-
-    if (round > round_max) {
-      round_max = round;
     }
-  }
-
-  return round_max;
-}
-
-int
-maxround_ul(module_id_t Mod_id, uint16_t rnti, int sched_frame,
-            sub_frame_t sched_subframe) {
-  uint8_t round, round_max = 0, UE_id;
-  int CC_id, harq_pid;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  COMMON_channels_t *cc;
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    cc = &RC.mac[Mod_id]->common_channels[CC_id];
-    UE_id = find_UE_id(Mod_id, rnti);
-
-    if(UE_id == -1)
+    if (UE_info->active[UE_id] != TRUE) {
+      LOG_E(MAC, "UE %d RNTI %x is NOT active!\n", UE_id, rnti);
       continue;
-
-    harq_pid = subframe2harqpid(cc, sched_frame, sched_subframe);
-    round = UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
-
-    if (round > round_max) {
-      round_max = round;
-    }
-  }
-
-  return round_max;
-}
-
-// This function scans all CC_ids for a particular UE to find the maximum DL CQI
-// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
-int maxcqi(module_id_t Mod_id, int32_t UE_id) {
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  int CC_id, n;
-  int CQI = 0;
-
-  for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) {
-    CC_id = UE_list->ordered_CCids[n][UE_id];
-
-    if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) {
-      CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
     }
-  }
-
-  return CQI;
-}
-
-long min_lcgidpriority(module_id_t Mod_id, int32_t UE_id) {
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  int i;
-  int pCC_id = UE_PCCID(Mod_id, UE_id);
-  long ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[0];
-
-  for (i = 1; i < 11; ++i) {
-    if (UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i] < ret)
-      ret = UE_list->UE_template[pCC_id][UE_id].lcgidpriority[i];
-  }
-
-  return ret;
-}
-
-struct sort_ue_dl_params {
-  int Mod_idP;
-  int frameP;
-  int subframeP;
-  int slice_idx;
-};
-
-static int ue_dl_compare(const void *_a, const void *_b, void *_params) {
-  struct sort_ue_dl_params *params = _params;
-  UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list;
-  int i;
-  int slice_idx = params->slice_idx;
-  int UE_id1 = *(const int *) _a;
-  int UE_id2 = *(const int *) _b;
-  int rnti1 = UE_RNTI(params->Mod_idP, UE_id1);
-  int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
-  int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP);
-  int rnti2 = UE_RNTI(params->Mod_idP, UE_id2);
-  int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
-  int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP);
-  int cqi1 = maxcqi(params->Mod_idP, UE_id1);
-  int cqi2 = maxcqi(params->Mod_idP, UE_id2);
-  long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1);
-  long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2);
-
-  for (i = 0; i < CR_NUM; ++i) {
-    switch (UE_list->sorting_criteria[slice_idx][i]) {
-      case CR_ROUND :
-        if (round1 > round2)
-          return -1;
-
-        if (round1 < round2)
-          return 1;
-
-        break;
-
-      case CR_SRB12 :
-        if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
-            UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] >
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
-          return -1;
-
-        if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] +
-            UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] <
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] +
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])
-          return 1;
-
-        break;
-
-      case CR_HOL :
-        if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max >
-            UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
-          return -1;
-
-        if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
-            UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max)
-          return 1;
-
-        break;
-
-      case CR_LC :
-        if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
-          return -1;
-
-        if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
-            UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
-          return 1;
-
-        break;
-
-      case CR_CQI :
-        if (cqi1 > cqi2)
-          return -1;
-
-        if (cqi1 < cqi2)
-          return 1;
-
-        break;
-
-      case CR_LCP :
-        if (lcgid1 < lcgid2)
-          return -1;
-
-        if (lcgid1 > lcgid2)
-          return 1;
-
-      default :
-        break;
+    if (ue_template->rach_resource_type > 0) {
+      LOG_D(MAC,
+            "UE %d is RACH resource type %d\n",
+            UE_id,
+            ue_template->rach_resource_type);
+      continue;
     }
-  }
-
-  return 0;
-}
-
-void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) {
-  int i;
-  UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
-  uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting;
-  uint32_t mask = 0x0000000F;
-  uint16_t criterion;
-
-  for (i = 0; i < CR_NUM; ++i) {
-    criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask);
-
-    if (criterion >= CR_NUM) {
-      LOG_W(MAC,
-            "Invalid criterion in slice index %d ID %d policy, revert to default policy \n",
-            slice_idx, RC.mac[Mod_idP]->slice_info.dl[slice_idx].id);
-      RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting = 0x12345;
-      break;
+    if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_CONNECTED) {
+      LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id);
+      continue;
     }
 
-    UE_list->sorting_criteria[slice_idx][i] = criterion;
-  }
-}
-
-void decode_slice_positioning(module_id_t Mod_idP,
-                              int slice_idx,
-                              uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) {
-  uint8_t CC_id;
-  int RBG, start_frequency, end_frequency;
+    /* define UEs to schedule */
+    if (first) {
+      first = 0;
+      UE_to_sched.head = UE_id;
+    } else {
+      UE_to_sched.next[last_UE_id] = UE_id;
+    }
+    UE_to_sched.next[UE_id] = -1;
+    last_UE_id = UE_id;
+  }
+
+  if (UE_to_sched.head < 0)
+    return;
+
+  uint8_t *vrb_map = RC.mac[Mod_id]->common_channels[CC_id].vrb_map;
+  uint8_t rbgalloc_mask[N_RBG_MAX];
+  int n_rbg_sched = 0;
+  for (int i = 0; i < N_RBG; i++) {
+    // calculate mask: init to one + "AND" with vrb_map:
+    // if any RB in vrb_map is blocked (1), the current RBG will be 0
+    rbgalloc_mask[i] = 1;
+    for (int j = 0; j < RBGsize; j++)
+      rbgalloc_mask[i] &= !vrb_map[RBGsize * i + j];
+    n_rbg_sched += rbgalloc_mask[i];
+  }
+
+  round_robin_dl(Mod_id,
+                 CC_id,
+                 frameP,
+                 subframeP,
+                 &UE_to_sched,
+                 4, // max_num_ue
+                 n_rbg_sched,
+                 rbgalloc_mask);
+
+  // the following block is meant for validation of the pre-processor to check
+  // whether all UE allocations are non-overlapping and is not necessary for
+  // scheduling functionality
+#ifdef DEBUG_eNB_SCHEDULER
+  char t[26] = "_________________________";
+  t[N_RBG] = 0;
+  for (int i = 0; i < N_RBG; i++)
+    for (int j = 0; j < RBGsize; j++)
+      if (vrb_map[RBGsize*i+j] != 0)
+        t[i] = 'x';
+  int print = 0;
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    const UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+    if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0)
+      continue;
 
-  // Init slice_alloc_mask
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) {
-    for (RBG = 0; RBG < N_RBG_MAX; ++RBG) {
-      slice_allocation_mask[CC_id][RBG] = 0;
-    }
-  }
+    LOG_D(MAC,
+          "%4d.%d UE%d %d RBs allocated, pre MCS %d\n",
+          frameP,
+          subframeP,
+          UE_id,
+          ue_sched_ctrl->pre_nb_available_rbs[CC_id],
+          UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1);
 
-  start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_low;
-  end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_high;
+    print = 1;
 
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) {
-    for (RBG = start_frequency; RBG <= end_frequency; ++RBG) {
-      slice_allocation_mask[CC_id][RBG] = 1;
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-/*
- * This function sorts the UEs in order, depending on their dlsch buffer and CQI
- */
-void sort_UEs(module_id_t Mod_idP,
-              int slice_idx,
-              int frameP,
-              sub_frame_t subframeP)
-//-----------------------------------------------------------------------------
-{
-  int list[MAX_MOBILES_PER_ENB];
-  int list_size = 0;
-  struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx};
-  UE_list_t *UE_list = &(RC.mac[Mod_idP]->UE_list);
-  UE_sched_ctrl_t *UE_scheduling_control = NULL;
-
-  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
-    UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]);
-
-    /* Check CDRX configuration and if UE is in active time for this subframe */
-    if (UE_scheduling_control->cdrx_configured == TRUE) {
-      if (UE_scheduling_control->in_active_time == FALSE) {
+    for (int i = 0; i < N_RBG; i++) {
+      if (!ue_sched_ctrl->rballoc_sub_UE[CC_id][i])
         continue;
-      }
-    }
-
-    if (UE_list->active[i] == TRUE &&
-        UE_RNTI(Mod_idP, i) != NOT_A_RNTI &&
-        UE_list->UE_sched_ctrl[i].ul_out_of_sync != 1 &&
-        ue_dl_slice_membership(Mod_idP, i, slice_idx)) {
-      list[list_size++] = i;
-    }
-  }
-
-  decode_sorting_policy(Mod_idP, slice_idx);
-  qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params);
-
-  if (list_size) {
-    for (int i = 0; i < list_size - 1; ++i) {
-      UE_list->next[list[i]] = list[i + 1];
-    }
-
-    UE_list->next[list[list_size - 1]] = -1;
-    UE_list->head = list[0];
-  } else {
-    UE_list->head = -1;
-  }
-}
-
-void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
-    int slice_idx,
-    const uint8_t rbs_retx[NFAPI_CC_MAX]) {
-  int UE_id, CC_id, N_RB_DL, i;
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  uint16_t available_rbs;
-
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
-
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
-      available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_idx].pct, N_RB_DL);
-
-      if (rbs_retx[CC_id] < available_rbs)
-        ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = available_rbs - rbs_retx[CC_id];
-      else
-        ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = 0;
-    }
-  }
-}
-
-void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
-    int slice_idx,
-    frame_t frameP,
-    sub_frame_t subframeP,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) {
-  int UE_id, CC_id;
-  int i;
-  rnti_t rnti;
-  uint8_t harq_pid, round;
-  uint16_t available_rbs[NFAPI_CC_MAX];
-  uint8_t rbs_retx[NFAPI_CC_MAX];
-  uint16_t average_rbs_per_user[NFAPI_CC_MAX];
-  int total_ue_count[NFAPI_CC_MAX];
-  int ue_count_newtx[NFAPI_CC_MAX];
-  int ue_count_retx[NFAPI_CC_MAX];
-  //uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  COMMON_channels_t *cc;
-
-  // Reset
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    total_ue_count[CC_id] = 0;
-    ue_count_newtx[CC_id] = 0;
-    ue_count_retx[CC_id] = 0;
-    rbs_retx[CC_id] = 0;
-    average_rbs_per_user[CC_id] = 0;
-    available_rbs[CC_id] = 0;
-    //for (UE_id = 0; UE_id < NFAPI_CC_MAX; ++UE_id) {
-    //  ue_retx_flag[CC_id][UE_id] = 0;
-    //}
-  }
-
-  // Find total UE count, and account the RBs required for retransmissions
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    rnti = UE_RNTI(Mod_id, UE_id);
-
-    if (rnti == NOT_A_RNTI) continue;
-
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      cc = &RC.mac[Mod_id]->common_channels[CC_id];
-      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
-      round = ue_sched_ctl->round[CC_id][harq_pid];
-
-      if (nb_rbs_required[CC_id][UE_id] > 0) {
-        total_ue_count[CC_id]++;
-      }
-
-      if (round != 8) {
-        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
-        rbs_retx[CC_id] += nb_rbs_required[CC_id][UE_id];
-        ue_count_retx[CC_id]++;
-        //ue_retx_flag[CC_id][UE_id] = 1;
-      } else {
-        ue_count_newtx[CC_id]++;
-      }
-    }
-  }
-
-  // PARTITIONING
-  // Reduces the available RBs according to slicing configuration
-  dlsch_scheduler_pre_processor_partitioning(Mod_id, slice_idx, rbs_retx);
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) {
-    if (UE_list->head < 0) continue; // no UEs in list
-
-    // max_rbs_allowed_slice is saved in every UE, so take it from the first one
-    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_list->head];
-    available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx];
-  }
-
-  switch (RC.mac[Mod_id]->slice_info.dl[slice_idx].accounting) {
-    // If greedy scheduling, try to account all the required RBs
-    case POL_GREEDY:
-      for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-        rnti = UE_RNTI(Mod_id, UE_id);
-
-        if (rnti == NOT_A_RNTI) continue;
-
-        if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-        if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-        for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-          CC_id = UE_list->ordered_CCids[i][UE_id];
-
-          if (available_rbs[CC_id] == 0) continue;
-
-          nb_rbs_accounted[CC_id][UE_id] = cmin(nb_rbs_required[CC_id][UE_id], available_rbs[CC_id]);
-          available_rbs[CC_id] -= nb_rbs_accounted[CC_id][UE_id];
-        }
-      }
-
-      break;
-
-    // Use the old, fair algorithm
-    // Loop over all active UEs and account the avg number of RBs to each UE, based on all non-retx UEs.
-    // case POL_FAIR:
-    default:
-
-      // FIXME: This is not ideal, why loop on UEs to find average_rbs_per_user[], that is per-CC?
-      // TODO: Look how to loop on active CCs only without using the UE_num_active_CC() function.
-      for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-        rnti = UE_RNTI(Mod_id, UE_id);
-
-        if (rnti == NOT_A_RNTI) continue;
-
-        if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-        if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-        for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) {
-          CC_id = UE_list->ordered_CCids[i][UE_id];
-          ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-          available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx];
-
-          if (ue_count_newtx[CC_id] == 0) {
-            average_rbs_per_user[CC_id] = 0;
-          } else if (min_rb_unit[CC_id]*ue_count_newtx[CC_id] <= available_rbs[CC_id]) {
-            average_rbs_per_user[CC_id] = (uint16_t)floor(available_rbs[CC_id]/ue_count_newtx[CC_id]);
-          } else {
-            // consider the total number of use that can be scheduled UE
-            average_rbs_per_user[CC_id] = (uint16_t)min_rb_unit[CC_id];
-          }
-        }
-      }
-
-      // note: nb_rbs_required is assigned according to total_buffer_dl
-      // extend nb_rbs_required to capture per LCID RB required
-      for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-        rnti = UE_RNTI(Mod_id, UE_id);
-
-        if (rnti == NOT_A_RNTI) continue;
-
-        if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-        if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-        for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-          CC_id = UE_list->ordered_CCids[i][UE_id];
-          nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]);
+      for (int j = 0; j < RBGsize; j++) {
+        if (vrb_map[RBGsize*i+j] != 0) {
+          LOG_I(MAC, "%4d.%d DL scheduler allocation list: %s\n", frameP, subframeP, t);
+          LOG_E(MAC, "%4d.%d: UE %d allocated at locked RB %d/RBG %d\n", frameP,
+                subframeP, UE_id, RBGsize * i + j, i);
         }
+        vrb_map[RBGsize*i+j] = 1;
       }
-
-      break;
-  }
-
-  // Check retransmissions
-  // TODO: Do this once at the beginning
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    rnti = UE_RNTI(Mod_id, UE_id);
-
-    if (rnti == NOT_A_RNTI) continue;
-
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      cc = &RC.mac[Mod_id]->common_channels[CC_id];
-      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP);
-      round = ue_sched_ctl->round[CC_id][harq_pid];
-
-      // control channel or retransmission
-      /* TODO: do we have to check for retransmission? */
-      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) {
-        nb_rbs_accounted[CC_id][UE_id] = nb_rbs_required[CC_id][UE_id];
-      }
+      t[i] = '0' + UE_id;
     }
   }
-}
-
-void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id,
-    int slice_idx,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) {
-  int UE_id, CC_id;
-  int i;
-#ifdef TM5
-  uint8_t transmission_mode;
-#endif
-  uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
-  int N_RBG[NFAPI_CC_MAX];
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask);
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
-    N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
-  }
-
-  // Try to allocate accounted RBs
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
-
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id];
-#ifdef TM5
-      transmission_mode = get_tmode(Mod_id, CC_id, UE_id);
-#endif
-
-      if (nb_rbs_required[CC_id][UE_id] > 0)
-        LOG_D(MAC,
-              "Step 1: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d,  pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
-              CC_id,
-              UE_id,
-              nb_rbs_remaining[CC_id][UE_id],
-              nb_rbs_accounted[CC_id][UE_id],
-              nb_rbs_required[CC_id][UE_id],
-              UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id],
-              N_RBG[CC_id],
-              min_rb_unit[CC_id]);
-
-      LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n ");
-      dlsch_scheduler_pre_processor_allocate(Mod_id,
-                                             UE_id,
-                                             CC_id,
-                                             N_RBG[CC_id],
-                                             min_rb_unit[CC_id],
-                                             nb_rbs_required,
-                                             nb_rbs_remaining,
-                                             rballoc_sub,
-                                             slice_allocation_mask,
-                                             MIMO_mode_indicator);
-#ifdef TM5
-
-      // data chanel TM5: to be revisited
-      if ((round == 0) &&
-          (transmission_mode == 5) &&
-          (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
-        for (j = 0; j < N_RBG[CC_id]; j += 2) {
-          if ((((j == (N_RBG[CC_id] - 1))
-                && (rballoc_sub[CC_id][j] == 0)
-                && (ue_sched_ctl->
-                    rballoc_sub_UE[CC_id][j] == 0))
-               || ((j < (N_RBG[CC_id] - 1))
-                   && (rballoc_sub[CC_id][j + 1] == 0)
-                   &&
-                   (ue_sched_ctl->rballoc_sub_UE
-                    [CC_id][j + 1] == 0)))
-              && (nb_rbs_remaining[CC_id][UE_id]
-                  > 0)) {
-            for (i = UE_list->next[UE_id + 1]; i >= 0;
-                 i = UE_list->next[i]) {
-              UE_id2 = i;
-              rnti2 = UE_RNTI(Mod_id, UE_id2);
-              ue_sched_ctl2 =
-                &UE_list->UE_sched_ctrl[UE_id2];
-              round2 = ue_sched_ctl2->round[CC_id];
-
-              if (rnti2 == NOT_A_RNTI)
-                continue;
-
-              if (UE_list->
-                  UE_sched_ctrl
-                  [UE_id2].ul_out_of_sync == 1)
-                continue;
-
-              eNB_UE_stats2 =
-                UE_list->
-                eNB_UE_stats[CC_id][UE_id2];
-              //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
-
-              if ((mac_eNB_get_rrc_status
-                   (Mod_id,
-                    rnti2) >= RRC_RECONFIGURED)
-                  && (round2 == 0)
-                  &&
-                  (get_tmode(Mod_id, CC_id, UE_id2)
-                   == 5)
-                  && (ue_sched_ctl->
-                      dl_pow_off[CC_id] != 1)) {
-                if ((((j == (N_RBG[CC_id] - 1))
-                      &&
-                      (ue_sched_ctl->rballoc_sub_UE
-                       [CC_id][j] == 0))
-                     || ((j < (N_RBG[CC_id] - 1))
-                         &&
-                         (ue_sched_ctl->
-                          rballoc_sub_UE[CC_id][j +
-                                                1]
-                          == 0)))
-                    &&
-                    (nb_rbs_remaining
-                     [CC_id]
-                     [UE_id2] > 0)) {
-                  if ((((eNB_UE_stats2->
-                         DL_pmi_single ^
-                         eNB_UE_stats1->
-                         DL_pmi_single)
-                        << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration
-                    rballoc_sub[CC_id][j] = 1;
-                    ue_sched_ctl->
-                    rballoc_sub_UE[CC_id]
-                    [j] = 1;
-                    ue_sched_ctl2->
-                    rballoc_sub_UE[CC_id]
-                    [j] = 1;
-                    MIMO_mode_indicator[CC_id]
-                    [j] = 0;
-
-                    if (j < N_RBG[CC_id] - 1) {
-                      rballoc_sub[CC_id][j +
-                                         1] =
-                                           1;
-                      ue_sched_ctl->
-                      rballoc_sub_UE
-                      [CC_id][j + 1] = 1;
-                      ue_sched_ctl2->rballoc_sub_UE
-                      [CC_id][j + 1] = 1;
-                      MIMO_mode_indicator
-                      [CC_id][j + 1]
-                        = 0;
-                    }
-
-                    ue_sched_ctl->
-                    dl_pow_off[CC_id]
-                      = 0;
-                    ue_sched_ctl2->
-                    dl_pow_off[CC_id]
-                      = 0;
-
-                    if ((j == N_RBG[CC_id] - 1)
-                        && ((N_RB_DL == 25)
-                            || (N_RB_DL ==
-                                50))) {
-                      nb_rbs_remaining
-                      [CC_id][UE_id] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id] -
-                        min_rb_unit[CC_id]
-                        + 1;
-                      ue_sched_ctl->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl->pre_nb_available_rbs
-                        [CC_id] +
-                        min_rb_unit[CC_id]
-                        - 1;
-                      nb_rbs_remaining
-                      [CC_id][UE_id2] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id2] -
-                        min_rb_unit[CC_id]
-                        + 1;
-                      ue_sched_ctl2->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl2->pre_nb_available_rbs
-                        [CC_id] +
-                        min_rb_unit[CC_id]
-                        - 1;
-                    } else {
-                      nb_rbs_remaining
-                      [CC_id][UE_id] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id] - 4;
-                      ue_sched_ctl->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl->pre_nb_available_rbs
-                        [CC_id] + 4;
-                      nb_rbs_remaining
-                      [CC_id][UE_id2] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id2] -
-                        4;
-                      ue_sched_ctl2->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl2->pre_nb_available_rbs
-                        [CC_id] + 4;
-                    }
-
-                    break;
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-
+  if (print)
+    LOG_D(MAC, "%4d.%d DL scheduler allocation list: %s\n", frameP, subframeP, t);
 #endif
-    }
-  }
 }
 
-void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
-    int slice_idx,
-    int min_rb_unit[NFAPI_CC_MAX],
-    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) {
-  int UE_id, CC_id;
-  int i;
-#ifdef TM5
-  uint8_t transmission_mode;
-#endif
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  int N_RBG[NFAPI_CC_MAX];
-  slice_info_t *sli = &RC.mac[Mod_id]->slice_info;
-  uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocation_mask;
-  decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask);
-
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
-    N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
-  }
-
-  // Remaining RBs are allocated to high priority UEs
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue;
-
-    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue;
-
-    if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue;
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      nb_rbs_remaining[CC_id][UE_id] =
-        nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id];
-
-      if (nb_rbs_remaining[CC_id][UE_id] < 0)
-        abort();
-
-#ifdef TM5
-      transmission_mode = get_tmode(Mod_id, CC_id, UE_id);
-#endif
-
-      if (nb_rbs_required[CC_id][UE_id] > 0)
-        LOG_D(MAC,
-              "Step 2: nb_rbs_remaining[%d][%d]= %d (accounted %d, required %d,  pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
-              CC_id,
-              UE_id,
-              nb_rbs_remaining[CC_id][UE_id],
-              nb_rbs_accounted[CC_id][UE_id],
-              nb_rbs_required[CC_id][UE_id],
-              UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id],
-              N_RBG[CC_id],
-              min_rb_unit[CC_id]);
-
-      LOG_T(MAC, "calling dlsch_scheduler_pre_processor_allocate .. \n ");
-      dlsch_scheduler_pre_processor_allocate(Mod_id,
-                                             UE_id,
-                                             CC_id,
-                                             N_RBG[CC_id],
-                                             min_rb_unit[CC_id],
-                                             nb_rbs_required,
-                                             nb_rbs_remaining,
-                                             rballoc_sub,
-                                             slice_allocation_mask,
-                                             MIMO_mode_indicator);
-#ifdef TM5
-
-      // data chanel TM5: to be revisited
-      if ((round == 0) &&
-          (transmission_mode == 5) &&
-          (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
-        for (j = 0; j < N_RBG[CC_id]; j += 2) {
-          if ((((j == (N_RBG[CC_id] - 1))
-                && (rballoc_sub[CC_id][j] == 0)
-                && (ue_sched_ctl->
-                    rballoc_sub_UE[CC_id][j] == 0))
-               || ((j < (N_RBG[CC_id] - 1))
-                   && (rballoc_sub[CC_id][j + 1] == 0)
-                   &&
-                   (ue_sched_ctl->rballoc_sub_UE
-                    [CC_id][j + 1] == 0)))
-              && (nb_rbs_remaining[CC_id][UE_id]
-                  > 0)) {
-            for (i = UE_list->next[UE_id + 1]; i >= 0;
-                 i = UE_list->next[i]) {
-              UE_id2 = i;
-              rnti2 = UE_RNTI(Mod_id, UE_id2);
-              ue_sched_ctl2 =
-                &UE_list->UE_sched_ctrl[UE_id2];
-              round2 = ue_sched_ctl2->round[CC_id];
-
-              if (rnti2 == NOT_A_RNTI)
-                continue;
-
-              if (UE_list->
-                  UE_sched_ctrl
-                  [UE_id2].ul_out_of_sync == 1)
-                continue;
-
-              eNB_UE_stats2 =
-                UE_list->
-                eNB_UE_stats[CC_id][UE_id2];
-              //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
-
-              if ((mac_eNB_get_rrc_status
-                   (Mod_id,
-                    rnti2) >= RRC_RECONFIGURED)
-                  && (round2 == 0)
-                  &&
-                  (get_tmode(Mod_id, CC_id, UE_id2)
-                   == 5)
-                  && (ue_sched_ctl->
-                      dl_pow_off[CC_id] != 1)) {
-                if ((((j == (N_RBG[CC_id] - 1))
-                      &&
-                      (ue_sched_ctl->rballoc_sub_UE
-                       [CC_id][j] == 0))
-                     || ((j < (N_RBG[CC_id] - 1))
-                         &&
-                         (ue_sched_ctl->
-                          rballoc_sub_UE[CC_id][j +
-                                                1]
-                          == 0)))
-                    &&
-                    (nb_rbs_remaining
-                     [CC_id]
-                     [UE_id2] > 0)) {
-                  if ((((eNB_UE_stats2->
-                         DL_pmi_single ^
-                         eNB_UE_stats1->
-                         DL_pmi_single)
-                        << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration
-                    rballoc_sub[CC_id][j] = 1;
-                    ue_sched_ctl->
-                    rballoc_sub_UE[CC_id]
-                    [j] = 1;
-                    ue_sched_ctl2->
-                    rballoc_sub_UE[CC_id]
-                    [j] = 1;
-                    MIMO_mode_indicator[CC_id]
-                    [j] = 0;
-
-                    if (j < N_RBG[CC_id] - 1) {
-                      rballoc_sub[CC_id][j +
-                                         1] =
-                                           1;
-                      ue_sched_ctl->
-                      rballoc_sub_UE
-                      [CC_id][j + 1] = 1;
-                      ue_sched_ctl2->rballoc_sub_UE
-                      [CC_id][j + 1] = 1;
-                      MIMO_mode_indicator
-                      [CC_id][j + 1]
-                        = 0;
-                    }
-
-                    ue_sched_ctl->
-                    dl_pow_off[CC_id]
-                      = 0;
-                    ue_sched_ctl2->
-                    dl_pow_off[CC_id]
-                      = 0;
-
-                    if ((j == N_RBG[CC_id] - 1)
-                        && ((N_RB_DL == 25)
-                            || (N_RB_DL ==
-                                50))) {
-                      nb_rbs_remaining
-                      [CC_id][UE_id] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id] -
-                        min_rb_unit[CC_id]
-                        + 1;
-                      ue_sched_ctl->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl->pre_nb_available_rbs
-                        [CC_id] +
-                        min_rb_unit[CC_id]
-                        - 1;
-                      nb_rbs_remaining
-                      [CC_id][UE_id2] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id2] -
-                        min_rb_unit[CC_id]
-                        + 1;
-                      ue_sched_ctl2->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl2->pre_nb_available_rbs
-                        [CC_id] +
-                        min_rb_unit[CC_id]
-                        - 1;
-                    } else {
-                      nb_rbs_remaining
-                      [CC_id][UE_id] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id] - 4;
-                      ue_sched_ctl->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl->pre_nb_available_rbs
-                        [CC_id] + 4;
-                      nb_rbs_remaining
-                      [CC_id][UE_id2] =
-                        nb_rbs_remaining
-                        [CC_id][UE_id2] -
-                        4;
-                      ue_sched_ctl2->pre_nb_available_rbs
-                      [CC_id] =
-                        ue_sched_ctl2->pre_nb_available_rbs
-                        [CC_id] + 4;
-                    }
-
-                    break;
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
+/// ULSCH PRE_PROCESSOR
 
-#endif
-    }
+void calculate_max_mcs_min_rb(module_id_t mod_id,
+                              int CC_id,
+                              int bytes,
+                              int phr,
+                              int max_mcs,
+                              int *mcs,
+                              int max_rbs,
+                              int *rb_index,
+                              int *tx_power) {
+  const int Ncp = RC.mac[mod_id]->common_channels[CC_id].Ncp;
+  /* TODO shouldn't we consider the SRS or other quality indicators? */
+  *mcs = max_mcs;
+  *rb_index = 2;
+  int tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
+
+  // fixme: set use_srs flag
+  *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+
+  /* find maximum MCS */
+  while ((phr - *tx_power < 0 || tbs > bytes) && *mcs > 3) {
+    mcs--;
+    tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
+    *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+  }
+
+  /* find minimum necessary RBs */
+  while (tbs < bytes
+         && *rb_index < 32
+         && rb_table[*rb_index] < max_rbs
+         && phr - *tx_power > 0) {
+    (*rb_index)++;
+    tbs = get_TBS_UL(*mcs, rb_table[*rb_index]);
+    *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0);
+  }
+
+  /* Decrease if we went to far in last iteration */
+  if (rb_table[*rb_index] > max_rbs)
+    (*rb_index)--;
+
+  // 1 or 2 PRB with cqi enabled does not work well
+  if (rb_table[*rb_index] < 3) {
+    *rb_index = 2; //3PRB
   }
 }
 
-// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
-void
-dlsch_scheduler_pre_processor(module_id_t Mod_id,
-                              int slice_idx,
-                              frame_t frameP,
-                              sub_frame_t subframeP,
-                              int *mbsfn_flag,
-                              uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) {
-  int UE_id;
-  uint8_t CC_id;
-  uint16_t i, j;
-  int min_rb_unit[NFAPI_CC_MAX];
-  eNB_MAC_INST *eNB = RC.mac[Mod_id];
-  slice_info_t *sli = &eNB->slice_info;
-  uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB]  = sli->pre_processor_results[slice_idx].nb_rbs_required;
-  uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_accounted;
-  uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_remaining;
-  uint8_t  (*MIMO_mode_indicator)[N_RBG_MAX]     = sli->pre_processor_results[slice_idx].MIMO_mode_indicator;
-  UE_list_t *UE_list = &eNB->UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  //  int rrc_status = RRC_IDLE;
-#ifdef TM5
-  int harq_pid1 = 0;
-  int round1 = 0, round2 = 0;
-  int UE_id2;
-  uint16_t i1, i2, i3;
-  rnti_t rnti1, rnti2;
-  LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
-  LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
-  UE_sched_ctrl_t *ue_sched_ctl1, *ue_sched_ctl2;
-#endif
-  // Initialize scheduling information for all active UEs
-  memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx]));
-  // FIXME: After the memset above, some of the resets in reset() are redundant
-  dlsch_scheduler_pre_processor_reset(Mod_id,
-                                      slice_idx,
-                                      frameP,
-                                      subframeP,
-                                      min_rb_unit,
-                                      nb_rbs_required,
-                                      rballoc_sub,
-                                      MIMO_mode_indicator,
-                                      mbsfn_flag); // FIXME: Not sure if useful
-  // STATUS
-  // Store the DLSCH buffer for each logical channel
-  store_dlsch_buffer(Mod_id,
-                     slice_idx,
-                     frameP,
-                     subframeP);
-  // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
-  assign_rbs_required(Mod_id,
-                      slice_idx,
-                      frameP,
-                      subframeP,
-                      nb_rbs_required,
-                      min_rb_unit);
-  // Sorts the user on the basis of dlsch logical channel buffer and CQI
-  sort_UEs(Mod_id,
-           slice_idx,
-           frameP,
-           subframeP);
-  // ACCOUNTING
-  // This procedure decides the number of RBs to allocate
-  dlsch_scheduler_pre_processor_accounting(Mod_id,
-      slice_idx,
-      frameP,
-      subframeP,
-      min_rb_unit,
-      nb_rbs_required,
-      nb_rbs_accounted);
-  // POSITIONING
-  // This procedure does the main allocation of the RBs
-  dlsch_scheduler_pre_processor_positioning(Mod_id,
-      slice_idx,
-      min_rb_unit,
-      nb_rbs_required,
-      nb_rbs_accounted,
-      nb_rbs_remaining,
-      rballoc_sub,
-      MIMO_mode_indicator);
-
-  // SHARING
-  // If there are available RBs left in the slice, allocate them to the highest priority UEs
-  if (eNB->slice_info.intraslice_share_active) {
-    dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id,
-        slice_idx,
-        min_rb_unit,
-        nb_rbs_required,
-        nb_rbs_accounted,
-        nb_rbs_remaining,
-        rballoc_sub,
-        MIMO_mode_indicator);
-  }
-
-#ifdef TM5
-
-  // This has to be revisited!!!!
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
-    COMMON_channels_t *cc = &eNB->common_channels[CC_id];
-    int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth);
-    i1 = 0;
-    i2 = 0;
-    i3 = 0;
-
-    for (j = 0; j < N_RBG; j++) {
-      if (MIMO_mode_indicator[CC_id][j] == 2) {
-        i1++;
-      } else if (MIMO_mode_indicator[CC_id][j] == 1) {
-        i2++;
-      } else if (MIMO_mode_indicator[CC_id][j] == 0) {
-        i3++;
-      }
-    }
-
-    if (i1 < N_RBG) {
-      if (i2 > 0 && i3 == 0) {
-        PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions + 1;
-      } else if (i3 > 0) {
-        PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions + 1;
-      }
-    } else if (i3 == N_RBG && i1 == 0 && i2 == 0) {
-      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
-    }
-
-    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1;
-  }
-
-#endif
-
-  for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
-    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-
-    for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) {
-      CC_id = UE_list->ordered_CCids[i][UE_id];
-      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
-      COMMON_channels_t *cc = &eNB->common_channels[CC_id];
-      int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth);
-
-      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
-        LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n",
-              UE_id);
-        LOG_D(MAC, "dl power offset UE%d = %d \n",
-              UE_id,
-              ue_sched_ctl->dl_pow_off[CC_id]);
-        LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n",
-              UE_id);
-
-        for (j = 0; j < N_RBG; j++) {
-          //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id];
-          LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
-                UE_id, j,
-                ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
-        }
-
-        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
-        LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n",
-              Mod_id,
-              eNB->slice_info.dl[slice_idx].id,
-              UE_id,
-              ue_sched_ctl->pre_nb_available_rbs[CC_id]);
-      }
-    }
-  }
+int pp_find_rb_table_index(int approximate) {
+  int lo = 2;
+  if (approximate <= rb_table[lo])
+    return lo;
+  int hi = sizeof(rb_table) - 1;
+  if (approximate >= rb_table[hi])
+    return hi;
+  int p = (hi + lo) / 2;
+  for (; lo + 1 != hi; p = (hi + lo) / 2) {
+    if (approximate <= rb_table[p])
+      hi = p;
+    else
+      lo = p;
+  }
+  return p + 1;
 }
 
-#define SF0_LIMIT 1
-
-void
-dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
-                                    int slice_idx,
-                                    frame_t frameP,
-                                    sub_frame_t subframeP,
-                                    int min_rb_unit[NFAPI_CC_MAX],
-                                    uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-                                    uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-                                    uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
-                                    int *mbsfn_flag) {
-  int UE_id;
-  uint8_t CC_id;
-  int i, j;
-  UE_list_t *UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  int N_RB_DL, RBGsize, RBGsize_last;
-  int N_RBG[NFAPI_CC_MAX];
-#ifdef SF0_LIMIT
-  int sf0_lower, sf0_upper;
-#endif
-  rnti_t rnti;
-  uint8_t *vrb_map;
-  COMMON_channels_t *cc;
-
-  //
-  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
-    // initialize harq_pid and round
-    cc = &RC.mac[module_idP]->common_channels[CC_id];
-    N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
-    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
-
-    if (mbsfn_flag[CC_id] > 0)    // If this CC is allocated for MBSFN skip it here
-      continue;
-
-    for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) {
-      UE_list = &RC.mac[module_idP]->UE_list;
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      rnti = UE_RNTI(module_idP, UE_id);
-
-      if (rnti == NOT_A_RNTI)
-        continue;
-
-      if (UE_list->active[UE_id] != TRUE)
+int g_start_ue_ul = -1;
+int round_robin_ul(module_id_t Mod_id,
+                   int CC_id,
+                   int frame,
+                   int subframe,
+                   int sched_frame,
+                   int sched_subframe,
+                   UE_list_t *UE_list,
+                   int max_num_ue,
+                   int num_contig_rb,
+                   contig_rbs_t *rbs) {
+  AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n");
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+  const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length;
+
+  /* for every UE: check whether we have to handle a retransmission (and
+   * allocate, if so). If not, compute how much RBs this UE would need */
+  int rb_idx_required[MAX_MOBILES_PER_ENB];
+  memset(rb_idx_required, 0, sizeof(rb_idx_required));
+  int num_ue_req = 0;
+  for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+    UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
+    uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id],
+                                        sched_frame, sched_subframe);
+    if (UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0) {
+      /* this UE has a retransmission, allocate it right away */
+      const int nb_rb = UE_template->nb_rb_ul[harq_pid];
+      if (nb_rb == 0) {
+        LOG_E(MAC,
+              "%4d.%d UE %d retransmission of 0 RBs in round %d, ignoring\n",
+              sched_frame, sched_subframe, UE_id,
+              UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid]);
         continue;
-
-      if (!ue_dl_slice_membership(module_idP, UE_id, slice_idx))
-        continue;
-
-      LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti);
-
-      // initialize harq_pid and round
-      if (ue_sched_ctl->ta_timer)
-        ue_sched_ctl->ta_timer--;
-
-      /*
-         eNB_UE_stats *eNB_UE_stats;
-
-         if (eNB_UE_stats == NULL)
-         return;
-
-
-         mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,
-         frameP,subframeP,
-         &ue_sched_ctl->harq_pid[CC_id],
-         &ue_sched_ctl->round[CC_id],
-         openair_harq_DL);
-
-
-         if (ue_sched_ctl->ta_timer == 0) {
-
-         // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
-
-         ue_sched_ctl->ta_timer = 20;  // wait 20 subframes before taking TA measurement from PHY
-         switch (N_RB_DL) {
-         case 6:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update;
-         break;
-
-         case 15:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2;
-         break;
-
-         case 25:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4;
-         break;
-
-         case 50:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8;
-         break;
-
-         case 75:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12;
-         break;
-
-         case 100:
-         ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16;
-         break;
-         }
-         // clear the update in case PHY does not have a new measurement after timer expiry
-         eNB_UE_stats->timing_advance_update =  0;
-         }
-         else {
-         ue_sched_ctl->ta_timer--;
-         ue_sched_ctl->ta_update =0; // don't trigger a timing advance command
-         }
-
-
-         if (UE_id==0) {
-         VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update);
-         }
-       */
-      nb_rbs_required[CC_id][UE_id] = 0;
-      ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
-      ue_sched_ctl->dl_pow_off[CC_id] = 2;
-
-      for (i = 0; i < N_RBG[CC_id]; i++) {
-        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
-      }
-    }
-
-    N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
-#ifdef SF0_LIMIT
-
-    switch (N_RBG[CC_id]) {
-      case 6:
-        sf0_lower = 0;
-        sf0_upper = 5;
-        break;
-
-      case 8:
-        sf0_lower = 2;
-        sf0_upper = 5;
-        break;
-
-      case 13:
-        sf0_lower = 4;
-        sf0_upper = 7;
-        break;
-
-      case 17:
-        sf0_lower = 7;
-        sf0_upper = 9;
-        break;
-
-      case 25:
-        sf0_lower = 11;
-        sf0_upper = 13;
-        break;
-
-      default:
-        AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
-    }
-
-#endif
-
-    switch (N_RB_DL) {
-      case 6:
-        RBGsize = 1;
-        RBGsize_last = 1;
-        break;
-
-      case 15:
-        RBGsize = 2;
-        RBGsize_last = 1;
-        break;
-
-      case 25:
-        RBGsize = 2;
-        RBGsize_last = 1;
-        break;
-
-      case 50:
-        RBGsize = 3;
-        RBGsize_last = 2;
-        break;
-
-      case 75:
-        RBGsize = 4;
-        RBGsize_last = 3;
-        break;
-
-      case 100:
-        RBGsize = 4;
-        RBGsize_last = 4;
-        break;
-
-      default:
-        AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL);
-    }
-
-    vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
-
-    // Initialize Subbands according to VRB map
-    for (i = 0; i < N_RBG[CC_id]; i++) {
-      int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize;
-#ifdef SF0_LIMIT
-
-      // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors)
-      /* TODO: make it proper - allocate those RBs, do not "protect" them, but
-        * compute number of available REs and limit MCS according to the
-        * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor)
-        */
-      if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper)
-        rballoc_sub[CC_id][i] = 1;
-
-#endif
-
-      // for SI-RNTI,RA-RNTI and P-RNTI allocations
-      for (j = 0; j < rb_size; j++) {
-        if (vrb_map[j + (i*RBGsize)] != 0) {
-          rballoc_sub[CC_id][i] = 1;
-          LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", frameP, subframeP, j + (i*RBGsize));
-          break;
-        }
-      }
-
-      //LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",
-      //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]);
-      MIMO_mode_indicator[CC_id][i] = 2;
-    }
-  }
-}
-
-
-void
-dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
-                                       int UE_id,
-                                       uint8_t CC_id,
-                                       int N_RBG,
-                                       int min_rb_unit,
-                                       uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-                                       uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
-                                       uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
-                                       uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX],
-                                       uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) {
-  int i;
-  int tm = get_tmode(Mod_id, CC_id, UE_id);
-  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-  int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
-
-  for (i = 0; i < N_RBG; i++) {
-    if (rballoc_sub[CC_id][i] != 0) continue;
-
-    if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) continue;
-
-    if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue;
-
-    if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue;
-
-    if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue;
-
-    if (slice_allocation_mask[CC_id][i] == 0) continue;
-
-    if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
-      // Allocating last, smaller RBG
-      if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) {
-        rballoc_sub[CC_id][i] = 1;
-        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
-        MIMO_mode_indicator[CC_id][i] = 1;
-
-        if (tm == 5) {
-          ue_sched_ctl->dl_pow_off[CC_id] = 1;
-        }
-
-        nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1;
-        ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
       }
-    } else {
-      // Allocating a standard-sized RBG
-      if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) {
-        rballoc_sub[CC_id][i] = 1;
-        ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
-        MIMO_mode_indicator[CC_id][i] = 1;
-
-        if (tm == 5) {
-          ue_sched_ctl->dl_pow_off[CC_id] = 1;
+      const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
+      const int idx = CCE_try_allocate_ulsch(Mod_id, CC_id, subframe, UE_id, cqi);
+      if (idx < 0)
+        continue; // cannot allocate CCE
+      UE_template->pre_dci_ul_pdu_idx = idx;
+      if (rbs[0].length >= nb_rb) { // fits in first contiguous region
+        UE_template->pre_first_nb_rb_ul = rbs[0].start;
+        rbs[0].length -= nb_rb;
+        rbs[0].start += nb_rb;
+      } else if (num_contig_rb == 2 && rbs[1].length >= nb_rb) { // in second
+        UE_template->pre_first_nb_rb_ul = rbs[1].start;
+        rbs[1].length -= nb_rb;
+        rbs[1].start += nb_rb;
+      } else if (num_contig_rb == 2
+          && rbs[1].start + rbs[1].length - rbs[0].start >= nb_rb) { // overlapping the middle
+        UE_template->pre_first_nb_rb_ul = rbs[0].start;
+        rbs[0].length = 0;
+        int ol = nb_rb - (rbs[1].start - rbs[0].start); // how much overlap in second region
+        if (ol > 0) {
+          rbs[1].length -= ol;
+          rbs[1].start += ol;
         }
-
-        nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit;
-        ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
-      }
-    }
-  }
-}
-
-
-/// ULSCH PRE_PROCESSOR
-
-void ulsch_scheduler_pre_processor(module_id_t module_idP,
-                                   int slice_idx,
-                                   int frameP,
-                                   sub_frame_t subframeP,
-                                   int sched_frameP,
-                                   unsigned char sched_subframeP,
-                                   uint16_t *first_rb) {
-  int UE_id;
-  uint16_t n;
-  uint8_t CC_id, harq_pid;
-  uint16_t nb_allocated_rbs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
-  uint16_t total_allocated_rbs[NFAPI_CC_MAX];
-  uint16_t average_rbs_per_user[NFAPI_CC_MAX];
-  int16_t total_remaining_rbs[NFAPI_CC_MAX];
-  uint16_t total_ue_count[NFAPI_CC_MAX];
-  eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
-  slice_info_t *sli = &eNB->slice_info;
-  UE_TEMPLATE *UE_template = 0;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  int N_RB_UL = 0;
-  uint16_t available_rbs, first_rb_offset;
-  rnti_t rntiTable[MAX_MOBILES_PER_ENB];
-  // sort ues
-  LOG_D(MAC, "In ulsch_preprocessor: sort ue \n");
-  sort_ue_ul(module_idP, slice_idx, sched_frameP, sched_subframeP, rntiTable);
-  // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
-  LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n");
-  assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb);
-  // we need to distribute RBs among UEs
-  // step1:  reset the vars
-  uint8_t CC_nb = (uint8_t) RC.nb_mac_CC[module_idP];
-
-  for (CC_id = 0; CC_id < CC_nb; CC_id++) {
-    total_allocated_rbs[CC_id] = 0;
-    total_remaining_rbs[CC_id] = 0;
-    average_rbs_per_user[CC_id] = 0;
-    total_ue_count[CC_id] = 0;
-  }
-
-  // Step 1.5: Calculate total_ue_count
-  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    // This is not the actual CC_id in the list
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      UE_template = &UE_list->UE_template[CC_id][UE_id];
-
-      if (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) {
-        total_ue_count[CC_id]++;
-      }
-    }
-  }
-
-  // step 2: calculate the average rb per UE
-  LOG_D(MAC, "In ulsch_preprocessor: step2 \n");
-
-  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    if (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 0) continue;
-
-    LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n",
-          UE_id,
-          rntiTable[UE_id]);
-
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      // This is the actual CC_id in the list
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x CCid %d\n",
-            UE_id,
-            rntiTable[UE_id],
-            CC_id);
-      /*
-          if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
-          nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
-          max_num_ue_to_be_scheduled+=1;
-          } */
-      N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth);
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] =
-        nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL);
-      first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx];
-      available_rbs =
-        cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset);
-
-      if (available_rbs < 0)
-        available_rbs = 0;
-
-      if (total_ue_count[CC_id] == 0) {
-        average_rbs_per_user[CC_id] = 0;
-      } else if (total_ue_count[CC_id] == 1) {    // increase the available RBs, special case,
-        average_rbs_per_user[CC_id] = (uint16_t) (available_rbs + 1);
-      } else if (total_ue_count[CC_id] <= available_rbs) {
-        average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]);
       } else {
-        average_rbs_per_user[CC_id] = 1;
-        LOG_W(MAC, "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n",
-              module_idP,
-              frameP,
-              subframeP,
+        LOG_W(MAC,
+              "cannot allocate UL retransmission for UE %d (nb_rb %d)\n",
               UE_id,
-              CC_id);
-      }
-
-      if (total_ue_count[CC_id] > 0) {
-        LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n",
-              module_idP,
-              frameP,
-              subframeP,
-              total_ue_count[CC_id]);
+              nb_rb);
+        UE_template->pre_dci_ul_pdu_idx = -1; // do not need CCE
+        RC.mac[Mod_id]->HI_DCI0_req[CC_id][subframe].hi_dci0_request_body.number_of_dci--;
+        continue;
       }
+      LOG_D(MAC, "%4d.%d UE %d retx %d RBs at start %d\n",
+            sched_frame,
+            sched_subframe,
+            UE_id,
+            UE_template->pre_allocated_nb_rb_ul,
+            UE_template->pre_first_nb_rb_ul);
+      UE_template->pre_allocated_nb_rb_ul = nb_rb;
+      max_num_ue--;
+      if (max_num_ue == 0) /* in this case, cannot allocate any other UE anymore */
+        return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0);
+      continue;
     }
-  }
 
-  // step 3: assigne RBS
-  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    // if (continueTable[UE_id]) continue;
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      // This is the actual CC_id in the list
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      UE_template = &UE_list->UE_template[CC_id][UE_id];
-      harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],
-                                  sched_frameP, sched_subframeP);
+    const int B = cmax(UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes, 0);
+    const int UE_to_be_scheduled = UE_is_to_be_scheduled(Mod_id, CC_id, UE_id);
+    if (B == 0 && !UE_to_be_scheduled)
+      continue;
 
-      //      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
+    num_ue_req++;
 
-      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0) {
-        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
-      } else {
-        nb_allocated_rbs[CC_id][UE_id] =
-          cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_idx], average_rbs_per_user[CC_id]);
-      }
+    /* if UE has pending scheduling request then pre-allocate 3 RBs */
+    if (B == 0 && UE_to_be_scheduled) {
+      UE_template->pre_assigned_mcs_ul = 10; /* use QPSK mcs only */
+      rb_idx_required[UE_id] = 2;
+      //UE_template->pre_allocated_nb_rb_ul = 3;
+      continue;
+    }
 
-      total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id];
-      LOG_D(MAC, "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",
-            nb_allocated_rbs[CC_id][UE_id],
+    int mcs;
+    int rb_table_index;
+    int tx_power;
+    calculate_max_mcs_min_rb(
+        Mod_id,
+        CC_id,
+        B,
+        UE_template->phr_info,
+        UE_info->UE_sched_ctrl[UE_id].phr_received == 1 ? 20 : 10,
+        &mcs,
+        max_rb,
+        &rb_table_index,
+        &tx_power);
+
+    UE_template->pre_assigned_mcs_ul = mcs;
+    rb_idx_required[UE_id] = rb_table_index;
+    //UE_template->pre_allocated_nb_rb_ul = rb_table[rb_table_index];
+    /* only print log when PHR changed */
+    static int phr = 0;
+    if (phr != UE_template->phr_info) {
+      phr = UE_template->phr_info;
+      LOG_D(MAC, "%d.%d UE %d CC %d: pre mcs %d, pre rb_table[%d]=%d RBs (phr %d, tx power %d, bytes %d)\n",
+            frame,
+            subframe,
             UE_id,
-            rntiTable[UE_id],
             CC_id,
-            harq_pid);
-    }
-  }
+            UE_template->pre_assigned_mcs_ul,
+            UE_template->pre_allocated_rb_table_index_ul,
+            UE_template->pre_allocated_nb_rb_ul,
+            UE_template->phr_info,
+            tx_power,
+            B);
+    }
+  }
+
+  if (num_ue_req == 0)
+    return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0);
+
+  // calculate how many users should be in both regions, and to maximize usage,
+  // go from the larger to the smaller one which at least will handle a single
+  // full load case better.
+  const int n = min(num_ue_req, max_num_ue);
+  int nr[2] = {n, 0};
+  int step = 1; // the order if we have two regions
+  int start = 0;
+  int end = 1;
+  if (num_contig_rb > 1) {
+    // proportionally divide between both regions
+    int la = rbs[0].length > 0 ? rbs[0].length : 1;
+    int lb = rbs[1].length > 0 ? rbs[1].length : 1;
+    nr[1] = min(max(n/(la/lb + 1), 1), n - 1);
+    nr[0] = n - nr[1];
+    step = la > lb ? 1 : -1; // 1: from 0 to 1, -1: from 1 to 0
+    start = la > lb ? 0 : 1;
+    end = la > lb ? 2 : -1;
+  }
+
+  if (g_start_ue_ul == -1)
+    g_start_ue_ul = UE_list->head;
+  int sUE_id = g_start_ue_ul;
+  int rb_idx_given[MAX_MOBILES_PER_ENB];
+  memset(rb_idx_given, 0, sizeof(rb_idx_given));
+
+  for (int r = start; r != end; r += step) {
+    // don't allocate if we have too little RBs
+    if (rbs[r].length < 3)
+      continue;
+    if (nr[r] <= 0)
+      continue;
 
-  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
-  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
-    // if (continueTable[UE_id]) continue;
-    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      // This is the actual CC_id in the list
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      UE_template = &UE_list->UE_template[CC_id][UE_id];
-      N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth);
-      first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx];
-      available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset);
-      total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id];
-
-      if (total_ue_count[CC_id] == 1) {
-        total_remaining_rbs[CC_id]++;
+    UE_list_t UE_sched;
+    // average RB index: just below the index that fits all UEs
+    int start_idx = pp_find_rb_table_index(rbs[r].length / nr[r]) - 1;
+    int num_ue_sched = 0;
+    int rb_required_add = 0;
+    int *cur_UE = &UE_sched.head;
+    while (num_ue_sched < nr[r]) {
+      while (rb_idx_required[sUE_id] == 0)
+        sUE_id = next_ue_list_looped(UE_list, sUE_id);
+      const int cqi = UE_info->UE_sched_ctrl[sUE_id].dl_cqi[CC_id];
+      const int idx = CCE_try_allocate_ulsch(Mod_id, CC_id, subframe, sUE_id, cqi);
+      if (idx < 0) {
+        LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", sUE_id);
+        nr[r]--;
+        sUE_id = next_ue_list_looped(UE_list, sUE_id); // next candidate
+        continue;
       }
-
-      while (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0 &&
-             nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx] &&
-             total_remaining_rbs[CC_id] > 0) {
-        nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id] + 1, UE_template->pre_allocated_nb_rb_ul[slice_idx]);
-        total_remaining_rbs[CC_id]--;
-        total_allocated_rbs[CC_id]++;
+      UE_info->UE_template[CC_id][sUE_id].pre_dci_ul_pdu_idx = idx;
+      *cur_UE = sUE_id;
+      cur_UE = &UE_sched.next[sUE_id];
+      rb_idx_given[sUE_id] = min(start_idx, rb_idx_required[sUE_id]);
+      rb_required_add += rb_table[rb_idx_required[sUE_id]] - rb_table[rb_idx_given[sUE_id]];
+      rbs[r].length -= rb_table[rb_idx_given[sUE_id]];
+      num_ue_sched++;
+      sUE_id = next_ue_list_looped(UE_list, sUE_id);
+    }
+    *cur_UE = -1;
+
+    /* give remaining RBs in RR fashion. Since we don't know in advance the
+     * amount of RBs we can give (the "step size" in rb_table is non-linear), go
+     * through all UEs and try to give a bit more. Continue until no UE can be
+     * given a higher index because the remaining RBs do not suffice to increase */
+    int UE_id = UE_sched.head;
+    int rb_required_add_old;
+    do {
+      rb_required_add_old = rb_required_add;
+      for (int UE_id = UE_sched.head; UE_id >= 0; UE_id = UE_sched.next[UE_id]) {
+        if (rb_idx_given[UE_id] >= rb_idx_required[UE_id])
+          continue; // this UE does not need more
+        const int new_idx = rb_idx_given[UE_id] + 1;
+        const int rb_inc = rb_table[new_idx] - rb_table[rb_idx_given[UE_id]];
+        if (rbs[r].length < rb_inc)
+          continue;
+        rb_idx_given[UE_id] = new_idx;
+        rbs[r].length -= rb_inc;
+        rb_required_add -= rb_inc;
       }
-
-      UE_template->pre_allocated_nb_rb_ul[slice_idx] = nb_allocated_rbs[CC_id][UE_id];
-      LOG_D(MAC, "******************UL Scheduling Information for UE%d CC_id %d ************************\n",
+    } while (rb_required_add != rb_required_add_old);
+
+    for (UE_id = UE_sched.head; UE_id >= 0; UE_id = UE_sched.next[UE_id]) {
+      UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
+
+      /* MCS has been allocated previously */
+      UE_template->pre_first_nb_rb_ul = rbs[r].start;
+      UE_template->pre_allocated_rb_table_index_ul = rb_idx_given[UE_id];
+      UE_template->pre_allocated_nb_rb_ul = rb_table[rb_idx_given[UE_id]];
+      rbs[r].start += rb_table[rb_idx_given[UE_id]];
+      LOG_D(MAC, "%4d.%d UE %d allocated %d RBs start %d new start %d\n",
+            sched_frame,
+            sched_subframe,
             UE_id,
-            CC_id);
-      LOG_D(MAC, "[eNB %d] total RB allocated for UE%d CC_id %d  = %d\n",
-            module_idP,
-            UE_id,
-            CC_id,
-            UE_template->pre_allocated_nb_rb_ul[slice_idx]);
+            UE_template->pre_allocated_nb_rb_ul,
+            UE_template->pre_first_nb_rb_ul,
+            rbs[r].start);
     }
   }
 
-  return;
-}
-
-void
-assign_max_mcs_min_rb(module_id_t module_idP,
-                      int slice_idx,
-                      int frameP,
-                      sub_frame_t subframeP,
-                      uint16_t *first_rb) {
-  int i;
-  uint16_t n, UE_id;
-  uint8_t CC_id;
-  int mcs;
-  int rb_table_index = 0, tbs, tx_power;
-  eNB_MAC_INST *eNB = RC.mac[module_idP];
-  UE_list_t *UE_list = &eNB->UE_list;
-  slice_info_t *sli = &eNB->slice_info;
-  UE_TEMPLATE *UE_template;
-  UE_sched_ctrl_t *ue_sched_ctl;
-  int Ncp;
-  int N_RB_UL;
-  int first_rb_offset, available_rbs;
-
-  for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) {
-    if (UE_list->UE_sched_ctrl[i].phr_received == 1) {
-      /* if we've received the power headroom information the UE, we can go to
-       * maximum mcs */
-      mcs = cmin(20, sli->ul[slice_idx].maxmcs);
-    } else {
-      /* otherwise, limit to QPSK PUSCH */
-      mcs = cmin(10, sli->ul[slice_idx].maxmcs);
-    }
-
-    UE_id = i;
-
-    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
-      // This is the actual CC_id in the list
-      CC_id = UE_list->ordered_ULCCids[n][UE_id];
-      AssertFatal(CC_id < RC.nb_mac_CC[module_idP], "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
-                  CC_id,
-                  NFAPI_CC_MAX,
-                  n,
-                  UE_id,
-                  UE_list->numactiveULCCs[UE_id]);
-      UE_template = &UE_list->UE_template[CC_id][UE_id];
-      UE_template->pre_assigned_mcs_ul = mcs;
-      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
-      Ncp = eNB->common_channels[CC_id].Ncp;
-      N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth);
-      ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL);
-      int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes;
-
-      if (bytes_to_schedule < 0) bytes_to_schedule = 0;
-
-      int bits_to_schedule = bytes_to_schedule * 8;
-
-      // if this UE has UL traffic
-      if (bits_to_schedule > 0) {
-        tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well!
-        rb_table_index = 2;
-        // fixme: set use_srs flag
-        tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0);
-
-        while ((UE_template->phr_info - tx_power < 0 || tbs > bits_to_schedule) && UE_template->pre_assigned_mcs_ul > 3) {
-          // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs);
-          UE_template->pre_assigned_mcs_ul--;
-          tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3;
-          tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0);   // fixme: set use_srs
-        }
-
-        first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx];
-        available_rbs =
-          cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset);
-
-        while (tbs < bits_to_schedule &&
-               rb_table[rb_table_index] < available_rbs &&
-               UE_template->phr_info - tx_power > 0 &&
-               rb_table_index < 32) {
-          rb_table_index++;
-          tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3;
-          tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0);
-        }
-
-        if (rb_table[rb_table_index] > (available_rbs - 1)) {
-          rb_table_index--;
-        }
-
-        // 1 or 2 PRB with cqi enabled does not work well
-        if (rb_table[rb_table_index] < 3) {
-          rb_table_index = 2; //3PRB
-        }
-
-        UE_template->pre_allocated_rb_table_index_ul = rb_table_index;
-        UE_template->pre_allocated_nb_rb_ul[slice_idx] = rb_table[rb_table_index];
-        LOG_D(MAC, "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n",
-              module_idP,
-              frameP,
-              subframeP,
-              UE_id,
-              CC_id,
-              UE_template->pre_assigned_mcs_ul,
-              UE_template->pre_allocated_rb_table_index_ul,
-              UE_template->pre_allocated_nb_rb_ul[slice_idx],
-              UE_template->phr_info, tx_power);
-      } else {
-        /* if UE has pending scheduling request then pre-allocate 3 RBs */
-        //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) {
-        if (UE_is_to_be_scheduled(module_idP, CC_id, i)) {
-          /* use QPSK mcs */
-          UE_template->pre_assigned_mcs_ul = 10;
-          UE_template->pre_allocated_rb_table_index_ul = 2;
-          UE_template->pre_allocated_nb_rb_ul[slice_idx] = 3;
-        } else {
-          UE_template->pre_assigned_mcs_ul = 0;
-          UE_template->pre_allocated_rb_table_index_ul = -1;
-          UE_template->pre_allocated_nb_rb_ul[slice_idx] = 0;
-        }
-      }
-    }
+  /* if not all UEs could be allocated in this round */
+  if (num_ue_req > max_num_ue) {
+    /* go to the first one we missed */
+    for (int i = 0; i < max_num_ue; ++i)
+      g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul);
+  } else {
+    /* else, just start with the next UE next time */
+    g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul);
   }
-}
-
-struct sort_ue_ul_params {
-  int module_idP;
-  int sched_frameP;
-  int sched_subframeP;
-};
-
-static int ue_ul_compare(const void *_a, const void *_b, void *_params) {
-  struct sort_ue_ul_params *params = _params;
-  UE_list_t *UE_list = &RC.mac[params->module_idP]->UE_list;
-  int UE_id1 = *(const int *) _a;
-  int UE_id2 = *(const int *) _b;
-  int rnti1 = UE_RNTI(params->module_idP, UE_id1);
-  int pCCid1 = UE_PCCID(params->module_idP, UE_id1);
-  int round1 = maxround_ul(params->module_idP, rnti1, params->sched_frameP,
-                           params->sched_subframeP);
-  int rnti2 = UE_RNTI(params->module_idP, UE_id2);
-  int pCCid2 = UE_PCCID(params->module_idP, UE_id2);
-  int round2 = maxround_ul(params->module_idP, rnti2, params->sched_frameP,
-                           params->sched_subframeP);
-
-  if (round1 > round2)
-    return -1;
-
-  if (round1 < round2)
-    return 1;
-
-  if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] >
-      UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
-    return -1;
-
-  if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] <
-      UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0])
-    return 1;
-
-  int bytes_to_schedule1 = UE_list->UE_template[pCCid1][UE_id1].estimated_ul_buffer - UE_list->UE_template[pCCid1][UE_id1].scheduled_ul_bytes;
-
-  if (bytes_to_schedule1 < 0) bytes_to_schedule1 = 0;
-
-  int bytes_to_schedule2 = UE_list->UE_template[pCCid2][UE_id2].estimated_ul_buffer - UE_list->UE_template[pCCid2][UE_id2].scheduled_ul_bytes;
-
-  if (bytes_to_schedule2 < 0) bytes_to_schedule2 = 0;
-
-  if (bytes_to_schedule1 > bytes_to_schedule2)
-    return -1;
 
-  if (bytes_to_schedule1 < bytes_to_schedule2)
-    return 1;
-
-  if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul >
-      UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
-    return -1;
-
-  if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul <
-      UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul)
-    return 1;
-
-  if (UE_list->UE_sched_ctrl[UE_id1].cqi_req_timer >
-      UE_list->UE_sched_ctrl[UE_id2].cqi_req_timer)
-    return -1;
-
-  if (UE_list->UE_sched_ctrl[UE_id1].cqi_req_timer <
-      UE_list->UE_sched_ctrl[UE_id2].cqi_req_timer)
-    return 1;
-
-  return 0;
+  return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0);
 }
 
-//-----------------------------------------------------------------------------
-/*
- * This function sorts the UEs in order, depending on their ulsch buffer and CQI
- */
-void sort_ue_ul(module_id_t module_idP,
-                int slice_idx,
-                int sched_frameP,
-                sub_frame_t sched_subframeP,
-                rnti_t *rntiTable)
-//-----------------------------------------------------------------------------
-{
-  int list[MAX_MOBILES_PER_ENB];
-  int list_size = 0;
-  struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP };
-  UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
-  UE_sched_ctrl_t *UE_scheduling_control = NULL;
-
-  for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
-    UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]);
-
-    /* Check CDRX configuration and if UE is in active time for this subframe */
-    if (UE_scheduling_control->cdrx_configured == TRUE) {
-      if (UE_scheduling_control->in_active_time == FALSE) {
-        continue;
-      }
-    }
-
-    rntiTable[i] = UE_RNTI(module_idP, i);
-
-    // Valid element and is not the actual CC_id in the list
-    if (UE_list->active[i] == TRUE &&
-        rntiTable[i] != NOT_A_RNTI &&
-        UE_list->UE_sched_ctrl[i].ul_out_of_sync != 1 &&
-        ue_ul_slice_membership(module_idP, i, slice_idx)) {
-      list[list_size++] = i; // Add to list
+void ulsch_scheduler_pre_processor(module_id_t Mod_id,
+                                   int CC_id,
+                                   int frameP,
+                                   sub_frame_t subframeP,
+                                   int sched_frameP,
+                                   unsigned char sched_subframeP) {
+  UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info;
+  const int N_RB_UL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].ul_Bandwidth);
+  COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id];
+
+  UE_list_t UE_to_sched;
+  UE_to_sched.head = -1;
+  for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i)
+    UE_to_sched.next[i] = -1;
+
+  int last_UE_id = -1;
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
+    UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+    /* initialize per-UE scheduling information */
+    UE_template->pre_assigned_mcs_ul = 0;
+    UE_template->pre_allocated_nb_rb_ul = 0;
+    UE_template->pre_allocated_rb_table_index_ul = -1;
+    UE_template->pre_first_nb_rb_ul = 0;
+    UE_template->pre_dci_ul_pdu_idx = -1;
+
+    const rnti_t rnti = UE_RNTI(Mod_id, UE_id);
+    if (rnti == NOT_A_RNTI) {
+      LOG_E(MAC, "UE %d has RNTI NOT_A_RNTI!\n", UE_id);
+      continue;
     }
-  }
+    if (ue_sched_ctrl->cdrx_configured && !ue_sched_ctrl->in_active_time)
+      continue;
+    if (UE_info->UE_template[CC_id][UE_id].rach_resource_type > 0)
+      continue;
 
-  qsort_r(list, list_size, sizeof(int), ue_ul_compare, &params);
+    /* define UEs to schedule */
+    if (UE_to_sched.head < 0)
+      UE_to_sched.head = UE_id;
+    else
+      UE_to_sched.next[last_UE_id] = UE_id;
+    UE_to_sched.next[UE_id] = -1;
+    last_UE_id = UE_id;
+  }
+
+  if (UE_to_sched.head < 0)
+    return;
+
+  int last_rb_blocked = 1;
+  int n_contig = 0;
+  contig_rbs_t rbs[2]; // up to two contig RBs for PRACH in between
+  for (int i = 0; i < N_RB_UL; ++i) {
+    if (cc->vrb_map_UL[i] == 0 && last_rb_blocked == 1) {
+      last_rb_blocked = 0;
+      n_contig++;
+      AssertFatal(n_contig <= 2, "cannot handle more than two contiguous RB regions\n");
+      rbs[n_contig - 1].start = i;
+    }
+    if (cc->vrb_map_UL[i] == 1 && last_rb_blocked == 0) {
+      last_rb_blocked = 1;
+      rbs[n_contig - 1].length = i - rbs[n_contig - 1].start;
+    }
+  }
+
+  round_robin_ul(Mod_id,
+                 CC_id,
+                 frameP,
+                 subframeP,
+                 sched_frameP,
+                 sched_subframeP,
+                 &UE_to_sched,
+                 4, // max_num_ue
+                 n_contig,
+                 rbs);
+
+  // the following block is meant for validation of the pre-processor to check
+  // whether all UE allocations are non-overlapping and is not necessary for
+  // scheduling functionality
+#ifdef DEBUG_eNB_SCHEDULER
+  char t[101] = "__________________________________________________"
+                "__________________________________________________";
+  t[N_RB_UL] = 0;
+  for (int j = 0; j < N_RB_UL; j++)
+    if (cc->vrb_map_UL[j] != 0)
+      t[j] = 'x';
+  int print = 0;
+  for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
+    UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id];
+    if (UE_template->pre_allocated_nb_rb_ul == 0)
+      continue;
 
-  if (list_size) { // At mimimum one list element
-    for (int i = 0; i < list_size - 1; i++) {
-      UE_list->next_ul[list[i]] = list[i + 1];
+    print = 1;
+    uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id],
+                                        sched_frameP, sched_subframeP);
+    LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n",
+          frameP,
+          subframeP,
+          UE_id,
+          UE_template->pre_allocated_nb_rb_ul,
+          UE_template->pre_allocated_rb_table_index_ul,
+          UE_template->pre_first_nb_rb_ul,
+          UE_template->pre_assigned_mcs_ul,
+          UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0 ? "(retx)" : "");
+
+    for (int i = 0; i < UE_template->pre_allocated_nb_rb_ul; ++i) {
+      /* only check if this is not a retransmission */
+      if (UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] == 0
+          && cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] == 1) {
+
+        LOG_I(MAC, "%4d.%d UL scheduler allocation list: %s\n", frameP, subframeP, t);
+        LOG_E(MAC,
+              "%4d.%d: UE %d allocated at locked RB %d (is: allocated start "
+              "%d/length %d)\n",
+              frameP, subframeP, UE_id, UE_template->pre_first_nb_rb_ul + i,
+              UE_template->pre_first_nb_rb_ul,
+              UE_template->pre_allocated_nb_rb_ul);
+      }
+      cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] = 1;
+      t[UE_template->pre_first_nb_rb_ul + i] = UE_id + '0';
     }
-
-    UE_list->next_ul[list[list_size - 1]] = -1;
-    UE_list->head_ul = list[0];
-  } else { // No element
-    UE_list->head_ul = -1;
   }
+  if (print)
+    LOG_D(MAC,
+          "%4d.%d UL scheduler allocation list: %s\n",
+          sched_frameP,
+          sched_subframeP,
+          t);
+#endif
 }
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index 19b1c7708bd..0d1afdf2a24 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -390,7 +390,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
         LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(module_idP,
             UE_mac_inst[module_idP].crnti,
             eNB_indexP, frameP, subframeP,
-            ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6,0, 0
+            ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 0, 0
                                                                               );
 
         if (UE_mac_inst[module_idP].crnti_before_ho)
@@ -406,7 +406,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
                 module_idP, frameP, rlc_status.bytes_in_buffer,
                 dcch_header_len);
 
-        sdu_lengths = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used
+        sdu_lengths = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6,
                                        (char *) &ulsch_buff[0],0,
                                        0
                                       );
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 12058519152..24630c0fe2c 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -1972,6 +1972,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
                                          subframe, ENB_FLAG_NO,
                                          lcid);
       lcid_buffer_occupancy_new = lcid_buffer_occupancy_old;
+#if 0
+      /* TODO: those assert crash the L2 simulator with the new RLC.
+       *       Are they necessary?
+       */
       AssertFatal(lcid_buffer_occupancy_new ==
                   UE_mac_inst[module_idP].
                   scheduling_info.LCID_buffer_remain[lcid],
@@ -1990,6 +1994,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
                   scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
                                             scheduling_info.LCGID
                                             [lcid]]);
+#endif
 
       //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
       //Adjust at the end of the loop
@@ -2085,18 +2090,10 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
       }
 
       //Update Buffer remain and BSR bytes after transmission
-      AssertFatal(lcid_buffer_occupancy_new <=
-                  lcid_buffer_occupancy_old,
-                  "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n",
-                  lcid_buffer_occupancy_new,
-                  lcid_buffer_occupancy_old, lcid,
-                  lcid_rlc_pdu_count, frameP, subframe);
-      UE_mac_inst[module_idP].scheduling_info.
-      LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new;
-      UE_mac_inst[module_idP].
-      scheduling_info.BSR_bytes[UE_mac_inst[module_idP].
-                                scheduling_info.LCGID[lcid]] +=
-                                  (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old);
+      UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new;
+      UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] += (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old);
+      if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] < 0)
+        UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0;
 
       //Update the number of LCGID with data as BSR shall reflect status after BSR transmission
       if ((num_lcg_id_with_data > 1)
@@ -2809,7 +2806,6 @@ update_bsr(module_id_t module_idP, frame_t frameP,
 
       rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
                                       lcid,
-                                      0xFFFF, //TBS is not used in RLC at this step, set a special value for debug
                                       0, 0
                                      );
       lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer;
@@ -3176,7 +3172,7 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_
         for (int j = 0; j < ue->numCommFlows; j++) {
           if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ) {
             rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
-                                            ue->SL_LCID[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]);
+                                            ue->SL_LCID[i], ue->sourceL2Id, ue->destinationList[j]);
 
             if (rlc_status.bytes_in_buffer > 2) {
               LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer);
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index ae231641943..cfde40daad1 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -79,6 +79,47 @@ nr_bandentry_t nr_bandtable[] = {
   {261,27500000,28350000,27500000,28350000,  2,2070833, 120}
 };
 
+
+// TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
+// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
+// When l' = l0, it is represented by 1
+// E.g. when symbol duration is 12 in colomn 7, value 1057 ('10000100001') which means l' =  l0, 5, 10.
+
+int32_t table_6_4_1_1_3_3_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
+{-1,          -1,          -1,         -1,          1,          1,         1,         1},       //<4              // (DMRS l' position)
+{1,            1,           1,          1,          1,          1,         1,         1},       //4               // (DMRS l' position)
+{1,            1,           1,          1,          1,          5,         5,         5},       //5               // (DMRS l' position)
+{1,            1,           1,          1,          1,          5,         5,         5},       //6               // (DMRS l' position)
+{1,            1,           1,          1,          1,          5,         5,         5},       //7               // (DMRS l' position)
+{1,          129,         129,        129,          1,         65,        73,        73},       //8               // (DMRS l' position)
+{1,          129,         129,        129,          1,         65,        73,        73},       //9               // (DMRS l' position)
+{1,          513,         577,        577,          1,        257,       273,       585},       //10              // (DMRS l' position)
+{1,          513,         577,        577,          1,        257,       273,       585},       //11              // (DMRS l' position)
+{1,          513,         577,       2337,          1,       1025,      1057,       585},       //12              // (DMRS l' position)
+{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //13              // (DMRS l' position)
+{1,         2049,        2177,       2337,          1,       1025,      1057,       585},       //14              // (DMRS l' position)
+};
+
+
+// TS 38.211 Table 6.4.1.1.3-4: PUSCH DMRS positions l' within a slot for double-symbol DMRS and intra-slot frequency hopping disabled.
+// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
+// When l' = l0, it is represented by 1
+
+int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {                             // Duration in symbols
+{-1,          -1,          -1,         -1,         -1,         -1,        -1,         -1},       //<4              // (DMRS l' position)
+{1,            1,          -1,         -1,         -1,         -1,        -1,         -1},       //4               // (DMRS l' position)
+{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //5               // (DMRS l' position)
+{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //6               // (DMRS l' position)
+{1,            1,          -1,         -1,          1,          1,        -1,         -1},       //7               // (DMRS l' position)
+{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //8               // (DMRS l' position)
+{1,            1,          -1,         -1,          1,         33,        -1,         -1},       //9               // (DMRS l' position)
+{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //10              // (DMRS l' position)
+{1,          257,          -1,         -1,          1,        129,        -1,         -1},       //11              // (DMRS l' position)
+{1,          257,          -1,         -1,          1,        513,        -1,         -1},       //12              // (DMRS l' position)
+{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //13              // (DMRS l' position)
+{1,         1025,          -1,         -1,          1,        513,        -1,         -1},       //14              // (DMRS l' position)
+};
+
 #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
 
 void get_band(uint64_t downlink_frequency,
@@ -517,6 +558,112 @@ int get_num_dmrs(uint16_t dmrs_mask ) {
   return(num_dmrs);
 }
 
+/*******************************************************************
+*
+* NAME :         get_l0_ul
+*
+* PARAMETERS :   mapping_type : PUSCH mapping type
+*                dmrs_typeA_position  : higher layer parameter
+*
+* RETURN :       demodulation reference signal for PUSCH
+*
+* DESCRIPTION :  see TS 38.211 V15.4.0 Demodulation reference signals for PUSCH
+*
+*********************************************************************/
+
+uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
+
+  return ((mapping_type==typeA)?dmrs_typeA_position:0);
+
+}
+
+int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength) {
+
+  uint8_t row, colomn;
+  int32_t l_prime;
+
+  colomn = additional_pos;
+
+  if (mapping_type == typeB)
+    colomn += 4;
+
+  if (duration_in_symbols < 4)
+    row = 0;
+  else
+    row = duration_in_symbols - 3;
+
+  if (pusch_maxLength == pusch_len1)
+    l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn];
+  else
+    l_prime = table_6_4_1_1_3_4_pusch_dmrs_positions_l[row][colomn];
+
+  AssertFatal(l_prime>0,"invalid l_prime < 0\n");
+
+  return l_prime;
+}
+
+/*******************************************************************
+*
+* NAME :         get_L_ptrs
+*
+* PARAMETERS :   mcs(i)                 higher layer parameter in PTRS-UplinkConfig
+*                I_mcs                  MCS index used for PUSCH
+*                mcs_table              0 for table 5.1.3.1-1, 1 for table 5.1.3.1-1
+*
+* RETURN :       the parameter L_ptrs
+*
+* DESCRIPTION :  3GPP TS 38.214 section 6.2.3.1
+*
+*********************************************************************/
+
+uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table) {
+
+  uint8_t mcs4;
+
+  if(mcs_table == 0)
+    mcs4 = 29;
+  else
+    mcs4 = 28;
+
+  if (I_mcs < mcs1) {
+    LOG_I(PHY, "PUSH PT-RS is not present.\n");
+    return -1;
+  } else if (I_mcs >= mcs1 && I_mcs < mcs2)
+    return 2;
+  else if (I_mcs >= mcs2 && I_mcs < mcs3)
+    return 1;
+  else if (I_mcs >= mcs3 && I_mcs < mcs4)
+    return 0;
+  else {
+    LOG_I(PHY, "PT-RS time-density determination is obtained from the DCI for the same transport block in the initial transmission\n");
+    return -1;
+  }
+}
+
+/*******************************************************************
+*
+* NAME :         get_K_ptrs
+*
+* PARAMETERS :   ptrs_UplinkConfig      PTRS uplink configuration
+*                N_RB                   number of RBs scheduled for PUSCH
+*
+* RETURN :       the parameter K_ptrs
+*
+* DESCRIPTION :  3GPP TS 38.214 6.2.3 Table 6.2.3.1-2
+*
+*********************************************************************/
+
+uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
+
+  if (N_RB < nrb0) {
+    LOG_I(PHY,"PUSH PT-RS is not present.\n");
+    return -1;
+  } else if (N_RB >= nrb0 && N_RB < nrb1)
+    return 0;
+  else
+    return 1;
+}
+
 uint16_t nr_dci_size(nr_dci_format_t format,
 		     nr_rnti_type_t rnti_type,
 		     uint16_t N_RB) {
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
index 2cfce4766f7..63c81def82b 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
@@ -45,7 +45,7 @@ extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
 extern UE_RRC_INST *UE_rrc_inst;
 extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
 extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
-extern int cqi_to_mcs[16];
+extern const int cqi_to_mcs[16];
 extern uint32_t RRC_CONNECTION_FLAG;
 extern uint8_t rb_table[34];
 extern mac_rlc_am_muilist_t rlc_am_mui;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 36d285e320e..3c625ec2ff1 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -166,6 +166,11 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
                          nr_dci_pdu_rel15_t *nr_pdci_info_extracted);
 
 
+uint8_t
+nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
+           sub_frame_t subframe, uint8_t eNB_index,
+           uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) ;
+
 int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
                          int nrofDownlinkSlots, int nrofDownlinkSymbols,
                          int nrofUplinkSlots,   int nrofUplinkSymbols);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 58b312038a2..a49a3f51a30 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -118,7 +118,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id,
   //fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
   nr_phy_config_t *phy_config = &mac->phy_config;
 
-  //ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti;
+  //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti;
   // First we need to verify if DCI ind contains a ul-sch to be perfomred. If it does, we will handle a PUSCH in the UL_CONFIG_REQ.
   ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUCCH;
   for (int i=0; i<10; i++) {
@@ -128,29 +128,28 @@ int8_t nr_ue_process_dlsch(module_id_t module_id,
   }
   if (ul_config->ul_config_list[ul_config->number_pdus].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
     // fill in the elements in config request inside P5 message
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.bandwidth_part_ind = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.frame_offset = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.pusch_freq_hopping = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.mcs = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.accumulated_delta_PUSCH = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.tpmi = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.n_dmrs_cdm_groups = 0;
-    for (int i=0;i<4;i++) ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.dmrs_ports[i]=0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.n_front_load_symb = 0;
-    //ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.srs_config = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.csi_reportTriggerSize = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.maxCodeBlockGroupsPerTransportBlock = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.ptrs_dmrs_association_port = 0;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15.beta_offset_ind = 0;
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.bandwidth_part_ind = 0; //FIXME
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rb_size = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rb_start = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.nr_of_symbols = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.start_symbol_index = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.frequency_hopping = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.mcs_index = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.new_data_indicator = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.rv_index = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.harq_process_id = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.absolute_delta_PUSCH = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.nrOfLayers = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.transform_precoding = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.dmrs_ports = 0;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.dmrs_config_type = 0;
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.n_front_load_symb = 0; //FIXME
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.srs_config = 0; //FIXME
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.csi_reportTriggerSize = 0; //FIXME
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.maxCodeBlockGroupsPerTransportBlock = 0; //FIXME
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.ptrs_dmrs_association_port = 0; FIXME
+    //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.beta_offset_ind = 0; //FIXME
   } else { // If DCI ind is not format 0_0 or 0_1, we will handle a PUCCH in the UL_CONFIG_REQ
     ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUCCH;
     // If we handle PUCCH common
@@ -468,7 +467,6 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
   uint32_t number_of_search_space_per_slot=UINT_MAX;
   uint32_t first_symbol_index=UINT_MAX;
   uint32_t search_space_duration;  //  element of search space
-  uint32_t coreset_duration;  //  element of coreset
   //  38.213 table 10.1-1
 
   /// MUX PATTERN 1
@@ -604,8 +602,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
   }
 
   AssertFatal(number_of_search_space_per_slot!=UINT_MAX,"");
-  coreset_duration = num_symbols * number_of_search_space_per_slot;
   /*
+  uint32_t coreset_duration = num_symbols * number_of_search_space_per_slot;
     mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0];
     mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1];
     mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2];   //  CCE aggregation level = 4
@@ -1669,7 +1667,7 @@ uint8_t table_7_3_2_3_3_4_twoCodeword[6][10] = {
   {2,0,1,2,3,6,7,8,0,2},
   {2,0,1,2,3,6,7,8,9,2}
 };
-int8_t nr_ue_process_dci_freq_dom_resource_assignment(fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu,
+int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
 						      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
 						      uint16_t n_RB_ULBWP,
 						      uint16_t n_RB_DLBWP,
@@ -1692,7 +1690,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(fapi_nr_ul_config_pusch_pd
     dlsch_config_pdu->start_rb   = NRRIV2PRBOFFSET(riv,n_RB_DLBWP);
 
   }
-  if(ulsch_config_pdu != NULL){
+  if(pusch_config_pdu != NULL){
     /*
      * TS 38.214 subclause 6.1.2.2 Resource allocation in frequency domain (uplink)
      */
@@ -1703,14 +1701,14 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(fapi_nr_ul_config_pusch_pd
      * TS 38.214 subclause 6.1.2.2.2 Uplink resource allocation type 1
      */
 
-    ulsch_config_pdu->number_rbs = NRRIV2BW(riv,n_RB_ULBWP);
-    ulsch_config_pdu->start_rb   = NRRIV2PRBOFFSET(riv,n_RB_ULBWP);
+    pusch_config_pdu->rb_size  = NRRIV2BW(riv,n_RB_ULBWP);
+    pusch_config_pdu->rb_start = NRRIV2PRBOFFSET(riv,n_RB_ULBWP);
   }
   return 0;
 }
 
 int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
-						      fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu,
+						      nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
 						      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
 						      uint8_t time_domain_ind
 						      ){
@@ -1849,9 +1847,6 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       SLIV2SL(startSymbolAndLength,&S,&L);
       dlsch_config_pdu->start_symbol=S;
       dlsch_config_pdu->number_symbols=L;
-      dlsch_config_pdu->frame_offset = pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->k0!=NULL ?
-	*pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->k0 : 
-	0;
     }
     else {// Default configuration from tables
       k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
@@ -1866,14 +1861,13 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0];
       // sliv_S   = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1];
       // sliv_L   = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2];
-      dlsch_config_pdu->frame_offset = k_offset;
       dlsch_config_pdu->number_symbols = sliv_L;
       dlsch_config_pdu->start_symbol = sliv_S;
     }
   }	/*
 	 * TS 38.214 subclause 6.1.2.1 Resource allocation in time domain (uplink)
 	 */
-  if(ulsch_config_pdu != NULL){
+  if(pusch_config_pdu != NULL){
     NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
     if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config)
       pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
@@ -1885,12 +1879,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength;
       int S,L;
       SLIV2SL(startSymbolAndLength,&S,&L);
-      ulsch_config_pdu->start_symbol=S;
-      ulsch_config_pdu->number_symbols=L;
-      ulsch_config_pdu->frame_offset = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2!=NULL ?
-	*pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2 : 
-	 mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing < NR_SubcarrierSpacing_kHz60 ? 1 :
-	mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing < NR_SubcarrierSpacing_kHz120 ? 2 : 3;
+      pusch_config_pdu->start_symbol_index=S;
+      pusch_config_pdu->nr_of_symbols=L;
     }
     else {
       k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
@@ -1899,9 +1889,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
       // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0];
       // sliv_S   = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1];
       // sliv_L   = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2];
-      ulsch_config_pdu->frame_offset = k_offset;
-      ulsch_config_pdu->number_symbols = sliv_L;
-      ulsch_config_pdu->start_symbol = sliv_S;
+      pusch_config_pdu->nr_of_symbols = sliv_L;
+      pusch_config_pdu->start_symbol_index = sliv_S;
     }
   }
   return 0;
@@ -1917,6 +1906,7 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
 
   nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,&dci_pdu_rel15);
   nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format);
+  return 0;
 }
 
 int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
@@ -1953,45 +1943,41 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
      *    50 SUL_IND_0_0:
      */
     ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti;
-    fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti;
+    nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
     /* IDENTIFIER_DCI_FORMATS */
     /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */
-    nr_ue_process_dci_freq_dom_resource_assignment(ulsch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL);
+    nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL);
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
     nr_ue_process_dci_time_dom_resource_assignment(mac,
-						   ulsch_config_pdu_0_0,NULL,
+						   pusch_config_pdu_0_0,NULL,
 						   dci->time_dom_resource_assignment);
 
     /* FREQ_HOPPING_FLAG */
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
-      ulsch_config_pdu_0_0->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled;
+      pusch_config_pdu_0_0->frequency_hopping = dci->freq_hopping_flag;
     /* MCS */
-    ulsch_config_pdu_0_0->mcs = dci->mcs;
+    pusch_config_pdu_0_0->mcs_index = dci->mcs;
     /* NDI */
-    ulsch_config_pdu_0_0->ndi = dci->ndi;
+    pusch_config_pdu_0_0->pusch_data.new_data_indicator = dci->ndi;
     /* RV */
-    ulsch_config_pdu_0_0->rv = dci->rv;
+    pusch_config_pdu_0_0->pusch_data.rv_index = dci->rv;
     /* HARQ_PROCESS_NUMBER */
-    ulsch_config_pdu_0_0->harq_process_nbr = dci->harq_process_number;
+    pusch_config_pdu_0_0->pusch_data.harq_process_id = dci->harq_process_number;
     /* TPC_PUSCH */
     // according to TS 38.213 Table Table 7.1.1-1
     if (dci->tpc_pusch == 0) {
-      ulsch_config_pdu_0_0->accumulated_delta_PUSCH = -1;
-      ulsch_config_pdu_0_0->absolute_delta_PUSCH = -4;
+      pusch_config_pdu_0_0->absolute_delta_PUSCH = -4;
     }
     if (dci->tpc_pusch == 1) {
-      ulsch_config_pdu_0_0->accumulated_delta_PUSCH = 0;
-      ulsch_config_pdu_0_0->absolute_delta_PUSCH = -1;
+      pusch_config_pdu_0_0->absolute_delta_PUSCH = -1;
     }
     if (dci->tpc_pusch == 2) {
-      ulsch_config_pdu_0_0->accumulated_delta_PUSCH = 1;
-      ulsch_config_pdu_0_0->absolute_delta_PUSCH = 1;
+      pusch_config_pdu_0_0->absolute_delta_PUSCH = 1;
     }
     if (dci->tpc_pusch == 3) {
-      ulsch_config_pdu_0_0->accumulated_delta_PUSCH = 3;
-      ulsch_config_pdu_0_0->absolute_delta_PUSCH = 4;
+      pusch_config_pdu_0_0->absolute_delta_PUSCH = 4;
     }
     /* SUL_IND_0_0 */ // To be implemented, FIXME!!!
 
@@ -2028,49 +2014,45 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
      *    49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space
      */
     ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-    ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti;
-    fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15;
+    ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti;
+    nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
     /* IDENTIFIER_DCI_FORMATS */
     /* CARRIER_IND */
     /* SUL_IND_0_1 */
     /* BANDWIDTH_PART_IND */
-    ulsch_config_pdu_0_1->bandwidth_part_ind = dci->bandwidth_part_ind;
+    //pusch_config_pdu_0_1->bandwidth_part_ind = dci->bandwidth_part_ind; //FIXME
     /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */
-    nr_ue_process_dci_freq_dom_resource_assignment(ulsch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL);
+    nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL);
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
-    nr_ue_process_dci_time_dom_resource_assignment(mac,ulsch_config_pdu_0_1,NULL,
+    nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,
 						   dci->time_dom_resource_assignment);
     /* FREQ_HOPPING_FLAG */
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
-      ulsch_config_pdu_0_1->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled;
+      pusch_config_pdu_0_1->frequency_hopping = dci->freq_hopping_flag;
     /* MCS */
-    ulsch_config_pdu_0_1->mcs = dci->mcs;
+    pusch_config_pdu_0_1->mcs_index = dci->mcs;
     /* NDI */
-    ulsch_config_pdu_0_1->ndi = dci->ndi;
+    pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi;
     /* RV */
-    ulsch_config_pdu_0_1->rv = dci->rv;
+    pusch_config_pdu_0_1->pusch_data.rv_index = dci->rv;
     /* HARQ_PROCESS_NUMBER */
-    ulsch_config_pdu_0_1->harq_process_nbr = dci->harq_process_number;
+    pusch_config_pdu_0_1->pusch_data.harq_process_id = dci->harq_process_number;
     /* FIRST_DAI */ //To be implemented, FIXME!!!
     /* SECOND_DAI */ //To be implemented, FIXME!!!
     /* TPC_PUSCH */
     // according to TS 38.213 Table Table 7.1.1-1
     if (dci->tpc_pusch == 0) {
-      ulsch_config_pdu_0_1->accumulated_delta_PUSCH = -1;
-      ulsch_config_pdu_0_1->absolute_delta_PUSCH = -4;
+      pusch_config_pdu_0_1->absolute_delta_PUSCH = -4;
     }
     if (dci->tpc_pusch == 1) {
-      ulsch_config_pdu_0_1->accumulated_delta_PUSCH = 0;
-      ulsch_config_pdu_0_1->absolute_delta_PUSCH = -1;
+      pusch_config_pdu_0_1->absolute_delta_PUSCH = -1;
     }
     if (dci->tpc_pusch == 2) {
-      ulsch_config_pdu_0_1->accumulated_delta_PUSCH = 1;
-      ulsch_config_pdu_0_1->absolute_delta_PUSCH = 1;
+      pusch_config_pdu_0_1->absolute_delta_PUSCH = 1;
     }
     if (dci->tpc_pusch == 3) {
-      ulsch_config_pdu_0_1->accumulated_delta_PUSCH = 3;
-      ulsch_config_pdu_0_1->absolute_delta_PUSCH = 4;
+      pusch_config_pdu_0_1->absolute_delta_PUSCH = 4;
     }
     /* SRS_RESOURCE_IND */
     //FIXME!!
@@ -2087,16 +2069,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
 		(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 3) ||
 		(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 4))){
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][0];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][1];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][0];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][1];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_partialAndNonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][2];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][3];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][2];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][3];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][4];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][5];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][4];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][5];
 	  }
 	}
 	// Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1
@@ -2104,16 +2086,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
 	     || (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled))
 	    && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1)){
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][6];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][7];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][6];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][7];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_partialAndNonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][8];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][9];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][8];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][9];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][10];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][11];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][10];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][11];
 	  }
 	}
       }
@@ -2122,12 +2104,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
 	if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled)
 	    && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 2)){
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][12];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][13];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][12];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][13];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][14];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][15];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][14];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][15];
 	  }
 	}
 	// Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1
@@ -2135,12 +2117,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
 	     || (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled))
 	    && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1)){
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) {
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][16];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][17];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][16];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][17];
 	  }
 	  if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){
-	    ulsch_config_pdu_0_1->n_layers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][18];
-	    ulsch_config_pdu_0_1->tpmi     = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][19];
+	    pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][18];
+	    pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precod_nbr_layers][19];
 	  }
 	}
       }
@@ -2150,146 +2132,158 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6
-      ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-      ulsch_config_pdu_0_1->dmrs_ports[0] = dci->antenna_ports;
+      pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+      pusch_config_pdu_0_1->dmrs_ports = dci->antenna_ports; //TBC
     }
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-7
-      ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-      ulsch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 3)?(dci->antenna_ports-4):(dci->antenna_ports);
-      ulsch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 3)?2:1;
+      pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+      pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports > 3)?(dci->antenna_ports-4):(dci->antenna_ports); //TBC
+      //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME
     }
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-8/9/10/11
       if (rank == 1){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 1)?2:1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports-2):(dci->antenna_ports);
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 1)?2:1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports > 1)?(dci->antenna_ports-2):(dci->antenna_ports); //TBC
       }
       if (rank == 2){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 0)?2:1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0;
-	ulsch_config_pdu_0_1->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 0)?2:1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0;
+	//pusch_config_pdu_0_1->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1;
       }
       if (rank == 3){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = 0;
-	ulsch_config_pdu_0_1->dmrs_ports[1] = 1;
-	ulsch_config_pdu_0_1->dmrs_ports[2] = 2;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = 0;
+	//pusch_config_pdu_0_1->dmrs_ports[1] = 1;
+	//pusch_config_pdu_0_1->dmrs_ports[2] = 2;
       }
       if (rank == 4){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = 0;
-	ulsch_config_pdu_0_1->dmrs_ports[1] = 1;
-	ulsch_config_pdu_0_1->dmrs_ports[2] = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[3] = 3;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = 0;
+	//pusch_config_pdu_0_1->dmrs_ports[1] = 1;
+	//pusch_config_pdu_0_1->dmrs_ports[2] = 2;
+	//pusch_config_pdu_0_1->dmrs_ports[3] = 3;
       }
     }
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-12/13/14/15
       if (rank == 1){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 1)?2:1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 5 ?(dci->antenna_ports-6):(dci->antenna_ports-2)):dci->antenna_ports;
-	ulsch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 6)?2:1;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 1)?2:1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports > 1)?(dci->antenna_ports > 5 ?(dci->antenna_ports-6):(dci->antenna_ports-2)):dci->antenna_ports; //TBC
+	//pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 6)?2:1; //FIXME
       }
       if (rank == 2){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 0)?2:1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_13[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 3)?2:1;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 0)?2:1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_13[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 3)?2:1; // FIXME
       }
       if (rank == 3){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_14[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_14[dci->antenna_ports][3];
-	ulsch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 1)?2:1;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_14[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_14[dci->antenna_ports][3];
+	//pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 1)?2:1; //FIXME
       }
       if (rank == 4){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_15[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_15[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_15[dci->antenna_ports][3];
-	ulsch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_15[dci->antenna_ports][4];
-	ulsch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 1)?2:1;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_15[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_15[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_15[dci->antenna_ports][3];
+	//pusch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_15[dci->antenna_ports][4];
+	//pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 1)?2:1; //FIXME
       }
     }
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-16/17/18/19
       if (rank == 1){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 1)?((dci->antenna_ports > 5)?3:2):1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 5 ?(dci->antenna_ports-6):(dci->antenna_ports-2)):dci->antenna_ports;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 1)?((dci->antenna_ports > 5)?3:2):1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports > 1)?(dci->antenna_ports > 5 ?(dci->antenna_ports-6):(dci->antenna_ports-2)):dci->antenna_ports; //TBC
       }
       if (rank == 2){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 0)?((dci->antenna_ports > 2)?3:2):1;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_17[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_17[dci->antenna_ports][2];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 0)?((dci->antenna_ports > 2)?3:2):1; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_17[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_17[dci->antenna_ports][2];
       }
       if (rank == 3){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = (dci->antenna_ports > 0)?3:2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_18[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_18[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_18[dci->antenna_ports][3];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports > 0)?3:2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_18[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_18[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_18[dci->antenna_ports][3];
       }
       if (rank == 4){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = dci->antenna_ports + 2;
-	ulsch_config_pdu_0_1->dmrs_ports[0] = 0;
-	ulsch_config_pdu_0_1->dmrs_ports[1] = 1;
-	ulsch_config_pdu_0_1->dmrs_ports[2] = 2;
-	ulsch_config_pdu_0_1->dmrs_ports[3] = 3;
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = dci->antenna_ports + 2; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = 0;
+	//pusch_config_pdu_0_1->dmrs_ports[1] = 1;
+	//pusch_config_pdu_0_1->dmrs_ports[2] = 2;
+	//pusch_config_pdu_0_1->dmrs_ports[3] = 3;
       }
     }
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-20/21/22/23
       if (rank == 1){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = table_7_3_1_1_2_20[dci->antenna_ports][0];
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_20[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports][2];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports][0]; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = table_7_3_1_1_2_20[dci->antenna_ports][1]; //TBC
+	//pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports][2]; //FIXME
       }
       if (rank == 2){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = table_7_3_1_1_2_21[dci->antenna_ports][0];
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports][3];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_21[dci->antenna_ports][0]; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports][3]; //FIXME
       }
       if (rank == 3){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = table_7_3_1_1_2_22[dci->antenna_ports][0];
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_22[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_22[dci->antenna_ports][3];
-	ulsch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports][4];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_22[dci->antenna_ports][0]; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_22[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_22[dci->antenna_ports][3];
+	//pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports][4]; //FIXME
       }
       if (rank == 4){
-	ulsch_config_pdu_0_1->n_dmrs_cdm_groups = table_7_3_1_1_2_23[dci->antenna_ports][0];
-	ulsch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_23[dci->antenna_ports][1];
-	ulsch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_23[dci->antenna_ports][2];
-	ulsch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_23[dci->antenna_ports][3];
-	ulsch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_23[dci->antenna_ports][4];
-	ulsch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports][5];
+	pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_23[dci->antenna_ports][0]; //TBC
+	pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME
+	//pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_23[dci->antenna_ports][1];
+	//pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_23[dci->antenna_ports][2];
+	//pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_23[dci->antenna_ports][3];
+	//pusch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_23[dci->antenna_ports][4];
+	//pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports][5]; //FIXME
       }
     }
     /* SRS_REQUEST */
     // if SUL is supported in the cell, there is an additional bit in thsi field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!!
-    ulsch_config_pdu_0_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212
+    //pusch_config_pdu_0_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 //FIXME
     /* CSI_REQUEST */
-    ulsch_config_pdu_0_1->csi_reportTriggerSize = dci->csi_request;
+    //pusch_config_pdu_0_1->csi_reportTriggerSize = dci->csi_request; //FIXME
     /* CBGTI */
-    ulsch_config_pdu_0_1->maxCodeBlockGroupsPerTransportBlock = dci->cbgti;
+    //pusch_config_pdu_0_1->maxCodeBlockGroupsPerTransportBlock = dci->cbgti; //FIXME
     /* PTRS_DMRS */
     if (((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) &&
 	 (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.ptrs_uplink_config == 0)) ||
 	((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
 	 (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1))){
     } else {
-      ulsch_config_pdu_0_1->ptrs_dmrs_association_port = dci->ptrs_dmrs;
+      //pusch_config_pdu_0_1->ptrs_dmrs_association_port = dci->ptrs_dmrs; //FIXME
     }
     /* BETA_OFFSET_IND */
     // Table 9.3-3 in [5, TS 38.213]
-    ulsch_config_pdu_0_1->beta_offset_ind = dci->beta_offset_ind;
+    //pusch_config_pdu_0_1->beta_offset_ind = dci->beta_offset_ind; //FIXME
     /* DMRS_SEQ_INI */
     // FIXME!!
     /* UL_SCH_IND */
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index c911fbd56a6..b5fdea67604 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -51,7 +51,6 @@ extern RAN_CONTEXT_t RC;
 extern void mac_top_init_gNB(void);
 extern uint8_t nfapi_mode;
 
-
 void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
 
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
@@ -283,7 +282,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
   else LOG_I(PHY,"TDD has been properly configurated\n");
   }
 
-
 /*
   // PDCCH-ConfigCommon
   cfg->pdcch_config.controlResourceSetZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index e5840d9cd19..702b034809f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -61,6 +61,8 @@
 
 uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
 
+uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
+
 void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
                                 int CC_idP,
                                 frame_t frameP,
@@ -299,6 +301,67 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
 }
 */
 
+void nr_schedule_pucch(int Mod_idP,
+                       int UE_id,
+                       frame_t frameP,
+                       sub_frame_t slotP) {
+
+  uint16_t O_uci;
+  uint16_t O_ack;
+  uint8_t SR_flag = 0; // no SR in PUCCH implemented for now
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
+  AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
+
+  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
+  int bwp_id=1;
+  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
+  nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
+
+  NR_sched_pucch *curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch;
+  NR_sched_pucch *temp_pucch;
+  int release_pucch = 0;
+
+  if (curr_pucch != NULL) {
+    if ((frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
+      UL_tti_req->SFN = frameP;
+      UL_tti_req->Slot = slotP;
+      UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
+      UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
+      nfapi_nr_pucch_pdu_t  *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
+      memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
+      UL_tti_req->n_pdus+=1;
+      O_ack = curr_pucch->dai_c;
+      O_uci = O_ack; // for now we are just sending acknacks in pucch
+
+      nr_configure_pucch(pucch_pdu,
+			 scc,
+			 ubwp,
+                         curr_pucch->resource_indicator,
+                         O_uci,
+                         O_ack,
+                         SR_flag);
+
+      release_pucch = 1;
+    }
+  }
+
+  if (release_pucch) {
+    temp_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch;
+    UE_list->UE_sched_ctrl[UE_id].sched_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch->next_sched_pucch;
+    free(temp_pucch);
+  }
+
+}
+
+bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
+
+  if((bitmap>>slot)&0x01)
+    return true;
+  else
+    return false;
+}
+
 void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
                                frame_t frame_rxP,
                                sub_frame_t slot_rxP,
@@ -312,8 +375,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   int CC_id, UE_id = 0;
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
   NR_UE_list_t *UE_list = &gNB->UE_list;
-  UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+  NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
   NR_COMMON_channels_t *cc = gNB->common_channels;
+  NR_sched_pucch *pucch_sched = (NR_sched_pucch*) malloc(sizeof(NR_sched_pucch));
 
   start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
@@ -327,27 +391,27 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   // Check if there are downlink symbols in the slot, 
   if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)) {
 
-  memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    //mbsfn_status[CC_id] = 0;
+    memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      //mbsfn_status[CC_id] = 0;
 
-    // clear vrb_maps
-    memset(cc[CC_id].vrb_map, 0, 100);
-    memset(cc[CC_id].vrb_map_UL, 0, 100);
+      // clear vrb_maps
+      memset(cc[CC_id].vrb_map, 0, 100);
+      memset(cc[CC_id].vrb_map_UL, 0, 100);
 
-    clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
-  }
+      clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
+    }
 
-  // refresh UE list based on UEs dropped by PHY in previous subframe
-  /*
-  for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
-    if (UE_list->active[i]) {
+    // refresh UE list based on UEs dropped by PHY in previous subframe
+    /*
+    for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
+      if (UE_list->active[i]) {
 
-      nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
+        nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
       
       
-      rnti = 0;//UE_RNTI(module_idP, i);
-      CC_id = 0;//UE_PCCID(module_idP, i);
+        rnti = 0;//UE_RNTI(module_idP, i);
+        CC_id = 0;//UE_PCCID(module_idP, i);
       
     } //END if (UE_list->active[i])
   } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
@@ -359,7 +423,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   }
 
   // TbD once RACH is available, start ta_timer when UE is connected
-  if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
+#if 0
+   if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
 
   if (ue_sched_ctl->ta_timer == 0) {
     gNB->ta_command = ue_sched_ctl->ta_update;
@@ -371,19 +436,20 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     /* MAC CE flag indicating TA length */
     gNB->ta_len = 2;
   }
+#endif
 
   // Phytest scheduling
   if (get_softmodem_params()->phy_test && slot_txP==1){
-    nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL);
-    // resetting ta flag
+    nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, pucch_sched, NULL);
+        // resetting ta flag
     gNB->ta_len = 0;
   }
 
-  /*
-  // Allocate CCEs for good after scheduling is done
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
-    allocate_CCEs(module_idP, CC_id, subframeP, 0);
-  */
+    /*
+    // Allocate CCEs for good after scheduling is done
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
+      allocate_CCEs(module_idP, CC_id, subframeP, 0);
+    */
 
   } //is_nr_DL_slot
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 1e0fd8d9a22..050f07ba670 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -249,9 +249,14 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
   }
 }
 
+
+
+
+
 int configure_fapi_dl_pdu(int Mod_idP,
                           int *CCEIndex,
                           nfapi_nr_dl_tti_request_body_t *dl_req,
+			  NR_sched_pucch *pucch_sched,
                           uint8_t *mcsIndex,
                           uint16_t *rbSize,
                           uint16_t *rbStart) {
@@ -260,13 +265,12 @@ int configure_fapi_dl_pdu(int Mod_idP,
   gNB_MAC_INST                        *nr_mac  = RC.nrmac[Mod_idP];
   NR_COMMON_channels_t                *cc      = nr_mac->common_channels;
   NR_ServingCellConfigCommon_t        *scc     = cc->ServingCellConfigCommon;
-  
+
   nfapi_nr_dl_tti_request_pdu_t  *dl_tti_pdcch_pdu;
   nfapi_nr_dl_tti_request_pdu_t  *dl_tti_pdsch_pdu;
   int TBS, bwp_id = 1, UE_id = 0;
   NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
 
-
   NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
   AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
 	      "downlinkBWP_ToAddModList has %d BWP!\n",
@@ -351,10 +355,10 @@ int configure_fapi_dl_pdu(int Mod_idP,
   dci_pdu_rel15[0].ndi = 1;
   dci_pdu_rel15[0].rv = 0;
   dci_pdu_rel15[0].harq_pid = 0;
-  dci_pdu_rel15[0].dai = 2;
+  dci_pdu_rel15[0].dai = (pucch_sched->dai_c-1)&3;
   dci_pdu_rel15[0].tpc = 2;
-  dci_pdu_rel15[0].pucch_resource_indicator = 7;
-  dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = 7;
+  dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
+  dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = pucch_sched->timing_indicator;
   
   LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
 	dci_pdu_rel15[0].frequency_domain_assignment,
@@ -413,7 +417,6 @@ int configure_fapi_dl_pdu(int Mod_idP,
 	pdsch_pdu_rel15->NrOfCodewords,
 	pdsch_pdu_rel15->mcsIndex[0],
 	TBS);
-
   return TBS; //Return TBS in bytes
 }
 
@@ -491,6 +494,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP,
 void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
                                    frame_t       frameP,
                                    sub_frame_t   slotP,
+                                   NR_sched_pucch *pucch_sched,
                                    nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){
 
   LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n");
@@ -537,7 +541,8 @@ void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
 
   TBS_bytes = configure_fapi_dl_pdu(module_idP,
                                     CCEIndices,
-                                    dl_req, 
+                                    dl_req,
+				    pucch_sched, 
                                     dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
                                     dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
                                     dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
@@ -562,7 +567,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
                                         ENB_FLAG_YES,
                                         MBMS_FLAG_NO,
                                         lcid,
-                                        TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
                                         0,
                                         0);
 
@@ -579,7 +583,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
                                                    ENB_FLAG_YES,
                                                    MBMS_FLAG_NO,
                                                    lcid,
-                                                   TBS_bytes,
+                                                   TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
                                                    (char *)&mac_sdus[sdu_length_total],
                                                    0,
                                                    0);
@@ -599,13 +603,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
       break;
       }
     }
-
   } //if (IS_SOFTMODEM_NOS1)
   else {
 
     //When the --NOS1 option is not enabled, DLSCH transmissions with random data
     //occur every time that the current function is called (dlsch phytest mode)
-
     LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP);
 
     // fill dlsch_buffer with random data
@@ -719,12 +721,12 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
 
   UL_tti_req->SFN = frameP;
   UL_tti_req->Slot = slotP;
-  UL_tti_req->n_pdus = 1;
-  UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
-  UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
-  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
+  UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
+  UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
+  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu;
   memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
-  
+  UL_tti_req->n_pdus+=1;  
+
   LOG_D(MAC, "Scheduling UE specific PUSCH\n");
   //UL_tti_req = &nr_mac->UL_tti_req[CC_id];
   /*
@@ -758,14 +760,6 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   pusch_pdu->transform_precoding = 0;
   pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.;
   pusch_pdu->nrOfLayers = 1;
-  //DMRS
-  pusch_pdu->ul_dmrs_symb_pos = 1<<2; //for now the gnb assumes dmrs in the first symbol of the scheduled pusch resource
-  pusch_pdu->dmrs_config_type = 0;  //dmrs-type 1 (the one with a single DMRS symbol in the beginning)
-  pusch_pdu->ul_dmrs_scrambling_id =  0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
-  pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
-  //pusch_pdu->num_dmrs_cdm_grps_no_data;
-  //pusch_pdu->dmrs_ports; //DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
-  //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
   pusch_pdu->resource_alloc = 1; //type 1
   //pusch_pdu->rb_bitmap;// for ressource alloc type 0
   pusch_pdu->rb_start = 0;
@@ -777,6 +771,40 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
   //Resource Allocation in time domain
   pusch_pdu->start_symbol_index = 2;
   pusch_pdu->nr_of_symbols = 12;
+
+  // --------------------
+  // ------- DMRS -------
+  // --------------------
+  uint16_t l_prime_mask            = get_l_prime(pusch_pdu->nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
+  pusch_pdu->ul_dmrs_symb_pos      = l_prime_mask << pusch_pdu->start_symbol_index;
+  pusch_pdu->dmrs_config_type      = 0;      // dmrs-type 1 (the one with a single DMRS symbol in the beginning)
+  pusch_pdu->ul_dmrs_scrambling_id = 0;      // If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id
+  pusch_pdu->scid                  = 0;      // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
+                                             // Should match what is sent in DCI 0_1, otherwise set to 0
+  //pusch_pdu->num_dmrs_cdm_grps_no_data;
+  //pusch_pdu->dmrs_ports; // DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports
+                           // Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011,
+                           // and for each bit 0: DMRS port not used 1: DMRS port used
+  // --------------------------------------------------------------------------------------------------------------------------------------------
+
+  // --------------------
+  // ------- PTRS -------
+  // --------------------
+  uint8_t ptrs_mcs1 = 2;  // higher layer parameter in PTRS-UplinkConfig
+  uint8_t ptrs_mcs2 = 4;  // higher layer parameter in PTRS-UplinkConfig
+  uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
+  uint16_t n_rb0 = 25;    // higher layer parameter in PTRS-UplinkConfig
+  uint16_t n_rb1 = 75;    // higher layer parameter in PTRS-UplinkConfig
+  pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
+  pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
+  pusch_pdu->pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
+  pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+
+  if(1<<pusch_pdu->pusch_ptrs.ptrs_time_density >= pusch_pdu->nr_of_symbols)
+    pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+  // --------------------------------------------------------------------------------------------------------------------------------------------
+
+  //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
   //Optional Data only included if indicated in pduBitmap
   pusch_pdu->pusch_data.rv_index = 0;
   pusch_pdu->pusch_data.harq_process_id = 0;
@@ -785,7 +813,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
 						 pusch_pdu->target_code_rate,
 						 pusch_pdu->rb_size,
 						 pusch_pdu->nr_of_symbols,
-						 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI
+						 pusch_pdu->dmrs_config_type?4:6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI
 						 0, //nb_rb_oh
 						 pusch_pdu->nrOfLayers)>>3;
   pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
@@ -821,7 +849,6 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
 		     1, // ue-specific,
 		     scc,
 		     bwp);
-
   
   dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 93768558823..6d3f69f2179 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -507,7 +507,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
     AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
     AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
 		"searchPsacesToAddModList is empty\n");
-    NR_SearchSpace_t *ss;
+    NR_SearchSpace_t *ss=NULL;
     int found=0;
     int target_ss = NR_SearchSpace__searchSpaceType_PR_common;
     if (ss_type == 1) { 
@@ -545,12 +545,196 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
 }
 
 
+// This function configures pucch pdu fapi structure
+void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
+			NR_ServingCellConfigCommon_t *scc,
+			NR_BWP_Uplink_t *bwp,
+                        uint8_t pucch_resource,
+                        uint16_t O_uci,
+                        uint16_t O_ack,
+                        uint8_t SR_flag) {
+
+  NR_PUCCH_Config_t *pucch_Config;
+  NR_PUCCH_Resource_t *pucchres;
+  NR_PUCCH_ResourceSet_t *pucchresset;
+  NR_PUCCH_FormatConfig_t *pucchfmt;
+  NR_PUCCH_ResourceId_t *resource_id = NULL;
+
+  long *id0 = NULL;
+  int n_list, n_set;
+  uint16_t N2,N3;
+  int res_found = 0;
+
+  pucch_pdu->bit_len_harq = O_ack;
+
+  if (bwp) { // This is not the InitialBWP
+
+    NR_PUSCH_Config_t *pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup;
+    long *pusch_id = pusch_Config->dataScramblingIdentityPUSCH;
+
+    if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
+      id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup->transformPrecodingDisabled->scramblingID0;
+    if (pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL)
+      id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0;
+
+    // hop flags and hopping id are valid for any BWP
+    switch (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping){
+      case 0 :
+        // if neither, both disabled
+        pucch_pdu->group_hop_flag = 0;
+        pucch_pdu->sequence_hop_flag = 0;
+        break;
+      case 1 :
+        // if enable, group enabled
+        pucch_pdu->group_hop_flag = 1;
+        pucch_pdu->sequence_hop_flag = 0;
+        break;
+      case 2 :
+        // if disable, sequence disabled
+        pucch_pdu->group_hop_flag = 0;
+        pucch_pdu->sequence_hop_flag = 1;
+        break;
+      default:
+        AssertFatal(1==0,"Group hopping flag %ld undefined (0,1,2) \n", bwp->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping);
+    }
+
+    if (bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId != NULL)
+      pucch_pdu->hopping_id = *bwp->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId;
+    else
+      pucch_pdu->hopping_id = *scc->physCellId;
+
+    pucch_pdu->bwp_size  = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+    pucch_pdu->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+    pucch_pdu->subcarrier_spacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
+    pucch_pdu->cyclic_prefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix;
+
+    pucch_Config = bwp->bwp_Dedicated->pucch_Config->choice.setup;
+
+    AssertFatal(pucch_Config->resourceSetToAddModList!=NULL,
+		"PUCCH resourceSetToAddModList is null\n");
+
+    n_set = pucch_Config->resourceSetToAddModList->list.count; 
+    AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n");
+
+    N2 = 2;
+    // procedure to select pucch resource id from resource sets according to 
+    // number of uci bits and pucch resource indicator pucch_resource
+    // ( see table 9.2.3.2 in 38.213)
+    for (int i=0; i<n_set; i++) {
+      pucchresset = pucch_Config->resourceSetToAddModList->list.array[i];
+      n_list = pucchresset->resourceList.list.count;
+      if (pucchresset->pucch_ResourceSetId == 0 && O_uci<3) {
+        if (pucch_resource < n_list)
+          resource_id = pucchresset->resourceList.list.array[pucch_resource];
+        else 
+          AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
+      }
+      else {
+        N3 = pucchresset->maxPayloadMinus1!= NULL ?  *pucchresset->maxPayloadMinus1 : 1706;
+        if (N2<O_uci && N3>O_uci) {
+          if (pucch_resource < n_list)
+            resource_id = pucchresset->resourceList.list.array[pucch_resource];
+          else 
+            AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci);
+        }
+        else N2 = N3;
+      }
+    }
+
+    AssertFatal(resource_id!=NULL,"Couldn-t find any matching PUCCH resource in the PUCCH resource sets");
+
+    AssertFatal(pucch_Config->resourceToAddModList!=NULL,
+		"PUCCH resourceToAddModList is null\n");
+
+    n_list = pucch_Config->resourceToAddModList->list.count; 
+    AssertFatal(n_list>0,"PUCCH resourceToAddModList is empty\n");
+
+    // going through the list of PUCCH resources to find the one indexed by resource_id
+    for (int i=0; i<n_list; i++) {
+      pucchres = pucch_Config->resourceToAddModList->list.array[i];
+      if (pucchres->pucch_ResourceId == *resource_id) {
+        res_found = 1;
+        pucch_pdu->prb_start = pucchres->startingPRB;
+        // FIXME why there is only one frequency hopping flag
+        // what about inter slot frequency hopping?
+        pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ?  1 : 0;
+        pucch_pdu->second_hop_prb = pucchres->secondHopPRB!= NULL ?  *pucchres->secondHopPRB : 0;
+        switch(pucchres->format.present) {
+          case NR_PUCCH_Resource__format_PR_format0 :
+            pucch_pdu->format_type = 0;
+            pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift;
+            pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols;
+            pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex;
+            pucch_pdu->sr_flag = SR_flag;
+            break;
+          case NR_PUCCH_Resource__format_PR_format1 :
+            pucch_pdu->format_type = 1;
+            pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format1->initialCyclicShift;
+            pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols;
+            pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex;
+            pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC;
+            pucch_pdu->sr_flag = SR_flag;
+            break;
+          case NR_PUCCH_Resource__format_PR_format2 :
+            pucch_pdu->format_type = 2;
+            pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols;
+            pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
+            pucch_pdu->prb_size = pucchres->format.choice.format2->nrofPRBs;
+            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+            pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId;
+            break;
+          case NR_PUCCH_Resource__format_PR_format3 :
+            pucch_pdu->format_type = 3;
+            pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols;
+            pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex;
+            pucch_pdu->prb_size = pucchres->format.choice.format3->nrofPRBs;
+            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+            if (pucch_Config->format3 == NULL) {
+              pucch_pdu->pi_2bpsk = 0;
+              pucch_pdu->add_dmrs_flag = 0;
+            }
+            else {
+              pucchfmt = pucch_Config->format3->choice.setup;
+              pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
+              pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
+            }
+            break;
+          case NR_PUCCH_Resource__format_PR_format4 :
+            pucch_pdu->format_type = 4;
+            pucch_pdu->nr_of_symbols = pucchres->format.choice.format4->nrofSymbols;
+            pucch_pdu->start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex;
+            pucch_pdu->pre_dft_occ_len = pucchres->format.choice.format4->occ_Length;
+            pucch_pdu->pre_dft_occ_idx = pucchres->format.choice.format4->occ_Index;
+            pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
+            if (pucch_Config->format3 == NULL) {
+              pucch_pdu->pi_2bpsk = 0;
+              pucch_pdu->add_dmrs_flag = 0;
+            }
+            else {
+              pucchfmt = pucch_Config->format3->choice.setup;
+              pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ?  1 : 0;
+              pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ?  1 : 0;
+            }
+            break;
+          default :
+            AssertFatal(1==0,"Undefined PUCCH format \n");
+        }
+      }
+    }
+    AssertFatal(res_found==1,"No PUCCH resource found corresponding to id %ld\n",*resource_id);
+  }  
+  else { // this is for InitialBWP
+    AssertFatal(1==0,"Fill in InitialBWP PUCCH configuration\n");
+  }
+
+}
+
+
 
 void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
 			dci_pdu_rel15_t *dci_pdu_rel15,
 			int *dci_formats,
-			int *rnti_types
-			) {
+			int *rnti_types) {
   
   uint16_t N_RB = pdcch_pdu_rel15->BWPSize;
   uint8_t fsize=0, pos=0;
@@ -1003,6 +1187,171 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
   return -1;
 }
 
+
+void get_pdsch_to_harq_feedback(int Mod_idP,
+                                int UE_id,
+                                NR_SearchSpace__searchSpaceType_PR ss_type,
+                                uint8_t *pdsch_to_harq_feedback) {
+
+  int bwp_id=1;
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
+  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
+  NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
+
+  NR_SearchSpace_t *ss;
+
+  // common search type uses DCI format 1_0
+  if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) {
+    for (int i=0; i<8; i++)
+      pdsch_to_harq_feedback[i] = i+1;
+  }
+  else {
+    // searching for a ue specific search space
+    int found=0;
+
+    for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
+      ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
+      AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
+      AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
+      if (ss->searchSpaceType->present == ss_type) {
+	found=1;
+	break;
+      }
+    }
+    AssertFatal(found==1,"Couldn't find a ue specific searchspace\n");
+    if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) {
+      for (int i=0; i<8; i++)
+        pdsch_to_harq_feedback[i] = i+1;
+    }
+    else {
+      if(ubwp->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK != NULL)
+        pdsch_to_harq_feedback = (uint8_t *)ubwp->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK;
+      else
+        AssertFatal(found==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n");
+    }
+  }
+}
+
+
+// function to update pucch scheduling parameters in UE list when a USS DL is scheduled
+void nr_update_pucch_scheduling(int Mod_idP,
+                                int UE_id,
+                                frame_t frameP,
+                                sub_frame_t slotP,
+                                int slots_per_tdd,
+                                NR_sched_pucch *sched_pucch) {
+
+  NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
+  int first_ul_slot_tdd,k;
+  NR_sched_pucch *curr_pucch;
+  uint8_t pdsch_to_harq_feedback[8];
+  int found = 0;
+  int i = 0;
+  int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+  if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
+    nr_ulmix_slots++;
+
+  // this is hardcoded for now as ue specific
+  NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
+  get_pdsch_to_harq_feedback(Mod_idP,UE_id,ss_type,pdsch_to_harq_feedback);
+
+  // if the list of pucch to be scheduled is empty
+  if (UE_list->UE_sched_ctrl[UE_id].sched_pucch == NULL) {
+    sched_pucch->frame = frameP;
+    sched_pucch->next_sched_pucch = NULL;
+    sched_pucch->dai_c = 1;
+    sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource
+    if ( nr_ulmix_slots > 0 ) {
+      // first pucch occasion in first UL or MIXED slot
+      first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
+      for (k=0; k<nr_ulmix_slots; k++) { // for each possible UL or mixed slot
+        while (i<8 && found == 0)  {  // look if timing indicator is among allowed values
+          if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd))
+            found = 1;
+          if (found == 0) i++;
+        }
+        if (found == 1) break;
+      }
+      if (found == 1) {
+        // computing slot in which pucch is scheduled
+        sched_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd));
+        sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
+      }
+      else
+        AssertFatal(1==0,"No Uplink slot available in accordance to allowed timing indicator\n");
+    }
+    else
+      AssertFatal(1==0,"No Uplink Slots in this Frame\n");
+
+    UE_list->UE_sched_ctrl[UE_id].sched_pucch = sched_pucch;
+  }
+  else {  // to be tested
+    curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch;
+    if (curr_pucch->dai_c<MAX_ACK_BITS) {     // we are scheduling at most MAX_UCI_BITS harq-ack in the same pucch
+      while (i<8 && found == 0)  {  // look if timing indicator is among allowed values for current pucch
+        if (pdsch_to_harq_feedback[i]==(curr_pucch->ul_slot % slots_per_tdd)-(slotP % slots_per_tdd))
+          found = 1;
+        if (found == 0) i++;
+      }
+      if (found == 1) {  // scheduling this harq-ack in current pucch
+        sched_pucch = curr_pucch;
+        sched_pucch->dai_c = 1 + sched_pucch->dai_c;
+        sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
+      }
+    }
+    if (curr_pucch->dai_c==MAX_ACK_BITS || found == 0) { // if current pucch is full or no timing indicator allowed
+      // look for pucch occasions in other UL of mixed slots
+      for (k=scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; k<slots_per_tdd; k++) { // for each possible UL or mixed slot
+        if (k!=(curr_pucch->ul_slot % slots_per_tdd)) { // skip current scheduled slot (already checked)
+          i = 0;
+          while (i<8 && found == 0)  {  // look if timing indicator is among allowed values
+            if (pdsch_to_harq_feedback[i]==k-(slotP % slots_per_tdd))
+              found = 1;
+            if (found == 0) i++;
+          }
+          if (found == 1) {
+            if (k<(curr_pucch->ul_slot % slots_per_tdd)) { // we need to add a pucch occasion before current pucch
+              sched_pucch->frame = frameP;
+              sched_pucch->ul_slot =  k + (slotP - (slotP % slots_per_tdd));
+              sched_pucch->next_sched_pucch = curr_pucch;
+              sched_pucch->dai_c = 1;
+              sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource
+              sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
+              UE_list->UE_sched_ctrl[UE_id].sched_pucch = sched_pucch;
+            }
+            else {
+              while (curr_pucch->next_sched_pucch != NULL && k!=(curr_pucch->ul_slot % slots_per_tdd))
+                curr_pucch = curr_pucch->next_sched_pucch;
+              if (curr_pucch == NULL) {  // creating a new item in the list
+                sched_pucch->frame = frameP;
+                sched_pucch->next_sched_pucch = NULL;
+                sched_pucch->dai_c = 1;
+                sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
+                sched_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource
+                sched_pucch->ul_slot = k + (slotP - (slotP % slots_per_tdd));
+                curr_pucch->next_sched_pucch = (NR_sched_pucch*) malloc(sizeof(NR_sched_pucch));
+                curr_pucch->next_sched_pucch = sched_pucch;
+              }
+              else {
+                if (curr_pucch->dai_c==MAX_ACK_BITS)
+                  found = 0; // if pucch at index k is already full we have to find a new one in a following occasion
+                else { // scheduling this harq-ack in current pucch
+                  sched_pucch = curr_pucch;
+                  sched_pucch->dai_c = 1 + sched_pucch->dai_c;
+                  sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
 /*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg,
 					  nfapi_nr_coreset_t *coreset,
 					  nfapi_nr_search_space_t *search_space) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index ade52006273..eb8d3389493 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -236,7 +236,7 @@ void nr_process_mac_pdu(
 void nr_rx_sdu(const module_id_t gnb_mod_idP,
                const int CC_idP,
                const frame_t frameP,
-               const sub_frame_t subframeP,
+               const sub_frame_t slotP,
                const rnti_t rntiP,
                uint8_t *sduP,
                const uint16_t sdu_lenP,
@@ -245,7 +245,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
   int current_rnti = 0, UE_id = -1, harq_pid = 0;
   gNB_MAC_INST *gNB_mac = NULL;
   NR_UE_list_t *UE_list = NULL;
-  UE_sched_ctrl_t *UE_scheduling_control = NULL;
+  NR_UE_sched_ctrl_t *UE_scheduling_control = NULL;
 
   current_rnti = rntiP;
   UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
@@ -255,13 +255,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
   if (UE_id != -1) {
     UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
 
-    LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
+    LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
           gnb_mod_idP,
           harq_pid,
           CC_idP,
           frameP,
-          subframeP,
-          UE_scheduling_control->round_UL[CC_idP][harq_pid],
+          slotP,
           current_rnti,
           UE_id,
           ul_cqi);
@@ -277,7 +276,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 #endif
 
     if (sduP != NULL){
-      UE_scheduling_control->ta_update = timing_advance;
+      //UE_scheduling_control->ta_update = timing_advance;
       LOG_D(MAC, "Received PDU at MAC gNB \n");
       nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP);
     }
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index d55a188817d..c0f4053c03d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -35,6 +35,8 @@
 #include "PHY/defs_gNB.h"
 #include "NR_TAG-Id.h"
 
+#define MAX_ACK_BITS 2 //only format 0 is available for now
+
 void set_cset_offset(uint16_t);
 
 void mac_top_init_gNB(void);
@@ -83,6 +85,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
 int configure_fapi_dl_pdu(int Mod_id,
                          int *CCEIndeces,
                          nfapi_nr_dl_tti_request_body_t *dl_req,
+                         NR_sched_pucch *pucch_sched,
                          uint8_t *mcsIndex,
                          uint16_t *rbSize,
                          uint16_t *rbStart);
@@ -100,11 +103,24 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP,
 void nr_schedule_uss_dlsch_phytest(module_id_t   module_idP,
                                    frame_t       frameP,
                                    sub_frame_t   slotP,
+                                   NR_sched_pucch *pucch_sched,
                                    nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config);
 
 void nr_schedule_uss_ulsch_phytest(int Mod_idP,
                                    frame_t       frameP,
                                    sub_frame_t   slotP);
+
+void nr_update_pucch_scheduling(int Mod_idP,
+                                int UE_id,
+                                frame_t frameP,
+                                sub_frame_t slotP,
+                                int slots_per_tdd,
+                                NR_sched_pucch *sched_pucch);
+
+void get_pdsch_to_harq_feedback(int Mod_idP,
+                                int UE_id,
+                                NR_SearchSpace__searchSpaceType_PR ss_type,
+                                uint8_t *pdsch_to_harq_feedback);
   
 void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
                                   nr_scs_e scs_common,
@@ -124,7 +140,13 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
                           uint16_t slot,
                           nfapi_nr_config_request_scf_t cfg);
 */
-
+void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
+			NR_ServingCellConfigCommon_t *scc,
+			NR_BWP_Uplink_t *bwp,
+                        uint8_t pucch_resource,
+                        uint16_t O_uci,
+                        uint16_t O_ack,
+                        uint8_t SR_flag);
 void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
                         int ss_type,
                         NR_ServingCellConfigCommon_t *scc,
@@ -134,7 +156,6 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
                         dci_pdu_rel15_t *dci_pdu_rel15,
                         int *dci_formats,
                         int *rnti_types);
-
 int get_spf(nfapi_nr_config_request_scf_t *cfg);
 
 int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
@@ -162,6 +183,11 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
 int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
 
 int get_num_dmrs(uint16_t dmrs_mask );
+uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
+int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
+
+uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
+uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
 
 uint16_t nr_dci_size(nr_dci_format_t format,
                          nr_rnti_type_t rnti_type,
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 5bc320d5e2e..bf9358dd436 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -102,9 +102,22 @@ typedef struct {
   uint8_t num_sf_allocation_pattern;
 } NR_COMMON_channels_t;
 
-/*! \brief scheduling control information set through an API (not used)*/
+typedef struct NR_sched_pucch {
+  int frame;
+  int ul_slot;
+  uint8_t dai_c;
+  uint8_t timing_indicator;
+  uint8_t resource_indicator;
+  struct NR_sched_pucch *next_sched_pucch;
+} NR_sched_pucch;
+
+/*! \brief scheduling control information set through an API */
 typedef struct {
-  int dummy;
+  uint64_t dlsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains dlsch
+  uint64_t ulsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains ulsch
+  NR_sched_pucch *sched_pucch;
+  uint16_t ta_timer;
+  int16_t ta_update;
 } NR_UE_sched_ctrl_t;
 
 /*! \brief UE list used by eNB to order UEs/CC for scheduling*/
@@ -112,7 +125,7 @@ typedef struct {
 
   DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
   /// scheduling control info
-  UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
+  NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
   int next[MAX_MOBILES_PER_GNB];
   int head;
   int next_ul[MAX_MOBILES_PER_GNB];
@@ -124,7 +137,7 @@ typedef struct {
   NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
 } NR_UE_list_t;
 
-/*! \brief top level eNB MAC structure */
+/*! \brief top level gNB MAC structure */
 typedef struct gNB_MAC_INST_s {
   /// Ethernet parameters for northbound midhaul interface
   eth_params_t                    eth_params_n;
@@ -191,64 +204,62 @@ typedef struct gNB_MAC_INST_s {
 } gNB_MAC_INST;
 
 typedef struct {
-
-
-uint8_t format_indicator; //1 bit
-uint16_t frequency_domain_assignment; //up to 16 bits
-uint8_t time_domain_assignment; // 4 bits
-uint8_t frequency_hopping_flag; //1 bit
-
-uint8_t ra_preamble_index; //6 bits
-uint8_t ss_pbch_index; //6 bits
-uint8_t prach_mask_index; //4 bits
-
-uint8_t vrb_to_prb_mapping; //0 or 1 bit
-uint8_t mcs; //5 bits
-uint8_t ndi; //1 bit
-uint8_t rv; //2 bits
-uint8_t harq_pid; //4 bits
-uint8_t dai; //0, 2 or 4 bits
-uint8_t dai1; //1 or 2 bits
-uint8_t dai2; //0 or 2 bits
-uint8_t tpc; //2 bits
-uint8_t pucch_resource_indicator; //3 bits
-uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
-
-uint8_t short_messages_indicator; //2 bits
-uint8_t short_messages; //8 bits
-uint8_t tb_scaling; //2 bits
-
-uint8_t carrier_indicator; //0 or 3 bits
-uint8_t bwp_indicator; //0, 1 or 2 bits
-uint8_t prb_bundling_size_indicator; //0 or 1 bits
-uint8_t rate_matching_indicator; //0, 1 or 2 bits
-uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
-uint8_t transmission_configuration_indication; //0 or 3 bits
-uint8_t srs_request; //2 bits
-uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
-uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
-uint8_t dmrs_sequence_initialization; //0 or 1 bit
-
-uint8_t srs_resource_indicator;
-uint8_t precoding_information;
-uint8_t csi_request;
-uint8_t ptrs_dmrs_association;
-uint8_t beta_offset_indicator; //0 or 2 bits
-
-uint8_t slot_format_indicator_count;
-uint8_t *slot_format_indicators;
-
-uint8_t pre_emption_indication_count;
-uint16_t *pre_emption_indications; //14 bit
-
-uint8_t block_number_count;
-uint8_t *block_numbers;
-
-uint8_t ul_sul_indicator; //0 or 1 bit
-uint8_t antenna_ports;
-
-uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
-uint16_t padding;
+  uint8_t format_indicator; //1 bit
+  uint16_t frequency_domain_assignment; //up to 16 bits
+  uint8_t time_domain_assignment; // 4 bits
+  uint8_t frequency_hopping_flag; //1 bit
+  
+  uint8_t ra_preamble_index; //6 bits
+  uint8_t ss_pbch_index; //6 bits
+  uint8_t prach_mask_index; //4 bits
+  
+  uint8_t vrb_to_prb_mapping; //0 or 1 bit
+  uint8_t mcs; //5 bits
+  uint8_t ndi; //1 bit
+  uint8_t rv; //2 bits
+  uint8_t harq_pid; //4 bits
+  uint8_t dai; //0, 2 or 4 bits
+  uint8_t dai1; //1 or 2 bits
+  uint8_t dai2; //0 or 2 bits
+  uint8_t tpc; //2 bits
+  uint8_t pucch_resource_indicator; //3 bits
+  uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
+  
+  uint8_t short_messages_indicator; //2 bits
+  uint8_t short_messages; //8 bits
+  uint8_t tb_scaling; //2 bits
+  
+  uint8_t carrier_indicator; //0 or 3 bits
+  uint8_t bwp_indicator; //0, 1 or 2 bits
+  uint8_t prb_bundling_size_indicator; //0 or 1 bits
+  uint8_t rate_matching_indicator; //0, 1 or 2 bits
+  uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
+  uint8_t transmission_configuration_indication; //0 or 3 bits
+  uint8_t srs_request; //2 bits
+  uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
+  uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
+  uint8_t dmrs_sequence_initialization; //0 or 1 bit
+  
+  uint8_t srs_resource_indicator;
+  uint8_t precoding_information;
+  uint8_t csi_request;
+  uint8_t ptrs_dmrs_association;
+  uint8_t beta_offset_indicator; //0 or 2 bits
+  
+  uint8_t slot_format_indicator_count;
+  uint8_t *slot_format_indicators;
+  
+  uint8_t pre_emption_indication_count;
+  uint16_t *pre_emption_indications; //14 bit
+  
+  uint8_t block_number_count;
+  uint8_t *block_numbers;
+  
+  uint8_t ul_sul_indicator; //0 or 1 bit
+  uint8_t antenna_ports;
+  
+  uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
+  uint16_t padding;
 
 } dci_pdu_rel15_t;
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
deleted file mode 100644
index b9f62acc3c9..00000000000
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/*
-                             pdcp_proto_extern.h
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
-
- ***************************************************************************/
-#ifndef __PDCP_PROTO_EXTERN_H__
-#    define __PDCP_PROTO_EXTERN_H__
-
-//#    include "pdcp_entity.h"
-//#    include "rb_mux.h"
-#    include "mem_block.h"
-
-#ifdef ROHC
-extern void     pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t *sduP);
-extern void     pdcp_data_req (struct pdcp_entity *pdcpP, mem_block *sduP);
-extern void     send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block *cprimitiveP);
-extern void     control_pdcp (struct pdcp_entity *pdcpP);
-extern void pdcp_process_input_sdus_high(struct pdcp_entity *pdcpP);
-extern void     pdcp_process_input_sdus_am (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block *sduP);
-extern void     pdcp_process_output_sdus (struct pdcp_entity *pdcpP, mem_block *sduP, uint8_t rb_idP);
-extern void   pdcp_process_output_sdus_high (struct pdcp_entity *pdcpP, mem_block *sduP, uint16_t data_sizeP,  uint16_t rb_idP);
-extern void     pdcp_process_input_sdus_um (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block *sduP);
-extern void     pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block *sduP);
-extern void     init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP);
-extern void    *pdcp_tx (struct pdcp_entity *pdcpP, uint16_t data_sizeP, mem_block *sduP);
-extern int  reception_from_rohc_mt(void);
-extern int  reception_from_rohc_bs(void);
-#else
-extern BOOL     pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t *sduP, uint8_t is_data_plane);
-extern BOOL     pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char *sdu_buffer,
-                               uint8_t is_data_pdu,const uint32_t *const sourceL2Id,const uint32_t *const destinationL2Id
-                              );
-//extern BOOL     pdcp_data_req (struct pdcp_entity *pdcpP, mem_block * sduP);
-extern void     send_pdcp_control_primitive (struct pdcp_entity *pdcpP, mem_block *cprimitiveP);
-extern void     control_pdcp (struct pdcp_entity *pdcpP);
-extern void     pdcp_process_input_sdus_am (struct pdcp_entity *pdcpP);
-extern void     pdcp_process_output_sdus (struct pdcp_entity *pdcpP, mem_block *sduP, uint8_t rb_idP);
-extern void     pdcp_process_input_sdus_um (struct pdcp_entity *pdcpP);
-extern void     pdcp_process_input_sdus_tr (struct pdcp_entity *pdcpP);
-extern void     init_pdcp (struct pdcp_entity *pdcpP, struct rb_dispatcher *rbP, uint8_t rb_idP);
-extern void    *pdcp_tx (void *argP);
-#endif
-
-extern void pdcp_pc5_socket_init(void);
-
-#endif
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.c b/openair2/LAYER2/PROTO_AGENT/proto_agent.c
index bead6ad28d3..6bf9cdce229 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.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 <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent.h
  * \brief top level enb agent receive thread and itti task
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
index 927b714b2c4..6898c9e4474 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
@@ -1,32 +1,23 @@
-
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2014 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-   included in this distribution in the file called "COPYING". If not,
-   see <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file proto_agent.h
  * \brief top level protocol agent
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
index eef697c5bbe..df3684ee275 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
@@ -1,32 +1,23 @@
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2014 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-   included in this distribution in the file called "COPYING". If not,
-   see <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 #include "proto_agent_async.h"
 #include "proto_agent_defs.h"
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
index 27030924cdf..6bc952e804d 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.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 <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_async.h
  * \brief channel implementation for async interface
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
index a11c029bd36..6e343343cde 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.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 <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file proto_agent_common.c
  * \brief common primitives for all agents
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
index 70e6b2a84ec..c805b815433 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.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 <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_common.h
  * \brief common message primitves and utilities 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
index 08c91e70850..cd730a6de86 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
@@ -1,31 +1,23 @@
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2016 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-   included in this distribution in the file called "COPYING". If not,
-   see <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_defs.h
  * \brief enb agent common definitions 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
index cb65da28039..82f7849717f 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.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 <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_handler.c
  * \brief enb agent tx and rx message handler 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
index f64a58f8e15..9a63427ed58 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
@@ -1,31 +1,23 @@
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2016 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-   included in this distribution in the file called "COPYING". If not,
-   see <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_net_comm.c
  * \brief enb agent network interface abstraction 
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
index c956bf48b1d..55fca5a928e 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
@@ -1,31 +1,23 @@
-/*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2016 Eurecom
-
-    OpenAirInterface is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-
-    OpenAirInterface is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenAirInterface.The full GNU General Public License is
-   included in this distribution in the file called "COPYING". If not,
-   see <http://www.gnu.org/licenses/>.
-
-  Contact Information
-  OpenAirInterface Admin: openair_admin@eurecom.fr
-  OpenAirInterface Tech : openair_tech@eurecom.fr
-  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
-
-  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, 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.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
 
 /*! \file enb_agent_net_comm.h
  * \brief enb agent network interface abstraction 
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index 865a8153594..de947225bbd 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -459,7 +459,6 @@ struct mac_status_resp
 rlc_am_mac_status_indication (
   const protocol_ctxt_t *const ctxt_pP,
   void *const                 rlc_pP,
-  const uint16_t               tb_sizeP,
   struct mac_status_ind        tx_statusP,
   const eNB_flag_t enb_flagP) {
   struct mac_status_resp  status_resp;
@@ -491,10 +490,6 @@ rlc_am_mac_status_indication (
 
   rlc->last_absolute_subframe_status_indication = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP);
 
-  if (tb_sizeP > 0) {
-    rlc->nb_bytes_requested_by_mac = tb_sizeP;
-  }
-
   status_resp.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, rlc);
 
   // For eNB scheduler : Add Max RLC header size for new PDU
@@ -549,8 +544,7 @@ rlc_am_mac_status_indication (
       NULL,0,
       MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" STATUS-IND %u",
       MSC_AS_TIME_ARGS(ctxt_pP),
-      PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc),
-      tb_sizeP);
+      PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc));
     MSC_LOG_TX_MESSAGE(
       (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
       (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_MAC_ENB:MSC_MAC_UE,
@@ -565,26 +559,14 @@ rlc_am_mac_status_indication (
   }
 
   if (LOG_DEBUGFLAG(DEBUG_RLC)) {
-    if (tb_sizeP > 0) {
-      LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" MAC_STATUS_INDICATION (DATA) %d bytes -> %d bytes\n",
-             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc),
-             tb_sizeP,
-             status_resp.buffer_occupancy_in_bytes);
-    }
+    LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" MAC_STATUS_INDICATION (DATA) -> %d bytes\n",
+           PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc),
+           status_resp.buffer_occupancy_in_bytes);
   }
 
   return status_resp;
 }
 
-//-----------------------------------------------------------------------------
-void
-rlc_am_set_nb_bytes_requested_by_mac (
-  void *const            rlc_pP,
-  const tb_size_t         tb_sizeP
-) {
-  ((rlc_am_entity_t *) rlc_pP)->nb_bytes_requested_by_mac = tb_sizeP;
-}
-
 //-----------------------------------------------------------------------------
 struct mac_data_req
 rlc_am_mac_data_request (
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
index f2cb456e8cf..3127f67eca8 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h
@@ -255,23 +255,15 @@ rlc_am_get_pdus (
 */
 void     rlc_am_rx (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind);
 
-/*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP)
+/*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP)
 * \brief    Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission.
 * \param[in]  ctxt_pP          Running context.
 * \param[in]  rlc_pP           RLC AM protocol instance pointer.
-* \param[in]  tbs_sizeP                 Number of bytes requested by MAC for next transmission.
 * \param[in]  tx_statusP                Transmission status given by MAC on previous MAC transmission of the PDU.
 * \param[in]  enb_flagP        eNB or UE flag indication.
 * \return     The maximum number of bytes that can be served by RLC instance to MAC.
 */
-struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);
-
-/*! \fn void rlc_am_set_nb_bytes_requested_by_mac (void * const            rlc_pP,const tb_size_t         tb_sizeP)
-* \brief    Set available TBS for RLC Tx just before am_mac_data_request. Used for UE only.
-* \param[in]  rlc_pP           RLC AM protocol instance pointer.
-* \param[in]  tb_sizeP         Available Tx Transport Block size in bytes.
-*/
-void rlc_am_set_nb_bytes_requested_by_mac (void * const            rlc_pP,const tb_size_t         tb_sizeP);
+struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);
 
 /*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP,const eNB_flag_t   enb_flagP)
 * \brief    Gives PDUs to lower layer MAC.
diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c
index e481550a460..4e3fffe176e 100644
--- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c
+++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c
@@ -151,13 +151,10 @@ struct mac_status_resp
 rlc_tm_mac_status_indication (
   const protocol_ctxt_t* const  ctxt_pP,
   void * const                  rlc_pP,
-  const tb_size_t               tb_sizeP,
   struct mac_status_ind         tx_statusP)
 {
   struct mac_status_resp status_resp;
 
-  ((rlc_tm_entity_t *) rlc_pP)->rlc_pdu_size = tb_sizeP;
-
   status_resp.buffer_occupancy_in_bytes = ((rlc_tm_entity_t *) rlc_pP)->buffer_occupancy;
   status_resp.buffer_occupancy_in_pdus = status_resp.buffer_occupancy_in_bytes / ((rlc_tm_entity_t *) rlc_pP)->rlc_pdu_size;
   status_resp.rlc_info.rlc_protocol_state = ((rlc_tm_entity_t *) rlc_pP)->protocol_state;
diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h
index 1ea99887071..d2bab33b1a4 100644
--- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h
+++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h
@@ -88,11 +88,10 @@ void     rlc_tm_rx (
                   struct mac_data_ind data_indP);
 
 
-/*! \fn struct mac_status_resp rlc_tm_mac_status_indication (const protocol_ctxt_t* const  ctxt_pP, void * const rlcP, const uint16_t tbs_sizeP, struct mac_status_ind tx_statusP)
+/*! \fn struct mac_status_resp rlc_tm_mac_status_indication (const protocol_ctxt_t* const  ctxt_pP, void * const rlcP, struct mac_status_ind tx_statusP)
 * \brief    Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission.
 * \param[in]  ctxtP                     Running context.
 * \param[in]  rlcP                      RLC TM protocol instance pointer.
-* \param[in]  tbs_sizeP                 Number of bytes requested by MAC for next transmission.
 * \param[in]  tx_statusP                Transmission status given by MAC on previous MAC transmission of the PDU.
 * \return     The maximum number of bytes that can be served by RLC instance to MAC.
 */
@@ -100,7 +99,6 @@ struct mac_status_resp
 rlc_tm_mac_status_indication (
   const protocol_ctxt_t* const  ctxt_pP,
   void * const                  rlc_pP,
-  const tb_size_t               tb_sizeP,
   struct mac_status_ind         tx_statusP);
 
 
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
index c7dc11f51dc..654ddb8da7e 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
@@ -370,7 +370,7 @@ rlc_um_rx (const protocol_ctxt_t *const ctxt_pP, void *argP, struct mac_data_ind
 
 //-----------------------------------------------------------------------------
 struct mac_status_resp
-rlc_um_mac_status_indication (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP) {
+rlc_um_mac_status_indication (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP) {
   struct mac_status_resp status_resp;
   uint16_t  sdu_size = 0;
   uint16_t  sdu_remaining_size = 0;
@@ -386,7 +386,6 @@ rlc_um_mac_status_indication (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP
   if (rlc_pP) {
     status_resp.rlc_info.rlc_protocol_state      = rlc_p->protocol_state;
     rlc_um_check_timer_dar_time_out(ctxt_pP, rlc_p);
-    rlc_p->nb_bytes_requested_by_mac = tbs_sizeP;
     status_resp.buffer_occupancy_in_bytes = rlc_um_get_buffer_occupancy (rlc_p);
 
     if ((status_resp.buffer_occupancy_in_bytes > 0) && ((mb_p = list_get_head(&rlc_p->input_sdus)) != NULL)) {
@@ -416,9 +415,8 @@ rlc_um_mac_status_indication (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP
 
     if (LOG_DEBUGFLAG(DEBUG_RLC)) {
       if (( rlc_p->rb_id > 0) && (status_resp.buffer_occupancy_in_bytes > 0)) {
-        LOG_UI(RLC, PROTOCOL_RLC_UM_CTXT_FMT"MAC_STATUS_INDICATION (DATA) %d bytes requested -> %d bytes available\n",
+        LOG_UI(RLC, PROTOCOL_RLC_UM_CTXT_FMT"MAC_STATUS_INDICATION (DATA) -> %d bytes available\n",
                PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p),
-               tbs_sizeP,
                status_resp.buffer_occupancy_in_bytes);
 
         if ((tx_statusP.tx_status == MAC_TX_STATUS_SUCCESSFUL) && (tx_statusP.no_pdu)) {
@@ -441,15 +439,6 @@ rlc_um_mac_status_indication (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP
   return status_resp;
 }
 
-//-----------------------------------------------------------------------------
-void
-rlc_um_set_nb_bytes_requested_by_mac (
-  void         *rlc_pP,
-  const tb_size_t   tb_sizeP
-) {
-  ((rlc_um_entity_t *) rlc_pP)->nb_bytes_requested_by_mac = tb_sizeP;
-}
-
 //-----------------------------------------------------------------------------
 struct mac_data_req
 rlc_um_mac_data_request (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP,const eNB_flag_t  enb_flagP) {
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
index 8000196b32d..be06551dde7 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h
@@ -160,27 +160,15 @@ rlc_um_get_pdus (const protocol_ctxt_t* const ctxt_pP, void *argP);
 */
 void
 rlc_um_rx (const protocol_ctxt_t* const ctxt_pP, void *argP, struct mac_data_ind data_indP);
-/*! \fn struct mac_status_resp rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP)
+/*! \fn struct mac_status_resp rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, struct mac_status_ind tx_statusP)
 * \brief    Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission.
 * \param[in]  ctxt_pP                   Running context.
 * \param[in]  rlc_pP                    RLC UM protocol instance pointer.
-* \param[in]  tbs_sizeP                 Number of bytes requested by MAC for next transmission.
 * \param[in]  tx_statusP                Transmission status given by MAC on previous MAC transmission of the PDU.
 * \return     The maximum number of bytes that can be served by RLC instance to MAC.
 */
 struct mac_status_resp
-rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);
-
-/*! \fn void     rlc_um_set_nb_bytes_requested_by_mac (rlc_um_entity_t * const rlc_pP, const tb_size_t		tb_sizeP)
-* \brief    Set available TBS size for MAC Tx.
-* \param[in]  rlc_pP                    RLC UM protocol instance pointer.
-* \param[in]  tb_sizeP                 remaining TBS in bytes.
-*/
-void
-rlc_um_set_nb_bytes_requested_by_mac (
-  void *                                rlc_pP,
-  const tb_size_t               tb_sizeP
-);
+rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);
 
 /*! \fn struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP,const eNB_flag_t  enb_flagP)
 * \brief    Gives PDUs to lower layer MAC.
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index dfdf5271235..27ca18ed7ee 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -137,7 +137,7 @@ void (*rlc_rrc_data_ind)(
   const protocol_ctxt_t *const ctxtP,
   const rb_id_t     rb_idP,
   const sdu_size_t  sdu_sizeP,
-  const uint8_t    *const sduP);
+  const uint8_t    *const sduP)  __attribute__ ((aligned(32)));
 
 void (*rlc_rrc_data_conf)(
   const protocol_ctxt_t *const ctxtP,
@@ -250,7 +250,7 @@ logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];
    (((hash_key_t)(sESSION_ID)) << 37) | \
    (((hash_key_t)(0x0000000000000001))  << 63))
 
-hash_table_t  *rlc_coll_p;
+hash_table_t  *rlc_coll_p  __attribute__ ((aligned(32)));
 
 /*! \fn tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP)
 * \brief  Serialize a list of transport blocks coming from RLC in order to be processed by MAC.
@@ -391,7 +391,7 @@ void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t r
 * \param [in]     eNB_flagP        Flag to indicate eNB (1) or UE (0)
 * \param [in]     MBMS_flagP       Flag to indicate whether this is the MBMS service (1) or not (0)
 * \param [in]     rb_idP           Radio bearer identifier.
-* \param [in]     tb_sizeP         Available Tx TBS in bytes. For UE only.
+* \param [in]     tb_sizeP         Requested Tx TBS in bytes.
 * \param [in,out] bufferP          Memory area to fill with the bytes requested by MAC.
 * \return     A status about the processing, OK or error code.
 */
@@ -416,7 +416,7 @@ tbs_size_t            mac_rlc_data_req     (const module_id_t, const rnti_t, con
 void                  mac_rlc_data_ind     (const module_id_t, const rnti_t, const eNB_index_t,const frame_t, const  eNB_flag_t, const  MBMS_flag_t, logical_chan_id_t, char *, tb_size_t, num_tb_t,
     crc_t * );
 
-/*! \fn mac_rlc_status_resp_t mac_rlc_status_ind     (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const sub_frame_t subframeP, const  eNB_flag_t eNB_flagP, const  MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP, tb_size_t tb_sizeP)
+/*! \fn mac_rlc_status_resp_t mac_rlc_status_ind     (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const sub_frame_t subframeP, const  eNB_flag_t eNB_flagP, const  MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP)
 * \brief    Interface with MAC layer, request and set the number of bytes scheduled for transmission by the RLC instance corresponding to the radio bearer identifier.
 * \param[in]  mod_idP          Virtualized module identifier.
 * \param[in]  rntiP            UE identifier.
@@ -425,10 +425,9 @@ void                  mac_rlc_data_ind     (const module_id_t, const rnti_t, con
 * \param[in]  eNB_flagP         Flag to indicate eNB operation (1 true, 0 false)
 * \param[in]  MBMS_flagP       Flag to indicate whether this is the MBMS service (1) or not (0)
 * \param[in]  rb_idP           Radio bearer identifier.
-* \param[in]  tb_sizeP         Size of a transport block set in bytes.
 * \return     The maximum number of bytes that the RLC instance can send in the next transmission sequence.
 */
-mac_rlc_status_resp_t mac_rlc_status_ind   (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const  eNB_flag_t, const  MBMS_flag_t, logical_chan_id_t, tb_size_t
+mac_rlc_status_resp_t mac_rlc_status_ind   (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const  eNB_flag_t, const  MBMS_flag_t, logical_chan_id_t
     ,const uint32_t sourceL2Id
     ,const uint32_t destinationL2Id
                                            );
diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c
index 9cf6cb739a0..89cbe4c406c 100644
--- a/openair2/LAYER2/RLC/rlc_mac.c
+++ b/openair2/LAYER2/RLC/rlc_mac.c
@@ -191,20 +191,19 @@ tbs_size_t mac_rlc_data_req(
     case RLC_MODE_AM:
       rlc_am_mui.rrc_mui_num = 0;
 
-      if (!enb_flagP) rlc_am_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.am,tb_sizeP);
-
+      ((rlc_am_entity_t *) &rlc_union_p->rlc.am)->nb_bytes_requested_by_mac = tb_sizeP;
       data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am,enb_flagP);
       ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data);
       break;
 
     case RLC_MODE_UM:
-      if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP);
-
+      ((rlc_um_entity_t *) &rlc_union_p->rlc.um)->nb_bytes_requested_by_mac = tb_sizeP;
       data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um,enb_flagP);
       ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data);
       break;
 
     case RLC_MODE_TM:
+      ((rlc_tm_entity_t *) &rlc_union_p->rlc.tm)->rlc_pdu_size = tb_sizeP;
       data_request = rlc_tm_mac_data_request(&ctxt, &rlc_union_p->rlc.tm);
       ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data);
       break;
@@ -317,7 +316,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
   const eNB_flag_t        enb_flagP,
   const MBMS_flag_t       MBMS_flagP,
   const logical_chan_id_t channel_idP,
-  const tb_size_t         tb_sizeP,
   const uint32_t sourceL2Id,
   const uint32_t destinationL2Id
 ) {
@@ -370,7 +368,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
       break;
 
     case RLC_MODE_AM:
-      status_resp = rlc_am_mac_status_indication(&ctxt, &rlc_union_p->rlc.am, tb_sizeP, tx_status,enb_flagP);
+      status_resp = rlc_am_mac_status_indication(&ctxt, &rlc_union_p->rlc.am, tx_status,enb_flagP);
       mac_rlc_status_resp.bytes_in_buffer                 = status_resp.buffer_occupancy_in_bytes;
       mac_rlc_status_resp.head_sdu_creation_time          = status_resp.head_sdu_creation_time;
       mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send;
@@ -379,7 +377,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
       break;
 
     case RLC_MODE_UM:
-      status_resp = rlc_um_mac_status_indication(&ctxt, &rlc_union_p->rlc.um, tb_sizeP, tx_status, enb_flagP);
+      status_resp = rlc_um_mac_status_indication(&ctxt, &rlc_union_p->rlc.um, tx_status, enb_flagP);
       mac_rlc_status_resp.bytes_in_buffer                 = status_resp.buffer_occupancy_in_bytes;
       mac_rlc_status_resp.pdus_in_buffer                  = status_resp.buffer_occupancy_in_pdus;
       mac_rlc_status_resp.head_sdu_creation_time          = status_resp.head_sdu_creation_time;
@@ -389,7 +387,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
       break;
 
     case RLC_MODE_TM:
-      status_resp = rlc_tm_mac_status_indication(&ctxt, &rlc_union_p->rlc.tm, tb_sizeP, tx_status);
+      status_resp = rlc_tm_mac_status_indication(&ctxt, &rlc_union_p->rlc.tm, tx_status);
       mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes;
       mac_rlc_status_resp.pdus_in_buffer  = status_resp.buffer_occupancy_in_pdus;
       // return mac_rlc_status_resp;
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 88bde65107f..ff0d446e3f0 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -107,7 +107,6 @@ tbs_size_t mac_rlc_data_req(
   int ret;
   nr_rlc_ue_t *ue;
   nr_rlc_entity_t *rb;
-  int is_enb;
   int maxsize;
 
   nr_rlc_manager_lock(nr_rlc_ue_manager);
@@ -121,12 +120,7 @@ tbs_size_t mac_rlc_data_req(
 
   if (rb != NULL) {
     rb->set_time(rb, nr_rlc_current_time);
-    /* UE does not seem to use saved_status_ind_tb_size */
-    is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager);
-    if (is_enb)
-      maxsize = ue->saved_status_ind_tb_size[channel_idP - 1];
-    else
-      maxsize = tb_sizeP;
+    maxsize = tb_sizeP;
     ret = rb->generate_pdu(rb, buffer_pP, maxsize);
   } else {
     LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__);
@@ -152,7 +146,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
   const eNB_flag_t        enb_flagP,
   const MBMS_flag_t       MBMS_flagP,
   const logical_chan_id_t channel_idP,
-  const tb_size_t         tb_sizeP,
   const uint32_t sourceL2Id,
   const uint32_t destinationL2Id
   )
@@ -189,7 +182,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
     ret.bytes_in_buffer = buf_stat.status_size
                         + buf_stat.retx_size
                         + buf_stat.tx_size;
-    ue->saved_status_ind_tb_size[channel_idP - 1] = tb_sizeP;
   } else {
     ret.bytes_in_buffer = 0;
   }
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
index 97da28cdce2..464cf3d083d 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
@@ -28,10 +28,6 @@ typedef void nr_rlc_ue_manager_t;
 
 typedef struct nr_rlc_ue_t {
   int rnti;
-  /* due to openair calling status_ind/data_req, we need to keep this.
-   * To be considered 'hackish'.
-   */
-  int saved_status_ind_tb_size[2+5];
   nr_rlc_entity_t *srb[2];
   nr_rlc_entity_t *drb[5];
 } nr_rlc_ue_t;
diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index 32c4d9788cf..bbdc55e0366 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -91,12 +91,12 @@ int dump_eNB_l2_stats(char *buffer, int length) {
     number_of_cards=NB_eNB_INST;
 #endif
     eNB_MAC_INST *eNB;
-    UE_list_t *UE_list;
+    UE_info_t *UE_info;
 
     for (eNB_id=0; eNB_id<number_of_cards; eNB_id++) {
         /* reset the values */
         eNB = RC.mac[eNB_id];
-        UE_list = &eNB->UE_list;
+        UE_info = &eNB->UE_info;
 
         for (CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) {
             eNB->eNB_stats[CC_id].dlsch_bitrate= 0;
@@ -141,76 +141,76 @@ int dump_eNB_l2_stats(char *buffer, int length) {
 
         len += sprintf(&buffer[len],"\n");
 
-        for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
-            for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
-                CC_id=UE_list->ordered_CCids[i][UE_id];
-                UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10));
-                UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10));
-                UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+=  UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes;
-                UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10));
-                UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS*8)/((eNB->frame + 1)*10));
-                UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx*8)/((eNB->frame + 1)*10));
+        for (UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) {
+            for (i=0; i<UE_info->numactiveCCs[UE_id]; i++) {
+                CC_id=UE_info->ordered_CCids[i][UE_id];
+                UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_info->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10));
+                UE_info->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10));
+                UE_info->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+=  UE_info->eNB_UE_stats[CC_id][UE_id].overhead_bytes;
+                UE_info->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_info->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10));
+                UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate=((UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS*8)/((eNB->frame + 1)*10));
+                UE_info->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate= ((UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx*8)/((eNB->frame + 1)*10));
                 len += sprintf(&buffer[len],"[MAC] UE %d (DLSCH),status %s, RNTI %x : CQI %d, MCS1 %d, MCS2 %d, RB (tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n",
                                UE_id,
-                               map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status),
-                               UE_list->eNB_UE_stats[CC_id][UE_id].crnti,
-                               UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],
-                               UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx
+                               map_int_to_str(rrc_status_names, UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status),
+                               UE_info->eNB_UE_stats[CC_id][UE_id].crnti,
+                               UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],
+                               UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used_retx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ncce_used,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ncce_used_retx
                               );
                 len += sprintf(&buffer[len],
                                "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes "
                                "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead "
                                "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64")\n",
-                               UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].TBS,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes
+                               UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].TBS,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].overhead_bytes,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes
                               );
                 len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : snr (%d,  target %d), MCS (pre %d, post %d), RB (rx %d, retx %d, total %d), Current TBS %d \n",
                                UE_id,
-                               map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status),
-                               UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].crnti,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].snr,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].target_snr,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_rx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS
+                               map_int_to_str(rrc_status_names, UE_info->eNB_UE_stats[CC_id][UE_id].rrc_status),
+                               UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].crnti,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].snr,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].target_snr,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used_rx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS
                               );
                 len += sprintf(&buffer[len],
                                "[MAC] ULSCH bitrate (TTI %d, avg %d), received bytes (total %"PRIu64"),"
                                "Total received PDU %d, Total errors %d\n",
-                               UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx,
-                               UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx);
-                len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_list->UE_template[CC_id][UE_id].phr_info);
+                               UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx,
+                               UE_info->eNB_UE_stats[CC_id][UE_id].num_errors_rx);
+                len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_info->UE_template[CC_id][UE_id].phr_info);
                 len+= sprintf(&buffer[len],"[MAC] Estimated size LCGID[0][1][2][3] = %u %u %u %u\n",
-                              UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0],
-                              UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1],
-                              UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2],
-                              UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3]
+                              UE_info->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0],
+                              UE_info->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1],
+                              UE_info->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2],
+                              UE_info->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3]
                              );
             }
 
             PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,
                                            eNB_id,
                                            ENB_FLAG_YES,
-                                           UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti,
+                                           UE_info->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti,
                                            eNB->frame,
                                            eNB->subframe,
                                            eNB_id);
@@ -509,7 +509,7 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) {
             for(i=1; i<=NB_CNX_CH; i++) {
                 if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) {
                     len+=sprintf(&buffer[len],"\nMR index %u: DL SINR (feedback) %d dB, CQI: %s\n\n",
-                                 i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0],
+                                 i,//CH_rrc_inst[Mod_id].Info.UE_info[i].L2_id[0],
                                  CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr,
                                  print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi));
                     len+=sprintf(&buffer[len],
diff --git a/openair2/M2AP/m2ap_MCE_handler.h b/openair2/M2AP/m2ap_MCE_handler.h
index e9faae8f5d9..68cab5c8ac9 100644
--- a/openair2/M2AP/m2ap_MCE_handler.h
+++ b/openair2/M2AP/m2ap_MCE_handler.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M2AP_MCE_HANDLERS_H_
-#define M2AP_MCE_HANDLERS_H_
+#ifndef __M2AP_MCE_HANDLERS__H__
+#define __M2AP_MCE_HANDLERS__H__
 
 #include "m2ap_MCE_defs.h"
 
@@ -40,4 +40,4 @@ int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre
                             //const uint8_t * const data, const uint32_t data_length);
 
 
-#endif /* M2AP_MCE_HANDLERS_H_ */
+#endif /* __M2AP_MCE_HANDLERS__H__ */
diff --git a/openair2/M2AP/m2ap_MCE_management_procedures.h b/openair2/M2AP/m2ap_MCE_management_procedures.h
index 9e13e723c96..4e8997dbc51 100644
--- a/openair2/M2AP/m2ap_MCE_management_procedures.h
+++ b/openair2/M2AP/m2ap_MCE_management_procedures.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M2AP_MCE_MANAGEMENT_PROCEDURES_H_
-#define M2AP_MCE_MANAGEMENT_PROCEDURES_H
+#ifndef __M2AP_MCE_MANAGEMENT_PROCEDURES__H__
+#define __M2AP_MCE_MANAGEMENT_PROCEDURES__H__
 
 void m2ap_MCE_prepare_internal_data(void);
 
@@ -51,4 +51,4 @@ struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
                                      int32_t assoc_id,
                                      uint16_t cnx_id);
 
-#endif /* M2AP_MCE_MANAGEMENT_PROCEDURES_H_ */
+#endif /* __M2AP_MCE_MANAGEMENT_PROCEDURES__H__ */
diff --git a/openair2/M2AP/m2ap_eNB_generate_messages.h b/openair2/M2AP/m2ap_eNB_generate_messages.h
index 49247405f78..793f7f18cf1 100644
--- a/openair2/M2AP/m2ap_eNB_generate_messages.h
+++ b/openair2/M2AP/m2ap_eNB_generate_messages.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
-#define M2AP_ENB_GENERATE_MESSAGES_H_
+#ifndef __M2AP_ENB_GENERATE_MESSAGES__H__
+#define __M2AP_ENB_GENERATE_MESSAGES__H__
 
 #include "m2ap_eNB_defs.h"
 #include "m2ap_common.h"
@@ -60,4 +60,4 @@ int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
 //                                          int m2_ue_id,
 //                                          m2ap_handover_cancel_cause_t cause);
 
-#endif /*  M2AP_ENB_GENERATE_MESSAGES_H_ */
+#endif /*  __M2AP_ENB_GENERATE_MESSAGES__H__ */
diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.h b/openair2/M2AP/m2ap_eNB_management_procedures.h
index fbc49d01698..2b1dc4a44bc 100644
--- a/openair2/M2AP/m2ap_eNB_management_procedures.h
+++ b/openair2/M2AP/m2ap_eNB_management_procedures.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M2AP_ENB_MANAGEMENT_PROCEDURES_H_
-#define M2AP_ENB_MANAGEMENT_PROCEDURES_H
+#ifndef __M2AP_ENB_MANAGEMENT_PROCEDURES__H__
+#define __M2AP_ENB_MANAGEMENT_PROCEDURES__H__
 
 void m2ap_eNB_prepare_internal_data(void);
 
@@ -51,4 +51,4 @@ struct m2ap_eNB_data_s *m2ap_get_eNB(m2ap_eNB_instance_t *instance_p,
                                      int32_t assoc_id,
                                      uint16_t cnx_id);
 
-#endif /* M2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
+#endif /* __M2AP_ENB_MANAGEMENT_PROCEDURES__H__ */
diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c
index 32dfa5cc42c..6f7454c321a 100644
--- a/openair2/MCE_APP/mce_app.c
+++ b/openair2/MCE_APP/mce_app.c
@@ -343,7 +343,9 @@ void *MCE_app_task(void *args_p) {
 
   /* Try to register each MCE */
   // This assumes that node_type of all RRC instances is the same
-  if (EPC_MODE_ENABLED) {
+  if ( EPC_MODE_ENABLED && RC.rrc == NULL )
+	  LOG_E(RRC, "inconsistent global variables\n");
+  if (EPC_MODE_ENABLED && RC.rrc ) {
     register_mce_pending = MCE_app_register(RC.rrc[0]->node_type, mce_id_start, mce_id_end);
   }
 
diff --git a/openair2/NETWORK_DRIVER/LITE/proto_extern.h b/openair2/NETWORK_DRIVER/LITE/proto_extern.h
index f07083921f3..d4289ca1f2d 100644
--- a/openair2/NETWORK_DRIVER/LITE/proto_extern.h
+++ b/openair2/NETWORK_DRIVER/LITE/proto_extern.h
@@ -30,8 +30,8 @@
 
 ***************************************************************************/
 
-#ifndef _NAS_PROTO_H
-#define _NAS_PROTO_H
+#ifndef __NETWORK_DRIVER_LITE_PROTO_EXTERN__H__
+#define __NETWORK_DRIVER_LITE_PROTO_EXTERN__H__
 
 #include <linux/if_arp.h>
 #include <linux/types.h>
diff --git a/openair2/NETWORK_DRIVER/MESH/proto_extern.h b/openair2/NETWORK_DRIVER/MESH/proto_extern.h
index 2eae034257f..ac92b2f8bdc 100644
--- a/openair2/NETWORK_DRIVER/MESH/proto_extern.h
+++ b/openair2/NETWORK_DRIVER/MESH/proto_extern.h
@@ -29,8 +29,8 @@
 
 ***************************************************************************/
 
-#ifndef _NAS_PROTO_H
-#define _NAS_PROTO_H
+#ifndef __NETWORK_DRIVER_MESH_PROTO_EXTERN__H__
+#define __NETWORK_DRIVER_MESH_PROTO_EXTERN__H__
 
 #include <linux/if_arp.h>
 #include <linux/types.h>
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 91c75ac67fd..4dacef3dbb8 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -54,34 +54,32 @@ extern uint16_t sf_ahead;
 extern uint16_t sl_ahead;
 
 void handle_nr_rach(NR_UL_IND_t *UL_info) {
-  if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) {
-    AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
-    UL_info->rach_ind.rach_indication_body.number_of_preambles=0;
-    LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->slot, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf));
-    /*
-    initiate_ra_proc(UL_info->module_id,
-
-    		         UL_info->CC_id,
-					 NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
-					 NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf),
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble,
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti
-#if (NR_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) || (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-//#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                    ,0
-#endif
+  if (UL_info->rach_ind.number_of_pdus>0) {
+    AssertFatal(UL_info->rach_ind.number_of_pdus==1,"More than 1 RACH pdu not supported\n");
+    UL_info->rach_ind.number_of_pdus=0;
+    LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
 
-         );
-    */
-  }
+    if (UL_info->rach_ind.pdu_list[0].num_preamble>0)
+    AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1,
+		"More than 1 preamble not supported\n");
 
+    /*nr_initiate_ra_proc(UL_info->module_id,
+                        UL_info->CC_id,
+                        UL_info->rach_ind.sfn,
+                        UL_info->rach_ind.slot,
+                        UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index,
+                        UL_info->rach_ind.pdu_list[0].freq_index,
+                        UL_info->rach_ind.pdu_list[0].symbol_index,
+                        UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);*/
+
+  }
 }
 
+
 void handle_nr_sr(NR_UL_IND_t *UL_info) {
 
 
-  if (nfapi_mode == 1)  // PNF
+ /* if (nfapi_mode == 1)  // PNF
   {
     if (UL_info->sr_ind.sr_indication_body.number_of_srs>0)
     {
@@ -91,20 +89,20 @@ void handle_nr_sr(NR_UL_IND_t *UL_info) {
   else
   {
 
-    /*
+    
     for (int i=0;i<UL_info->sr_ind.sr_indication_body.number_of_srs;i++)
       SR_indication(UL_info->module_id,
           UL_info->CC_id,
           UL_info->frame,
           UL_info->slot,
           UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti,
-          UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi);*/
+          UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi);
 
 
 
   }
 
-  UL_info->sr_ind.sr_indication_body.number_of_srs=0;
+  UL_info->sr_ind.sr_indication_body.number_of_srs=0;*/
 }
 
 void handle_nr_cqi(NR_UL_IND_t *UL_info) {
@@ -119,103 +117,99 @@ void handle_nr_cqi(NR_UL_IND_t *UL_info) {
           &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9,
           UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu,
           &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information);
-    */
-    UL_info->cqi_ind.number_of_cqis=0;
+    
+    UL_info->cqi_ind.number_of_cqis=0;*/
 
 }
 
 void handle_nr_harq(NR_UL_IND_t *UL_info) {
-  if (nfapi_mode == 1 && UL_info->harq_ind.harq_indication_body.number_of_harqs>0) { // PNF
+ /*  if (nfapi_mode == 1 && UL_info->harq_ind.harq_indication_body.number_of_harqs>0) { // PNF
     //LOG_D(PHY, "UL_info->harq_ind.harq_indication_body.number_of_harqs:%d Send to VNF\n", UL_info->harq_ind.harq_indication_body.number_of_harqs);
-    /*    int retval = oai_nfapi_harq_indication(&UL_info->harq_ind);
+       int retval = oai_nfapi_harq_indication(&UL_info->harq_ind);
 
     if (retval!=0) {
       LOG_E(PHY, "Failed to encode NFAPI HARQ_IND retval:%d\n", retval);
     }
-    */
+    
     UL_info->harq_ind.harq_indication_body.number_of_harqs = 0;
   }
   else
   {
-    /*
+    
     for (int i=0;i<UL_info->harq_ind.harq_indication_body.number_of_harqs;i++)
       harq_indication(UL_info->module_id,
           UL_info->CC_id,
           NFAPI_SFNSF2SFN(UL_info->harq_ind.sfn_sf),
           NFAPI_SFNSF2SF(UL_info->harq_ind.sfn_sf),
           &UL_info->harq_ind.harq_indication_body.harq_pdu_list[i]);
-    */
+    
     UL_info->harq_ind.harq_indication_body.number_of_harqs=0;
-  }
+  }*/
 }
 
 void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
   if(nfapi_mode == 1) {
-    if (UL_info->crc_ind.crc_indication_body.number_of_crcs>0) {
+    if (UL_info->crc_ind.number_crcs>0) {
       //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
       //      oai_nfapi_crc_indication(&UL_info->crc_ind);
 
-      UL_info->crc_ind.crc_indication_body.number_of_crcs = 0;
+      UL_info->crc_ind.number_crcs = 0;
     }
 
-    if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0) {
+    if (UL_info->rx_ind.number_of_pdus>0) {
       //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
       //      oai_nfapi_rx_ind(&UL_info->rx_ind);
-      UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
+      UL_info->rx_ind.number_of_pdus = 0;
     }
   } else {
 
-    if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) {
-      for (int i=0; i<UL_info->rx_ind.rx_indication_body.number_of_pdus; i++) {
-        for (int j=0; j<UL_info->crc_ind.crc_indication_body.number_of_crcs; j++) {
+    if (UL_info->rx_ind.number_of_pdus>0 && UL_info->crc_ind.number_crcs>0) {
+      for (int i=0; i<UL_info->rx_ind.number_of_pdus; i++) {
+        for (int j=0; j<UL_info->crc_ind.number_crcs; j++) {
           // find crc_indication j corresponding rx_indication i
           LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j,
-                UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti);
+                UL_info->crc_ind.crc_list[j].rnti, i, UL_info->rx_ind.pdu_list[i].rnti);
 
-          if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti ==
-              UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) {
-            LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag);
+          if (UL_info->crc_ind.crc_list[j].rnti ==
+              UL_info->rx_ind.pdu_list[i].rnti) {
+            LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status);
 
-            if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication
+            if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication
               LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
 
               nr_rx_sdu(UL_info->module_id,
                         UL_info->CC_id,
-                        NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame,
-                        NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
+                        UL_info->rx_ind.sfn, //UL_info->frame,
+                        UL_info->rx_ind.slot, //UL_info->slot,
+                        UL_info->rx_ind.pdu_list[i].rnti,
                         (uint8_t *)NULL,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
+                        UL_info->rx_ind.pdu_list[i].pdu_length,
+                        UL_info->rx_ind.pdu_list[i].timing_advance,
+                        UL_info->rx_ind.pdu_list[i].ul_cqi);
             } else {
               LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot);
               nr_rx_sdu(UL_info->module_id,
                         UL_info->CC_id,
-                        NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame,
-                        NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->slot,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
-                        UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
+                        UL_info->rx_ind.sfn, //UL_info->frame,
+                        UL_info->rx_ind.slot, //UL_info->slot,
+                        UL_info->rx_ind.pdu_list[i].rnti,
+                        UL_info->rx_ind.pdu_list[i].pdu,
+                        UL_info->rx_ind.pdu_list[i].pdu_length,
+                        UL_info->rx_ind.pdu_list[i].timing_advance,
+                        UL_info->rx_ind.pdu_list[i].ul_cqi);
             }
-            //printf("rx_indication_rel8.timing_advance %d\n", UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance);
             break;
-          } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti ==
-
-          //    UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti)
-        } //    for (j=0;j<UL_info->crc_ind.crc_indication_body.number_of_crcs;j++)
+          }
+        } //    for (j=0;j<UL_info->crc_ind.number_crcs;j++)
       } //   for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
 
-      UL_info->crc_ind.crc_indication_body.number_of_crcs=0;
-      UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
-    } // UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->slot && UL_info->crc_ind.crc_indication_body.number_of_crcs>0
-    else if (UL_info->rx_ind.rx_indication_body.number_of_pdus!=0 || UL_info->crc_ind.crc_indication_body.number_of_crcs!=0) {
-      LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SF:%05d) crc_ind:%d(SFN/SF:%05d) UL_info(SFN/SF):%04d%d\n",
-            UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf),
-            UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf),
-            UL_info->frame, UL_info->slot);
+      UL_info->crc_ind.number_crcs=0;
+      UL_info->rx_ind.number_of_pdus = 0;
+    }
+    else if (UL_info->rx_ind.number_of_pdus!=0 || UL_info->crc_ind.number_crcs!=0) {
+      LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
+            UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot,
+            UL_info->crc_ind.number_crcs, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
     }
   }
 }
@@ -230,11 +224,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
   NR_Sched_Rsp_t   *sched_info = &Sched_INFO[module_id][CC_id];
   NR_IF_Module_t   *ifi        = if_inst[module_id];
   gNB_MAC_INST     *mac        = RC.nrmac[module_id];
-  LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n",
+  LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d crcs:%d]\n",
         UL_info->frame,UL_info->slot,
         module_id,CC_id,
-        UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis,
-        UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs);
+        UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
 
   if (nfapi_mode != 1) {
     if (ifi->CC_mask==0) {
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h
index 14355781d01..d523d6e0f0d 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h
@@ -61,29 +61,20 @@ typedef struct {
   /// slot
   slot_t slot;
 
-  /// harq indication list
-  nfapi_harq_indication_t harq_ind;
-
   /// crc indication list
-  nfapi_crc_indication_t crc_ind;
-
-  /// SR indication list
-  nfapi_sr_indication_t sr_ind;
-
-  /// CQI indication list
-  nfapi_cqi_indication_body_t cqi_ind;
+  nfapi_nr_crc_indication_t crc_ind;
 
   /// RACH indication list
-  nfapi_rach_indication_t rach_ind;
-
-  /// RACH indication list for BR UEs
-  nfapi_rach_indication_t rach_ind_br;
+  nfapi_nr_rach_indication_t rach_ind;
 
   /// SRS indication list
-  nfapi_srs_indication_body_t srs_ind;
+  nfapi_nr_srs_indication_t srs_ind;
 
   /// RX indication
-  nfapi_rx_indication_t rx_ind;
+  nfapi_nr_rx_data_indication_t rx_ind;
+
+  /// UCI indication
+  nfapi_nr_uci_indication_t uci_ind;
 
 } NR_UL_IND_t;
 
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index b5cda35193f..d98c603d784 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -685,7 +685,7 @@ static void dump_dl(Sched_Rsp_t *d) {
 /* debug utility functions end                                              */
 /****************************************************************************/
 
-void UL_indication(UL_IND_t *UL_info) {
+void UL_indication(UL_IND_t *UL_info, L1_rxtx_proc_t *proc) {
   AssertFatal(UL_info!=NULL,"UL_INFO is null\n");
 #ifdef DUMP_FAPI
   dump_ul(UL_info);
@@ -767,7 +767,7 @@ void UL_indication(UL_IND_t *UL_info) {
                     "schedule_response is null (mod %d, cc %d)\n",
                     module_id,
                     CC_id);
-        ifi->schedule_response(sched_info);
+        ifi->schedule_response(sched_info, proc );
       }
 
       LOG_D(PHY,"Schedule_response: SFN_SF:%d%d dl_pdus:%d\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu);
diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h
index f2602220970..42a44597323 100644
--- a/openair2/PHY_INTERFACE/IF_Module.h
+++ b/openair2/PHY_INTERFACE/IF_Module.h
@@ -34,10 +34,12 @@
 
 
 #include <stdint.h>
+#include <sched.h>
 //#include "openair1/PHY/LTE_TRANSPORT/transport_eNB.h"
 #include "nfapi_interface.h"
 #include "platform_constants.h"
 #include "platform_types.h"
+#include <common/utils/threadPool/thread-pool.h>
 
 #define MAX_NUM_DL_PDU 100
 #define MAX_NUM_UL_PDU 100
@@ -130,16 +132,69 @@ typedef struct {
 } Sched_Rsp_t;
 
 typedef struct {
-  uint8_t Mod_id;
-  int CC_id;
-  nfapi_config_request_t *cfg;
-} PHY_Config_t;
-
-typedef struct IF_Module_s {
-  //define the function pointer
-  void (*UL_indication)(UL_IND_t *UL_INFO);
-  void (*schedule_response)(Sched_Rsp_t *Sched_INFO);
-  void (*PHY_config_req)(PHY_Config_t *config_INFO);
+    uint8_t Mod_id;
+    int CC_id;
+    nfapi_config_request_t *cfg;
+}PHY_Config_t;
+#include <targets/ARCH/COMMON/common_lib.h>
+/// Context data structure for RX/TX portion of subframe processing
+typedef struct {
+  /// Component Carrier index
+  uint8_t              CC_id;
+  /// timestamp transmitted to HW
+  openair0_timestamp timestamp_tx;
+  openair0_timestamp timestamp_rx;
+  /// subframe to act upon for transmission
+  int subframe_tx;
+  /// subframe to act upon for reception
+  int subframe_rx;
+  /// frame to act upon for transmission
+  int frame_tx;
+  /// frame to act upon for reception
+  int frame_rx;
+  int frame_prach;
+  int subframe_prach;
+  int frame_prach_br;
+  int subframe_prach_br;
+  /// \brief Instance count for RXn-TXnp4 processing thread.
+  /// \internal This variable is protected by \ref mutex_rxtx.
+  int instance_cnt;
+  /// pthread structure for RXn-TXnp4 processing thread
+  pthread_t pthread;
+  /// pthread attributes for RXn-TXnp4 processing thread
+  pthread_attr_t attr;
+  /// condition variable for tx processing thread
+  pthread_cond_t cond;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t mutex;
+  /// scheduling parameters for RXn-TXnp4 thread
+  struct sched_param sched_param_rxtx;
+
+  /// \internal This variable is protected by \ref mutex_RUs.
+  int instance_cnt_RUs;
+  /// condition variable for tx processing thread
+  pthread_cond_t cond_RUs;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t mutex_RUs;
+  tpool_t *threadPool;
+  int nbEncode;
+  int nbDecode;
+  notifiedFIFO_t *respEncode;
+  notifiedFIFO_t *respDecode;
+    pthread_mutex_t mutex_emulateRF;
+  int instance_cnt_emulateRF;
+  pthread_t pthread_emulateRF;
+  pthread_attr_t attr_emulateRF;
+  pthread_cond_t cond_emulateRF;
+  int first_rx;
+} L1_rxtx_proc_t;
+
+typedef struct IF_Module_s{
+//define the function pointer
+  void (*UL_indication)(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
+  void (*schedule_response)(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
+  void (*PHY_config_req)(PHY_Config_t* config_INFO);
+
   void (*PHY_config_update_sib2_req)(PHY_Config_t* config_INFO);
   void (*PHY_config_update_sib13_req)(PHY_Config_t* config_INFO);
   uint32_t CC_mask;
@@ -165,7 +220,7 @@ void IF_Module_kill(int Mod_id);
 
 /*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler)
  */
-void UL_indication(UL_IND_t *UL_INFO);
+void UL_indication(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
 
 /*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
 void Schedule_Response(Sched_Rsp_t *Sched_INFO);
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index bf2bbf74295..41fb3ddc3a7 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -708,200 +708,182 @@ int tx_req_UE_MAC(nfapi_tx_request_t *req) {
   return 0;
 }
 
-int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) {
-  int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
-  int sf = NFAPI_SFNSF2SF(req->sfn_sf);
+void dl_config_req_UE_MAC_dci(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *dci,
+                              nfapi_dl_config_request_pdu_t *dlsch,
+                              int num_ue) {
+  DevAssert(dci->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE);
+  DevAssert(dlsch->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE);
+
+  const rnti_t rnti = dci->dci_dl_pdu.dci_dl_pdu_rel8.rnti;
+  const int rnti_type = dci->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type;
+  if (rnti != dlsch->dlsch_pdu.dlsch_pdu_rel8.rnti) {
+    LOG_E(MAC,
+          "%s(): sfn/sf %d.%d DLSCH PDU RNTI %x does not match DCI RNTI %x\n",
+          __func__, sfn, sf, rnti, dlsch->dlsch_pdu.dlsch_pdu_rel8.rnti);
+    return;
+  }
 
-  nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
-
-  for (int i = 0; i < req->dl_config_request_body.number_pdu; i++) {
-    if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) {
-      const rnti_t rnti = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti;
-      const int rnti_type = dl_config_pdu_list[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type;
-      /* We assume the DCI DL PDU is followed by the DLSCH (the standard is
-       * more free), so advance by one more and directly process the
-       * following DLSCH PDU */
-      i++;
-      AssertFatal(i < req->dl_config_request_body.number_pdu,
-                  "Need PDU following DCI at index %d, but not found\n",
-                  i);
-      nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp = &dl_config_pdu_list[i];
-      if (dl_config_pdu_tmp->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
-        LOG_E(MAC, "expected DLSCH PDU at index %d\n", i);
-        continue;
-      }
-      if (rnti != dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) {
-        LOG_I(MAC,
-              "%s(): sfn/sf %d DLSCH PDU RNTI %x does not match DCI RNTI %x\n",
-              __func__,
-              NFAPI_SFNSF2DEC(req->sfn_sf),
-              rnti,
-              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti);
-        continue;
-      }
-      const int pdu_index = dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index;
-      if (pdu_index < 0 && pdu_index >= tx_req_num_elems) {
-        LOG_E(MAC,
-              "dl_config_req_UE_MAC 2: Problem with receiving data: "
-              "sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d\n",
-              NFAPI_SFNSF2DEC(req->sfn_sf),
-              i,
-              dl_config_pdu_list[i].pdu_size,
-              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
-        continue;
-      }
-      if (rnti_type == 1) {
-        // C-RNTI (Normal DLSCH case)
-        if (UE_mac_inst[Mod_id].crnti != rnti) {
-          LOG_D(MAC,
-                "sfn/sf %d/%d DCI not for UE %d/RNTI %x but for RNTI %x, "
-                "skipping\n",
-                sfn, sf, Mod_id, UE_mac_inst[Mod_id].crnti, rnti);
-          continue;
-        }
+  const int pdu_index = dlsch->dlsch_pdu.dlsch_pdu_rel8.pdu_index;
+  if (pdu_index < 0 || pdu_index >= tx_req_num_elems) {
+    LOG_E(MAC,
+          "%s(): Problem with receiving data: "
+          "sfn/sf:%d.%d PDU size:%d, TX_PDU index: %d\n",
+          __func__,
+          sfn, sf, dci->pdu_size, dlsch->dlsch_pdu.dlsch_pdu_rel8.pdu_index);
+    return;
+  }
 
+  if (rnti_type == 1) { // C-RNTI (Normal DLSCH case)
+    for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+      if (UE_mac_inst[ue_id].crnti == rnti) {
         LOG_D(MAC,
-              "%s() Received data: sfn/sf:%d PDU[%d] "
+              "%s() Received data: sfn/sf:%d.%d "
               "size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n",
               __func__,
-              NFAPI_SFNSF2DEC(req->sfn_sf),
-              i,
-              dl_config_pdu_list[i].pdu_size,
-              dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index,
+              sfn, sf, dci->pdu_size,
+              dlsch->dlsch_pdu.dlsch_pdu_rel8.pdu_index,
               tx_req_num_elems);
-        ue_send_sdu(Mod_id, 0, sfn, sf,
+        ue_send_sdu(ue_id, 0, sfn, sf,
             tx_request_pdu_list[pdu_index].segments[0].segment_data,
             tx_request_pdu_list[pdu_index].segments[0].segment_length,
             0);
-      } else if (rnti_type == 2) {
-        if (rnti == 0xFFFF) { /* SI-RNTI */
-          if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED) {
-            /* this check is in the code before refactoring, but I don't know
-             * why. Leave it in here for the moment */
-            continue;
-          }
-
-          ue_decode_si(Mod_id, 0, sfn, 0,
+        return;
+      }
+    }
+  } else if (rnti_type == 2) {
+    if (rnti == 0xFFFF) { /* SI-RNTI */
+      for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+        if (UE_mac_inst[ue_id].UE_mode[0] == NOT_SYNCHED)
+          continue;
+
+        ue_decode_si(ue_id, 0, sfn, 0,
+            tx_request_pdu_list[pdu_index].segments[0].segment_data,
+            tx_request_pdu_list[pdu_index].segments[0].segment_length);
+      }
+    } else if (rnti == 0xFFFE) { /* PI-RNTI */
+      for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+        LOG_I(MAC, "%s() Received paging message: sfn/sf:%d.%d\n",
+              __func__, sfn, sf);
+        ue_decode_p(ue_id, 0, sfn, 0,
+                    tx_request_pdu_list[pdu_index].segments[0].segment_data,
+                    tx_request_pdu_list[pdu_index].segments[0].segment_length);
+      }
+    } else if (rnti == 0x0002) { /* RA-RNTI */
+      for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+        if (UE_mac_inst[ue_id].UE_mode[0] != RA_RESPONSE) {
+          LOG_D(MAC, "UE %d not awaiting RAR, is in mode %d\n",
+                ue_id, UE_mac_inst[ue_id].UE_mode[0]);
+          continue;
+        }
+        // RNTI parameter not actually used. Provided only to comply with
+        // existing function definition.  Not sure about parameters to fill
+        // the preamble index.
+        const rnti_t ra_rnti = UE_mac_inst[ue_id].RA_prach_resources.ra_RNTI;
+        DevAssert(ra_rnti == 0x0002);
+        if (UE_mac_inst[ue_id].UE_mode[0] != PUSCH
+            && UE_mac_inst[ue_id].RA_prach_resources.Msg3 != NULL
+            && ra_rnti == dlsch->dlsch_pdu.dlsch_pdu_rel8.rnti) {
+          LOG_E(MAC,
+                "%s(): Received RAR, PreambleIndex: %d\n",
+                __func__, UE_mac_inst[ue_id].RA_prach_resources.ra_PreambleIndex);
+          ue_process_rar(ue_id, 0, sfn,
+              ra_rnti, //RA-RNTI
               tx_request_pdu_list[pdu_index].segments[0].segment_data,
-              tx_request_pdu_list[pdu_index].segments[0].segment_length);
-        } else if (rnti == 0xFFFE) { /* PI-RNTI */
-          LOG_I(MAC, "%s() Received paging message: sfn/sf:%d PDU[%d]\n",
-                __func__, NFAPI_SFNSF2DEC(req->sfn_sf), i);
-          ue_decode_p(Mod_id, 0, sfn, 0,
-                      tx_request_pdu_list[pdu_index].segments[0].segment_data,
-                      tx_request_pdu_list[pdu_index].segments[0].segment_length);
-        } else if (rnti == 0x0002) { /* RA-RNTI */
-          LOG_E(MAC, "%s(): Received RAR?\n", __func__);
-          // RNTI parameter not actually used. Provided only to comply with
-          // existing function definition.  Not sure about parameters to fill
-          // the preamble index.
-          const rnti_t ra_rnti = UE_mac_inst[Mod_id].RA_prach_resources.ra_RNTI;
-          DevAssert(ra_rnti == 0x0002);
-          if (UE_mac_inst[Mod_id].UE_mode[0] != PUSCH
-              && UE_mac_inst[Mod_id].RA_prach_resources.Msg3 != NULL
-              && ra_rnti == dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti) {
-            LOG_E(MAC,
-                  "dl_config_req_UE_MAC 5 Received RAR, PreambleIndex: %d \n",
-                  UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex);
-            ue_process_rar(Mod_id, 0, sfn,
-                ra_rnti, //RA-RNTI
-                tx_request_pdu_list[pdu_index].segments[0].segment_data,
-                &dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.rnti, //t-crnti
-                UE_mac_inst[Mod_id].RA_prach_resources.ra_PreambleIndex,
-                tx_request_pdu_list[pdu_index].segments[0].segment_data);
-            UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
-            // Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first
-            // ULSCH Txon for the UE)
-            UE_mac_inst[Mod_id].first_ULSCH_Tx = 1;
-          }
-        } else {
-          LOG_W(MAC, "can not handle special RNTI %x\n", rnti);
+              &UE_mac_inst[ue_id].crnti, //t-crnti
+              UE_mac_inst[ue_id].RA_prach_resources.ra_PreambleIndex,
+              tx_request_pdu_list[pdu_index].segments[0].segment_data);
+          UE_mac_inst[ue_id].UE_mode[0] = RA_RESPONSE;
+          // Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first
+          // ULSCH Txon for the UE)
+          UE_mac_inst[ue_id].first_ULSCH_Tx = 1;
         }
       }
-    } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) {
-      // BCH case: Last parameter is 1 if first time synchronization and zero
-      // otherwise.  Not sure which value to put for our case.
-      if (UE_mac_inst[Mod_id].UE_mode[0] == NOT_SYNCHED){
-        dl_phy_sync_success(Mod_id, sfn, 0, 1);
-        LOG_E(MAC,
-              "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n",
-              __func__,
-              UE_mac_inst[Mod_id].UE_mode[0],
-              sfn,
-              sf);
-        UE_mac_inst[Mod_id].UE_mode[0] = PRACH;
-      } else {
-        dl_phy_sync_success(Mod_id, sfn, 0, 0);
-      }
+    } else {
+      LOG_W(MAC, "can not handle special RNTI %x\n", rnti);
     }
   }
-  return 0;
 }
 
-int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t *req, module_id_t Mod_id) {
-  if (req != NULL && req->hi_dci0_request_body.hi_dci0_pdu_list != NULL) {
-    LOG_D(PHY,
-          "[UE-PHY_STUB] hi dci0 request sfn_sf:%d number_of_dci:%d "
-          "number_of_hi:%d\n",
-          NFAPI_SFNSF2DEC(req->sfn_sf),
-          req->hi_dci0_request_body.number_of_dci,
-          req->hi_dci0_request_body.number_of_hi);
-
-    for (int i = 0; i < req->hi_dci0_request_body.number_of_dci
-                            + req->hi_dci0_request_body.number_of_hi;
-         i++) {
-      LOG_D(PHY,
-            "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n",
-            NFAPI_SFNSF2DEC(req->sfn_sf),
-            i);
-
-      if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type
-          == NFAPI_HI_DCI0_DCI_PDU_TYPE) {
-        LOG_D(PHY,
-              "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - "
-              "NFAPI_HI_DCI0_DCI_PDU_TYPE\n",
-              NFAPI_SFNSF2DEC(req->sfn_sf),
-              i);
-        const nfapi_hi_dci0_dci_pdu_rel8_t *dci =
-            &req->hi_dci0_request_body.hi_dci0_pdu_list[i].dci_pdu.dci_pdu_rel8;
-        if (dci->rnti != UE_mac_inst[Mod_id].crnti)
-          continue;
-        const int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
-        const int sf = NFAPI_SFNSF2SF(req->sfn_sf);
-        if (dci->cqi_csi_request)
-          fill_ulsch_cqi_indication_UE_MAC(Mod_id, sfn, sf, UL_INFO, dci->rnti);
-      } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type
-                 == NFAPI_HI_DCI0_HI_PDU_TYPE) {
-        nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu =
-            &req->hi_dci0_request_body.hi_dci0_pdu_list[i];
-
-        // This is meaningful only after ACKnowledging the first ULSCH Txon
-        // (i.e. Msg3)
-        if (hi_dci0_req_pdu->hi_pdu.hi_pdu_rel8.hi_value == 1
-            && UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) {
-          // LOG_I(MAC,"[UE-PHY_STUB] HI_DCI0_REQ 2 sfn_sf:%d PDU[%d] -
-          // NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
-          // UE_mac_inst[Mod_id].UE_mode[0] = PUSCH;
-          // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0;
-        }
+void dl_config_req_UE_MAC_bch(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *bch,
+                              int num_ue) {
+  DevAssert(bch->pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE);
+
+  for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+    if (UE_mac_inst[ue_id].UE_mode[0] == NOT_SYNCHED){
+      dl_phy_sync_success(ue_id, sfn, 0, 1);
+      LOG_E(MAC,
+            "%s(): Received MIB: UE_mode: %d, sfn/sf: %d.%d\n",
+            __func__,
+            UE_mac_inst[ue_id].UE_mode[0],
+            sfn,
+            sf);
+      UE_mac_inst[ue_id].UE_mode[0] = PRACH;
+    } else {
+      dl_phy_sync_success(ue_id, sfn, 0, 0);
+    }
+  }
+}
 
-      } else {
-        LOG_E(PHY,
-              "[UE-PHY_STUB] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu "
-              "type:%d\n",
-              NFAPI_SFNSF2DEC(req->sfn_sf),
-              i,
-              req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type);
-      }
+void dl_config_req_UE_MAC_mch(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *mch,
+                              int num_ue) {
+  DevAssert(mch->pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE);
+
+  for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+    if (UE_mac_inst[ue_id].UE_mode[0] == NOT_SYNCHED){
+	 LOG_D(MAC,
+            "%s(): Received MCH in NOT_SYNCHED: UE_mode: %d, sfn/sf: %d.%d\n",
+            __func__,
+            UE_mac_inst[ue_id].UE_mode[0],
+            sfn,
+            sf);
+	return;
+
+    } else {
+	 const int pdu_index = mch->mch_pdu.mch_pdu_rel8.pdu_index;
+  	if (pdu_index < 0 || pdu_index >= tx_req_num_elems) {
+    	LOG_E(MAC,
+          "%s(): Problem with receiving data: "
+          "sfn/sf:%d.%d PDU size:%d, TX_PDU index: %d\n",
+          __func__,
+          sfn, sf, mch->pdu_size, mch->mch_pdu.mch_pdu_rel8.pdu_index);
+    	return;
+  	}
+        ue_send_mch_sdu(ue_id, 0, sfn,
+            tx_request_pdu_list[pdu_index].segments[0].segment_data,
+            tx_request_pdu_list[pdu_index].segments[0].segment_length,
+            0,0);
     }
   }
+}
 
-  return 0;
+void hi_dci0_req_UE_MAC(int sfn,
+                        int sf,
+                        nfapi_hi_dci0_request_pdu_t* hi_dci0,
+                        int num_ue) {
+  if (hi_dci0->pdu_type != NFAPI_HI_DCI0_DCI_PDU_TYPE)
+    return;
+
+  const nfapi_hi_dci0_dci_pdu_rel8_t *dci = &hi_dci0->dci_pdu.dci_pdu_rel8;
+  if (!dci->cqi_csi_request)
+    return;
+  for (int ue_id = 0; ue_id < num_ue; ue_id++) {
+    if (dci->rnti == UE_mac_inst[ue_id].crnti) {
+      fill_ulsch_cqi_indication_UE_MAC(ue_id, sfn, sf, UL_INFO, dci->rnti);
+      return;
+    }
+  }
 }
 
 // The following set of memcpy functions should be getting called as callback
 // functions from pnf_p7_subframe_ind.
-int memcpy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7,
+int memcpy_dl_config_req(L1_rxtx_proc_t *proc, 
+			nfapi_pnf_p7_config_t *pnf_p7,
                          nfapi_dl_config_request_t *req) {
   dl_config_req = (nfapi_dl_config_request_t *)malloc(sizeof(nfapi_dl_config_request_t));
 
@@ -929,10 +911,11 @@ int memcpy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7,
   return 0;
 }
 
-int memcpy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7,
-                         nfapi_ul_config_request_t *req) {
+int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req)
+{
   ul_config_req = malloc(sizeof(nfapi_ul_config_request_t));
 
+
   ul_config_req->sfn_sf = req->sfn_sf;
   ul_config_req->vendor_extension = req->vendor_extension;
 
@@ -976,9 +959,12 @@ int memcpy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
   return 0;
 }
 
-int memcpy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7,
-                       nfapi_hi_dci0_request_t *req) {
+int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, 
+			nfapi_pnf_p7_config_t* pnf_p7, 
+			nfapi_hi_dci0_request_t* req) {
   hi_dci0_req = (nfapi_hi_dci0_request_t *)malloc(sizeof(nfapi_hi_dci0_request_t));
+	//if(req!=0){
+
 
   hi_dci0_req->sfn_sf = req->sfn_sf;
   hi_dci0_req->vendor_extension = req->vendor_extension;
@@ -1093,7 +1079,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,
                             int frame,
                             int subframe,
                             L1_rxtx_proc_t *proc,
-                            nfapi_dl_config_request_pdu_t *dl_config_pdu,
+			    nfapi_dl_config_request_pdu_t *dl_config_pdu,
                             uint8_t codeword_index,
                             uint8_t *sdu) {
 }
@@ -1105,6 +1091,11 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,
                          uint8_t subframe,
                          uint8_t srs_present) {
 }
+void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB,
+                          L1_rxtx_proc_t *proc,
+                          nfapi_dl_config_request_pdu_t *dl_config_pdu,
+                          uint8_t *sdu) {
+}
 
 void phy_config_request(PHY_Config_t *phy_config) {
 }
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index 21fb8518fad..09356fc9f81 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -93,27 +93,41 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id,
                          nfapi_ul_config_request_pdu_t *ul_config_pdu,
                          uint16_t frame,uint8_t subframe,uint8_t srs_present, int index);
 
-//int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, nfapi_tx_request_pdu_t* tx_request_pdu_list);
-int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id);
+void dl_config_req_UE_MAC_dci(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *dci,
+                              nfapi_dl_config_request_pdu_t *dlsch,
+                              int num_ue);
+void dl_config_req_UE_MAC_bch(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *bch,
+                              int num_ue);
+void dl_config_req_UE_MAC_mch(int sfn,
+                              int sf,
+                              nfapi_dl_config_request_pdu_t *bch,
+                              int num_ue);
 
 int tx_req_UE_MAC(nfapi_tx_request_t* req);
 
 
-int hi_dci0_req_UE_MAC(nfapi_hi_dci0_request_t* req, module_id_t Mod_id);
+void hi_dci0_req_UE_MAC(int sfn,
+                        int sf,
+                        nfapi_hi_dci0_request_pdu_t* bch,
+                        int num_ue);
 
 // The following set of memcpy functions should be getting called as callback functions from
 // pnf_p7_subframe_ind.
 
-int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req);
+int memcpy_dl_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req);
 
 
-int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req);
+int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req);
 
 
 int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req);
 
 
-int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req);
+int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req);
 
 void UE_config_stub_pnf(void);
 
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 1d25bf180a1..5965e517201 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -656,7 +656,7 @@ rrc_eNB_get_next_transaction_identifier(
 //    AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST);
 //
 //    for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
-//        if (RC.rrc[enb_mod_idP]->Info.UE_list[i] == UE_identity) {
+//        if (RC.rrc[enb_mod_idP]->Info.UE_info[i] == UE_identity) {
 //            // UE_identity already registered
 //            reg = TRUE;
 //            break;
@@ -1476,9 +1476,9 @@ rrc_eNB_generate_RRCConnectionReestablishment(
 
   if (UE_id != -1) {
     /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
-    RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+    RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
     /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */
-    RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
+    RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100;
   } else {
     LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n",
           PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
@@ -2086,8 +2086,8 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
     int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
 
     if(UE_id != -1) {
-      RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
-      RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
+      RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+      RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
     } else {
       LOG_E(RRC,
             PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n",
@@ -2134,6 +2134,8 @@ rrc_eNB_generate_RRCConnectionRelease(
 {
   uint8_t buffer[RRC_BUF_SIZE];
   uint16_t size = 0;
+  int release_num;
+
   memset(buffer, 0, RRC_BUF_SIZE);
   T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
@@ -2161,12 +2163,9 @@ rrc_eNB_generate_RRCConnectionRelease(
     ue_context_pP->ue_context.rnti,
     rrc_eNB_mui,
     size);
+  pthread_mutex_lock(&rrc_release_freelist);
 
-  while (pthread_mutex_trylock(&rrc_release_freelist)) {
-    /* spin... */
-  }
-
-  for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
+  for (release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
     if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
       if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) {
         rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
@@ -2186,6 +2185,12 @@ rrc_eNB_generate_RRCConnectionRelease(
     }
   }
 
+  /* TODO: what to do if RRC_release_ctrl is full? For now, exit. */
+  if (release_num == NUMBER_OF_UE_MAX) {
+    LOG_E(RRC, "fatal: rrc_release_info.RRC_release_ctrl is full\n");
+    exit(1);
+  }
+
   pthread_mutex_unlock(&rrc_release_freelist);
 
   if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
@@ -3512,6 +3517,35 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
                size,
                buffer,
                PDCP_TRANSMISSION_MODE_CONTROL);
+
+  /* Refresh SRBs/DRBs */
+  rrc_pdcp_config_asn1_req(ctxt_pP,
+                          *SRB_configList2, // NULL,
+                          *DRB_configList,
+                          NULL,
+                          0xff, // already configured during the securitymodecommand
+                          NULL,
+                          NULL,
+                          NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                          , (LTE_PMCH_InfoList_r9_t *) NULL
+#endif
+                          , NULL);
+
+  /* Refresh SRBs/DRBs */
+  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    rrc_rlc_config_asn1_req(ctxt_pP,
+                            *SRB_configList2, // NULL,
+                            *DRB_configList,
+                            NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                            , (LTE_PMCH_InfoList_r9_t *) NULL,
+                            0,
+                            0
+#endif
+                            );
+  }
+
   free(Sparams);
   Sparams = NULL;
   free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
@@ -5192,13 +5226,13 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
   DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
   DRB_config->rlc_Config = DRB_rlc_config;
 #ifdef RRC_DEFAULT_RAB_IS_AM
-  DRB_rlc_config->present = RLC_Config_PR_am;
-  DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50;
-  DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16;
-  DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity;
-  DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8;
-  DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35;
-  DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25;
+  DRB_rlc_config->present = LTE_RLC_Config_PR_am;
+  DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50;
+  DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16;
+  DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity;
+  DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8;
+  DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35;
+  DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25;
 #else
   DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
   DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
@@ -6029,6 +6063,35 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct
     ue_context_pP->ue_context.rnti,
     rrc_eNB_mui,
     size);
+
+  /* Refresh SRBs/DRBs */
+  rrc_pdcp_config_asn1_req(ctxt_pP,
+                          *SRB_configList2, // NULL,
+                          *DRB_configList,
+                          NULL,
+                          0xff, // already configured during the securitymodecommand
+                          NULL,
+                          NULL,
+                          NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                          , (LTE_PMCH_InfoList_r9_t *) NULL
+#endif
+                          , NULL);
+
+  /* Refresh SRBs/DRBs */
+  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    rrc_rlc_config_asn1_req(ctxt_pP,
+                            *SRB_configList2, // NULL,
+                            *DRB_configList,
+                            NULL
+#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
+                            , (LTE_PMCH_InfoList_r9_t *) NULL,
+                            0,
+                            0
+#endif
+                            );
+  }
+
   free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ);
   quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = NULL;
   free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP);
@@ -6072,12 +6135,14 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc
                            NULL,
                            NULL,
                            (LTE_PMCH_InfoList_r9_t *) NULL, NULL);
-  rrc_rlc_config_asn1_req(ctxt_pP,
-                          ue_context_p->ue_context.SRB_configList,
-                          (LTE_DRB_ToAddModList_t *) NULL,
-                          (LTE_DRB_ToReleaseList_t *) NULL,
-                          (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0
-                         );
+  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    rrc_rlc_config_asn1_req(ctxt_pP,
+                            ue_context_p->ue_context.SRB_configList,
+                            (LTE_DRB_ToAddModList_t *) NULL,
+                            (LTE_DRB_ToReleaseList_t *) NULL,
+                            (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0
+                           );
+  }
 
   if (EPC_MODE_ENABLED) {
     rrc_eNB_process_security (
@@ -6168,7 +6233,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
       return;
     }
 
-    UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id_mac]);
+    UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id_mac]);
 
     if (UE_scheduling_control->cdrx_waiting_ack == TRUE) {
       UE_scheduling_control->cdrx_waiting_ack = FALSE;
@@ -6212,14 +6277,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
                            (LTE_PMCH_InfoList_r9_t *) NULL,
                            NULL);
   /* Refresh SRBs/DRBs */
-  rrc_rlc_config_asn1_req(ctxt_pP,
-                          SRB_configList, // NULL,
-                          DRB_configList,
-                          DRB_Release_configList2,
-                          (LTE_PMCH_InfoList_r9_t *) NULL,
-                          0,
-                          0
-                         );
+  if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+    rrc_rlc_config_asn1_req(ctxt_pP,
+                            SRB_configList, // NULL,
+                            DRB_configList,
+                            DRB_Release_configList2,
+                            (LTE_PMCH_InfoList_r9_t *) NULL,
+                            0,
+                            0
+                            );
+  }
 
   /* Set the SRB active in UE context */
   if (SRB_configList != NULL) {
@@ -6615,14 +6682,6 @@ char openair_rrc_eNB_configuration(
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_FMT" Init...\n",
         PROTOCOL_RRC_CTXT_ARGS(&ctxt));
-#if OCP_FRAMEWORK
-
-  while ( RC.rrc[enb_mod_idP] == NULL ) {
-    LOG_E(RRC, "RC.rrc not yet initialized, waiting 1 second\n");
-    sleep(1);
-  }
-
-#endif
   AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!");
   AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow");
   AssertFatal(configuration!=NULL,"configuration input is null\n");
@@ -6831,12 +6890,12 @@ rrc_eNB_decode_ccch(
             break;
           }
 
-          if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
-              (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
+          if((RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
+              (RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
             LOG_E(RRC,
                   PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the c-rnti UE\n",
                   PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
-            RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
+            RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
             rrc_eNB_previous_SRB2(ue_context_p);
             ue_context_p->ue_context.ue_reestablishment_timer = 0;
           }
@@ -6862,12 +6921,12 @@ rrc_eNB_decode_ccch(
               break;
             }
 
-            if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
-                (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
+            if((RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
+                (RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
               LOG_E(RRC,
                     PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n",
                     PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
-              RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
+              RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
               rrc_eNB_previous_SRB2(ue_context_p);
               ue_context_p->ue_context.ue_reestablishment_timer = 0;
             }
@@ -7439,12 +7498,12 @@ rrc_eNB_decode_dcch(
               AssertFatal(!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type),
                           "CU cannot decode DCCH: no access to RC.mac[]\n");
 
-              if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) {
+              if(RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) {
                 LOG_I(RRC,
                       PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n",
                       PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
                 dedicated_DRB = 2;
-                RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
+                RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
               }
             } else if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION) {
               int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
@@ -7459,7 +7518,7 @@ rrc_eNB_decode_dcch(
               flexran_agent_handover = 1;
               RC.rrc[ctxt_pP->module_id]->Nb_ue++;
               dedicated_DRB = 3;
-              RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
+              RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
               ue_context_p->ue_context.Status = RRC_RECONFIGURED;
 
               if(ue_context_p->ue_context.handover_info) {
@@ -7637,7 +7696,7 @@ rrc_eNB_decode_dcch(
             break;
           }
 
-          RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
+          RC.mac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
           ue_context_p->ue_context.reestablishment_xid = -1;
 
           if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present ==
@@ -8166,6 +8225,143 @@ void rrc_enb_init(void) {
   memset(&rrc_release_info,0,sizeof(RRC_release_list_t));
 }
 
+//-----------------------------------------------------------------------------
+void process_successful_rlc_sdu_indication(int instance,
+                                           int rnti,
+                                           int message_id)
+{
+  int release_num;
+  int release_total;
+  RRC_release_ctrl_t *release_ctrl;
+
+  /* Check if the message sent was RRC Connection Release.
+   * If yes then continue the release process.
+   */
+
+  pthread_mutex_lock(&rrc_release_freelist);
+
+  if (rrc_release_info.num_UEs > 0) {
+    release_total = 0;
+
+    for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
+         release_num < NUMBER_OF_UE_MAX;
+         release_num++, release_ctrl++) {
+      if(release_ctrl->flag > 0) {
+        release_total++;
+      } else {
+        continue;
+      }
+
+      if (release_ctrl->flag == 1 && release_ctrl->rnti == rnti && release_ctrl->rrc_eNB_mui == message_id) {
+        release_ctrl->flag = 3;
+        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d flag 1->3\n",
+              release_num,
+              rnti,
+              message_id);
+        break;
+      }
+
+      if (release_ctrl->flag == 2 && release_ctrl->rnti == rnti && release_ctrl->rrc_eNB_mui == message_id) {
+        release_ctrl->flag = 4;
+        LOG_D(MAC, "DLSCH Release send:index %d rnti %x mui %d flag 2->4\n",
+              release_num,
+              rnti,
+              message_id);
+        break;
+      }
+
+      if(release_total >= rrc_release_info.num_UEs)
+        break;
+    }
+  }
+
+  pthread_mutex_unlock(&rrc_release_freelist);
+}
+
+//-----------------------------------------------------------------------------
+void process_unsuccessful_rlc_sdu_indication(int instance, int rnti)
+{
+  int release_num;
+  int release_total;
+  RRC_release_ctrl_t *release_ctrl;
+
+  /* radio link failure detected by RLC layer, remove UE properly */
+
+  pthread_mutex_lock(&rrc_release_freelist);
+
+  /* first, check if the rnti is in the list rrc_release_info.RRC_release_ctrl */
+
+  if (rrc_release_info.num_UEs > 0) {
+    release_total = 0;
+
+    for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
+         release_num < NUMBER_OF_UE_MAX;
+         release_num++, release_ctrl++) {
+      if(release_ctrl->flag > 0) {
+        release_total++;
+      } else {
+        continue;
+      }
+
+      if (release_ctrl->flag == 1 && release_ctrl->rnti == rnti) {
+        release_ctrl->flag = 3;
+        LOG_D(MAC,"DLSCH Release send:index %d rnti %x flag 1->3\n",
+              release_num,
+              rnti);
+        goto done;
+      }
+
+      if (release_ctrl->flag == 2 && release_ctrl->rnti == rnti) {
+        release_ctrl->flag = 4;
+        LOG_D(MAC, "DLSCH Release send:index %d rnti %x flag 2->4\n",
+              release_num,
+              rnti);
+        goto done;
+      }
+
+      if(release_total >= rrc_release_info.num_UEs)
+        break;
+    }
+  }
+
+  /* it's not in the list, put it with flag = 4 */
+  for (release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
+    if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) {
+      rrc_release_info.RRC_release_ctrl[release_num].flag = 4;
+      rrc_release_info.RRC_release_ctrl[release_num].rnti = rnti;
+      rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = -1;     /* not defined */
+      rrc_release_info.num_UEs++;
+      LOG_D(RRC, "radio link failure detected: index %d rnti %x flag %d \n",
+            release_num,
+            rnti,
+            rrc_release_info.RRC_release_ctrl[release_num].flag);
+      break;
+    }
+  }
+
+  /* TODO: what to do if rrc_release_info.RRC_release_ctrl is full? */
+  if (release_num == NUMBER_OF_UE_MAX) {
+    LOG_E(RRC, "fatal: radio link failure: rrc_release_info.RRC_release_ctrl is full\n");
+    exit(1);
+  }
+
+done:
+  pthread_mutex_unlock(&rrc_release_freelist);
+}
+
+//-----------------------------------------------------------------------------
+void process_rlc_sdu_indication(int instance,
+                                int rnti,
+                                int is_successful,
+                                int srb_id,
+                                int message_id)
+{
+  if (is_successful)
+    process_successful_rlc_sdu_indication(instance, rnti, message_id);
+  else
+    process_unsuccessful_rlc_sdu_indication(instance, rnti);
+}
+
 //-----------------------------------------------------------------------------
 int add_ue_to_remove(struct rrc_eNB_ue_context_s **ue_to_be_removed,
                      int removed_ue_count,
@@ -8868,6 +9064,13 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
        rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p));
        break;
 
+    case RLC_SDU_INDICATION:
+      process_rlc_sdu_indication(instance,
+                                 RLC_SDU_INDICATION(msg_p).rnti,
+                                 RLC_SDU_INDICATION(msg_p).is_successful,
+                                 RLC_SDU_INDICATION(msg_p).srb_id,
+                                 RLC_SDU_INDICATION(msg_p).message_id);
+      break;
 
     default:
       LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p);
@@ -8904,7 +9107,7 @@ rrc_enb_task(
   //if (go_nr) rrc_go_nr();
 }
   }
-}
+  }
 
 /*------------------------------------------------------------------------------*/
 void
diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.h b/openair2/RRC/LTE/rrc_eNB_UE_context.h
index 289b4d69d69..e22f517d501 100644
--- a/openair2/RRC/LTE/rrc_eNB_UE_context.h
+++ b/openair2/RRC/LTE/rrc_eNB_UE_context.h
@@ -28,6 +28,8 @@
  * \email: lionel.gauthier@eurecom.fr
  */
 #ifndef __RRC_ENB_UE_CONTEXT_H__
+#define __RRC_ENB_UE_CONTEXT_H__
+
 #include "collection/tree.h"
 #include "COMMON/platform_types.h"
 #include "rrc_defs.h"
diff --git a/openair2/RRC/LTE/utils.c b/openair2/RRC/LTE/utils.c
index 08637e0e676..c84a2be476f 100644
--- a/openair2/RRC/LTE/utils.c
+++ b/openair2/RRC/LTE/utils.c
@@ -60,11 +60,11 @@ uint8_t rrc_find_free_ue_index(uint8_t Mod_id) {
   uint16_t i;
 
   for(i=1; i<=NB_CNX_CH; i++)
-    if ( (CH_rrc_inst[Mod_id].Info.UE_list[i][0] == 0) &&
-         (CH_rrc_inst[Mod_id].Info.UE_list[i][1] == 0) &&
-         (CH_rrc_inst[Mod_id].Info.UE_list[i][2] == 0) &&
-         (CH_rrc_inst[Mod_id].Info.UE_list[i][3] == 0) &&
-         (CH_rrc_inst[Mod_id].Info.UE_list[i][4] == 0)) {
+    if ( (CH_rrc_inst[Mod_id].Info.UE_info[i][0] == 0) &&
+         (CH_rrc_inst[Mod_id].Info.UE_info[i][1] == 0) &&
+         (CH_rrc_inst[Mod_id].Info.UE_info[i][2] == 0) &&
+         (CH_rrc_inst[Mod_id].Info.UE_info[i][3] == 0) &&
+         (CH_rrc_inst[Mod_id].Info.UE_info[i][4] == 0)) {
       return i;
     }
 
@@ -78,7 +78,7 @@ unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) {
   unsigned char i;
   /*
   for(i=0;i<=NB_CNX_CH;i++)
-    if( bcmp(Mac_id.L2_id,CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id,sizeof(L2_ID))==0)
+    if( bcmp(Mac_id.L2_id,CH_rrc_inst[Mod_id].Info.UE_info[i].L2_id,sizeof(L2_ID))==0)
       return i;
   return i;
   */
@@ -167,7 +167,7 @@ unsigned char rrc_is_mobile_already_associated(uint8_t Mod_id, L2_ID Mac_id) {
   /*
   unsigned char i;
   for(i=0;i<NB_CNX_CH;i++)
-    if( bcmp(Mac_id.L2_id,CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id,sizeof(L2_ID))==0)
+    if( bcmp(Mac_id.L2_id,CH_rrc_inst[Mod_id].Info.UE_info[i].L2_id,sizeof(L2_ID))==0)
       return 1;
   return 0;
   */
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index a4092c11fa4..c00b57d7aaf 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -570,8 +570,8 @@ void  do_PHYSICALCELLGROUP(uint8_t Mod_id,
 
 void do_SpCellConfig(gNB_RRC_INST *rrc,
                       struct NR_SpCellConfig  *spconfig){
-  gNB_RrcConfigurationReq  *common_configuration;
-  common_configuration = CALLOC(1,sizeof(gNB_RrcConfigurationReq));
+  //gNB_RrcConfigurationReq  *common_configuration;
+  //common_configuration = CALLOC(1,sizeof(gNB_RrcConfigurationReq));
   //Fill servingcellconfigcommon config value
   //Fill common config to structure
   //  rrc->configuration = common_configuration;
diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h
index 8373a53584d..04e0392236b 100644
--- a/openair2/RRC/NR/nr_rrc_extern.h
+++ b/openair2/RRC/NR/nr_rrc_extern.h
@@ -28,8 +28,8 @@
 * \email: navid.nikaein@eurecom.fr, kroempa@gmail.com
 */
 
-#ifndef __OPENAIR_RRC_EXTERN_H__
-#define __OPENAIR_RRC_EXTERN_H__
+#ifndef __OPENAIR_NR_RRC_EXTERN_H__
+#define __OPENAIR_NR_RRC_EXTERN_H__
 #include "nr_rrc_defs.h"
 #include "COMMON/mac_rrc_primitives.h"
 #include "LAYER2/MAC/mac.h"
@@ -69,10 +69,12 @@ extern uint32_t timeToTrigger_ms[16];
 extern float RSRP_meas_mapping[98];
 extern float RSRQ_meas_mapping[35];
 
-extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
+
 extern pthread_mutex_t ue_pf_po_mutex;
 
-extern uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2];
+extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2];
+char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration);
 
 #endif
 
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index fba66105541..5ece5f91694 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -81,6 +81,7 @@
 #include "SIMULATION/TOOLS/sim.h" // for taus
 
 #include "executables/softmodem-common.h"
+#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
 
 //#define XER_PRINT
 
@@ -267,13 +268,6 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
   LOG_I(NR_RRC,
         PROTOCOL_NR_RRC_CTXT_FMT" Init...\n",
         PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
-#if OCP_FRAMEWORK
-
-  while (rrc == NULL ) {
-    LOG_E(NR_RRC, "RC.nrrrc not yet initialized, waiting 1 second\n");
-    sleep(1);
-  }
-#endif 
   AssertFatal(rrc != NULL, "RC.nrrrc not initialized!");
   AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow");
   AssertFatal(configuration!=NULL,"configuration input is null\n");
diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h
index 4681cabb8f2..d703c4c34ca 100644
--- a/openair2/RRC/NR/rrc_gNB_UE_context.h
+++ b/openair2/RRC/NR/rrc_gNB_UE_context.h
@@ -27,7 +27,9 @@
  * \company Eurecom
  * \email: lionel.gauthier@eurecom.fr
  */
-#ifndef __RRC_ENB_UE_CONTEXT_H__
+#ifndef __RRC_GNB_UE_CONTEXT_H__
+#define __RRC_GNB_UE_CONTEXT_H__
+
 #include "collection/tree.h"
 #include "COMMON/platform_types.h"
 #include "nr_rrc_defs.h"
@@ -58,7 +60,7 @@ int rrc_gNB_compare_ue_rnti_id(
   struct rrc_gNB_ue_context_s* c2_pP
 );
 
-RB_PROTOTYPE(rrc_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id);
+RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id);
 
 struct rrc_gNB_ue_context_s*
 rrc_gNB_allocate_new_UE_context(
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index cf48aef4594..763c208dfe6 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -41,9 +41,9 @@
 void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList) {
 
   struct rrc_gNB_ue_context_s        *ue_context_p = NULL;
-  OCTET_STRING_t *ueCapabilityRAT_Container_nr;
-  OCTET_STRING_t *ueCapabilityRAT_Container_MRDC;
-  int list_size;
+  OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL;
+  OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL;
+  int list_size=0;
   AssertFatal(UE_CapabilityRAT_ContainerList!=NULL,"UE_CapabilityRAT_ContainerList is null\n");
   AssertFatal((list_size=UE_CapabilityRAT_ContainerList->list.count) >= 2, "UE_CapabilityRAT_ContainerList->list.size %d < 2\n",UE_CapabilityRAT_ContainerList->list.count);
   for (int i=0;i<list_size;i++) {
diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c
deleted file mode 100644
index 0150ef00cda..00000000000
--- a/openair2/UTIL/MEM/mem_block.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/***************************************************************************
-                          mem_block.c  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
-
-
- ***************************************************************************/
-#define MEM_BLOCK_C
-//#include "rtos_header.h"
-#include "mem_block.h"
-#include "mem_pool.h"
-#include "list.h"
-#include "LAYER2/MAC/mac_extern.h"
-#include "assertions.h"
-/* all function calls are protected by a mutex
- * to ensure that many threads calling them at
- * the same time don't mess up.
- * We might be more clever in the future, it's a
- * bit overkill.
- * Commenting this define removes the protection,
- * so be careful with it.
- */
-#define MEMBLOCK_BIG_LOCK
-
-#ifdef MEMBLOCK_BIG_LOCK
-static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-//-----------------------------------------------------------------------------
-//#define DEBUG_MEM_MNGT_FREE
-//#define DEBUG_MEM_MNGT_ALLOC_SIZE
-//#define DEBUG_MEM_MNGT_ALLOC
-//-----------------------------------------------------------------------------
-#if defined(DEBUG_MEM_MNGT_ALLOC)
-uint32_t             counters[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-#endif
-//-----------------------------------------------------------------------------
-/*
- * initialize all ures
- */
-extern mem_pool  *memBlockVar;
-void           *
-pool_buffer_init (void)
-{
-  //-----------------------------------------------------------------------------
-
-  uint32_t             index, mb_index, pool_index;
-  mem_pool       *memory = (mem_pool *) &mem_block_var;
-  memBlockVar=malloc(sizeof(mem_pool));
-  int             pool_sizes[14] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
-                                     MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
-                                     MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
-                                     MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
-                                     MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
-                                     MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB11_NB_BLOCKS,
-                                     MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MBCOPY_NB_BLOCKS
-                                   };
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_lock(&mtex)) abort();
-#endif
-
-  memset (memory, 0, sizeof (mem_pool));
-  mb_index = 0;
-
-  // LG_TEST
-  for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
-    list_init (&memory->mem_lists[pool_index], "POOL");
-
-    for (index = 0; index < pool_sizes[pool_index]; index++) {
-      //memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
-      //memory->mem_blocks[mb_index + index].next     = NULL; -> done in memset 0
-      switch (pool_index) {
-      case 0:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool0[index][0]);
-        break;
-
-      case 1:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool1[index][0]);
-        break;
-
-      case 2:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool2[index][0]);
-        break;
-
-      case 3:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool3[index][0]);
-        break;
-
-      case 4:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool4[index][0]);
-        break;
-
-      case 5:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool5[index][0]);
-        break;
-
-      case 6:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool6[index][0]);
-        break;
-
-      case 7:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool7[index][0]);
-        break;
-
-      case 8:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool8[index][0]);
-        break;
-
-      case 9:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool9[index][0]);
-        break;
-
-      case 10:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool10[index][0]);
-        break;
-
-      case 11:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool11[index][0]);
-        break;
-
-      case 12:
-        memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool12[index][0]);
-        break;
-
-      default:
-        ;
-        memory->mem_blocks[mb_index + index].data = NULL;   // pool copy
-
-      }
-
-      memory->mem_blocks[mb_index + index].pool_id = pool_index;
-      list_add_tail_eurecom (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
-    }
-
-    mb_index += pool_sizes[pool_index];
-  }
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_unlock(&mtex)) abort();
-#endif
-
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-void           *
-pool_buffer_clean (void *arg)
-{
-  //-----------------------------------------------------------------------------
-  return 0;
-}
-//-----------------------------------------------------------------------------
-void
-free_mem_block (mem_block_t * leP, const char* caller)
-{
-  //-----------------------------------------------------------------------------
-
-  if (!(leP)) {
-    LOG_W (RLC,"[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
-    return;
-  }
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_lock(&mtex)) abort();
-#endif
-
-#ifdef DEBUG_MEM_MNGT_FREE
-  LOG_D (RLC,"[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id);
-#endif
-#ifdef DEBUG_MEM_MNGT_ALLOC
-  check_free_mem_block (leP);
-#endif
-
-  if (leP->pool_id <= MEM_MNGT_POOL_ID_COPY) {
-    list_add_tail_eurecom (leP, &mem_block_var.mem_lists[leP->pool_id]);
-#ifdef DEBUG_MEM_MNGT_ALLOC
-    counters[leP->pool_id] -= 1;
-    LGO_D (RLC,"[%s][MEM_MNGT][INFO] after pool[%2d] freed: counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
-        caller, leP->pool_id,
-        counters[0],counters[1],counters[2],counters[3],counters[4],
-        counters[5],counters[6],counters[7],counters[8],counters[9],
-        counters[10],counters[11]);
-#endif
-    leP = NULL;                 // this prevent from freeing the block twice
-  } else {
-    LOG_E (RLC,"[MEM_MNGT][FREE] ERROR free_mem_block() unknown pool_id : %d\n", leP->pool_id);
-  }
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_unlock(&mtex)) abort();
-#endif
-}
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-get_free_mem_block (uint32_t sizeP, const char* caller)
-{
-  //-----------------------------------------------------------------------------
-  mem_block_t      *le = NULL;
-  int             pool_selected;
-  int             size;
-
-  if (sizeP > MEM_MNGT_MB12_BLOCK_SIZE) {
-    LOG_E (RLC,"[MEM_MNGT][ERROR][FATAL] size requested %d out of bounds\n", sizeP);
-    display_mem_load ();
-    AssertFatal(1==0,"get_free_mem_block size requested out of bounds");
-    return NULL;
-  }
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_lock(&mtex)) abort();
-#endif
-
-  size = sizeP >> 6;
-  pool_selected = 0;
-
-  while ((size)) {
-    pool_selected += 1;
-    size = size >> 1;
-  }
-
-  // pool is selected according to the size requested, now get a block
-  // if no block is available pick one in an other pool
-  do {
-    if ((le = list_remove_head (&mem_block_var.mem_lists[pool_selected]))) {
-#ifdef DEBUG_MEM_MNGT_ALLOC
-      counters[pool_selected] += 1;
-      LOG_D (RLC,"[%s][MEM_MNGT][INFO] after pool[%2d] allocated: counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
-          caller,
-          pool_selected,
-          counters[0],counters[1],counters[2],counters[3],counters[4],
-          counters[5],counters[6],counters[7],counters[8],counters[9],
-          counters[10],counters[11]);
-#endif
-#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
-      LOG_D (RLC,"[MEM_MNGT][INFO] ALLOC MEM_BLOCK SIZE %d bytes pool %d (%p)\n", sizeP, pool_selected,le);
-#endif
-
-      AssertFatal(le->pool_id == pool_selected, "Unexpected pool ID!");
-
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_unlock(&mtex)) abort();
-#endif
-
-      return le;
-    }
-
-#ifdef DEBUG_MEM_MNGT_ALLOC
-    LOG_E (RLC,"[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
-    //    display_mem_load ();
-    //    check_mem_area ((void *)&mem_block_var);
-#endif
-  } while (pool_selected++ < 12);
-
-  LOG_E(PHY, "[MEM_MNGT][ERROR][FATAL] failed allocating MEM_BLOCK size %d byes (pool_selected=%d size=%d)\n", sizeP, pool_selected, size);
-//  display_mem_load();
-//  AssertFatal(1==0,"get_free_mem_block failed");
-  LOG_E(MAC,"[MEM_MNGT][ERROR][FATAL] get_free_mem_block failed!!!\n");
-#ifdef MEMBLOCK_BIG_LOCK
-  if (pthread_mutex_unlock(&mtex)) abort();
-#endif
-
-  return NULL;
-};
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-get_free_copy_mem_block (void)
-{
-  //-----------------------------------------------------------------------------
-  mem_block_t      *le;
-
-#ifdef MEMBLOCK_BIG_LOCK
-  AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
-#endif
-
-  if ((le = list_remove_head (&mem_block_var.mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
-#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
-    LOG_D (RLC,"[MEM_MNGT][INFO] ALLOC COPY MEM BLOCK (%p)\n",le);
-#endif
-#ifdef DEBUG_MEM_MNGT_ALLOC
-      counters[MEM_MNGT_POOL_ID_COPY] += 1;
-      LOG_D (RLC,"[MEM_MNGT][INFO] pool counters = {%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d %2d}\n",
-          counters[0],counters[1],counters[2],counters[3],counters[4],
-          counters[5],counters[6],counters[7],counters[8],counters[9],
-          counters[10],counters[11]);
-#endif
-    return le;
-  } else {
-    LOG_E (RLC,"[MEM_MNGT][ERROR] POOL COPY IS EMPTY\n");
-    //#ifdef DEBUG_MEM_MNGT_ALLOC
-    check_mem_area ();
-    //    break_point ();
-    //#endif
-
-    AssertFatal(1==0,"mem pool is empty");
-    return NULL;
-  }
-}
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-copy_mem_block (mem_block_t * leP, mem_block_t * destP)
-{
-  //-----------------------------------------------------------------------------
-
-#ifdef MEMBLOCK_BIG_LOCK
-  AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
-#endif
-
-  if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
-    destP->data = leP->data;
-  } else {
-    LOG_E (RLC,"[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
-  }
-
-  return destP;
-}
-
-//-----------------------------------------------------------------------------
-void
-display_mem_load (void)
-{
-  //-----------------------------------------------------------------------------
-#ifdef MEMBLOCK_BIG_LOCK
-  /* this function does not need to be protected, do nothing */
-#endif
-
-  mem_pool       *memory = (mem_pool *) &mem_block_var;
-
-  LOG_D (RLC,"POOL 0 (%d elements of %d Bytes): ", MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB0_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID0]);
-  LOG_D (RLC,"POOL 1 (%d elements of %d Bytes): ", MEM_MNGT_MB1_NB_BLOCKS, MEM_MNGT_MB1_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID1]);
-  LOG_D (RLC,"POOL 2 (%d elements of %d Bytes): ", MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB2_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID2]);
-  LOG_D (RLC,"POOL 3 (%d elements of %d Bytes): ", MEM_MNGT_MB3_NB_BLOCKS, MEM_MNGT_MB3_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID3]);
-  LOG_D (RLC,"POOL 4 (%d elements of %d Bytes): ", MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB4_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID4]);
-  LOG_D (RLC,"POOL 5 (%d elements of %d Bytes): ", MEM_MNGT_MB5_NB_BLOCKS, MEM_MNGT_MB5_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID5]);
-  LOG_D (RLC,"POOL 6 (%d elements of %d Bytes): ", MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB6_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID6]);
-  LOG_D (RLC,"POOL 7 (%d elements of %d Bytes): ", MEM_MNGT_MB7_NB_BLOCKS, MEM_MNGT_MB7_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID7]);
-  LOG_D (RLC,"POOL 8 (%d elements of %d Bytes): ", MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB8_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID8]);
-  LOG_D (RLC,"POOL 9 (%d elements of %d Bytes): ", MEM_MNGT_MB9_NB_BLOCKS, MEM_MNGT_MB9_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID9]);
-  LOG_D (RLC,"POOL 10 (%d elements of %d Bytes): ", MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB10_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID10]);
-  LOG_D (RLC,"POOL 11 (%d elements of %d Bytes): ", MEM_MNGT_MB11_NB_BLOCKS, MEM_MNGT_MB11_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID11]);
-  LOG_D (RLC,"POOL 12 (%d elements of %d Bytes): ", MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MB12_BLOCK_SIZE);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID12]);
-  LOG_D (RLC,"POOL C (%d elements): ", MEM_MNGT_MBCOPY_NB_BLOCKS);
-  list_display (&memory->mem_lists[MEM_MNGT_POOL_ID_COPY]);
-}
-
-//-----------------------------------------------------------------------------
-void
-check_mem_area (void)
-{
-  //-----------------------------------------------------------------------------
-  int             index, mb_index;
-  mem_pool       *memory = (mem_pool *) &mem_block_var;
-
-#ifdef MEMBLOCK_BIG_LOCK
-  AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
-#endif
-
-  for (index = 0; index < MEM_MNGT_MB0_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[index].data != (unsigned char*)&(memory->mem_pool0[index][0])) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID0)) {
-      LOG_D (RLC,"[MEM] ERROR POOL0 block index %d\n", index);
-    }
-  }
-
-  mb_index = MEM_MNGT_MB0_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool1[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
-      LOG_D (RLC,"[MEM] ERROR POOL1 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB1_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool2[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
-      LOG_D (RLC,"[MEM] ERROR POOL2 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB2_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool3[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
-      LOG_D (RLC,"[MEM] ERROR POOL3 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB3_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool4[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
-      LOG_D (RLC,"[MEM] ERROR POOL4 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB4_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool5[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
-      LOG_D (RLC,"[MEM] ERROR POOL5 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB5_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool6[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
-      LOG_D (RLC,"[MEM] ERROR POOL6 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB6_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool7[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
-      LOG_D (RLC,"[MEM] ERROR POOL7 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB7_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool8[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
-      LOG_D (RLC,"[MEM] ERROR POOL8 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB8_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool9[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
-      LOG_D (RLC,"[MEM] ERROR POOL9 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB9_NB_BLOCKS;
-
-  for (index = mb_index; index < MEM_MNGT_MB10_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool10[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID10)) {
-      LOG_D (RLC,"[MEM] ERROR POOL10 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB10_NB_BLOCKS;
-
-  for (index = mb_index; index < MEM_MNGT_MB11_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool11[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID11)) {
-      LOG_D (RLC,"[MEM] ERROR POOL11 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB11_NB_BLOCKS;
-
-  for (index = mb_index; index < MEM_MNGT_MB12_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool12[index][0]))
-        && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID12)) {
-      LOG_D (RLC,"[MEM] ERROR POOL12 block index %d\n", index);
-    }
-  }
-
-  mb_index += MEM_MNGT_MB12_NB_BLOCKS;
-
-  for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
-    if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
-      LOG_D (RLC,"[MEM] ERROR POOL COPY block index %d\n", index);
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-void
-check_free_mem_block (mem_block_t * leP)
-{
-  //-----------------------------------------------------------------------------
-  ptrdiff_t             block_index;
-
-#ifdef MEMBLOCK_BIG_LOCK
-  /* this function does not SEEM TO need to be protected, do nothing (for the moment) */
-#endif
-
-  if ((leP >= mem_block_var.mem_blocks) && (leP <= &mem_block_var.mem_blocks[MEM_MNGT_NB_ELEMENTS-1])) {
-    // the pointer is inside the memory region
-    block_index = leP - mem_block_var.mem_blocks;
-    // block_index is now: 0 <= block_index < MEM_MNGT_NB_ELEMENTS
-
-    if (block_index < MEM_MNGT_MB0_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool0[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB0_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB1_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool1[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID1)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB1_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB2_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool2[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID2)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB2_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB3_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool3[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID3)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB3_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB4_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool4[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB4_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB5_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool5[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB5_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB6_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool6[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB6_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB7_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool7[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB7_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB8_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool8[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB8_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB9_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool9[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB9_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB10_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool10[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID10)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB10_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB11_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool11[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID11)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-
-    block_index -= MEM_MNGT_MB11_NB_BLOCKS;
-
-    if (block_index < MEM_MNGT_MB12_NB_BLOCKS) {
-      if ((leP->data != (unsigned char*)mem_block_var.mem_pool12[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID12)) {
-        LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-
-      return;
-    }
-  } else {
-    LOG_D (RLC,"[MEM][ERROR][FATAL] free mem block is corrupted\n");
-  }
-
-  // the block is ok
-}
diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h
index f40566f6ed2..0d994306407 100644
--- a/openair2/UTIL/MEM/mem_block.h
+++ b/openair2/UTIL/MEM/mem_block.h
@@ -57,91 +57,8 @@ mem_block_t *get_free_copy_mem_block (void);
 mem_block_t *get_free_copy_mem_block_up (void);
 mem_block_t *copy_mem_block (mem_block_t * leP, mem_block_t * destP);
 void         display_mem_load (void);
-
-void         check_mem_area (void);
-void        check_free_mem_block (mem_block_t * leP);
-#    define MEM_SCALE MAX_MOBILES_PER_ENB
-// definition of the size of the allocated memory area
-#    define MEM_MNGT_MB0_BLOCK_SIZE     64
-// 64
-#    define MEM_MNGT_MB0_NB_BLOCKS      4096 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID0           0
-
-#    define MEM_MNGT_MB1_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*2
-// 128
-#    define MEM_MNGT_MB1_NB_BLOCKS      4096 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID1           1
-
-#    define MEM_MNGT_MB2_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*4
-// 256
-#    define MEM_MNGT_MB2_NB_BLOCKS      2048 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID2           2
-
-#    define MEM_MNGT_MB3_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*8
-// 512
-#    define MEM_MNGT_MB3_NB_BLOCKS      2048 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID3           3
-
-#    define MEM_MNGT_MB4_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*16
-// 1024
-#    define MEM_MNGT_MB4_NB_BLOCKS      1024 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID4           4
-
-#    define MEM_MNGT_MB5_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*32
-// 2048
-#    define MEM_MNGT_MB5_NB_BLOCKS      1024 * MEM_SCALE // LG WAS 1024
-#    define MEM_MNGT_POOL_ID5           5
-
-#    define MEM_MNGT_MB6_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*64
-// 4096
-#    define MEM_MNGT_MB6_NB_BLOCKS      1024 * MEM_SCALE  // LG WAS 256
-#    define MEM_MNGT_POOL_ID6           6
-
-#    define MEM_MNGT_MB7_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*128
-// 8192
-#    define MEM_MNGT_MB7_NB_BLOCKS      64* MEM_SCALE   // LG WAS 32
-#    define MEM_MNGT_POOL_ID7           7
-
-#    define MEM_MNGT_MB8_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*256
-
-#ifdef JUMBO_FRAMES
-#    define MEM_MNGT_MB8_NB_BLOCKS      256 * MEM_SCALE
-#else
-#    define MEM_MNGT_MB8_NB_BLOCKS      16 * MEM_SCALE
-// 16384
-#endif
-#    define MEM_MNGT_POOL_ID8           8
-
-#    define MEM_MNGT_MB9_BLOCK_SIZE     MEM_MNGT_MB0_BLOCK_SIZE*512
-// 32768
-#    define MEM_MNGT_MB9_NB_BLOCKS      8 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID9           9
-
-#    define MEM_MNGT_MB10_BLOCK_SIZE    MEM_MNGT_MB0_BLOCK_SIZE*1024
-// 65536
-#    define MEM_MNGT_MB10_NB_BLOCKS     0 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID10          10
-
-#    define MEM_MNGT_MB11_BLOCK_SIZE    MEM_MNGT_MB0_BLOCK_SIZE*2048
-// 131072
-#    define MEM_MNGT_MB11_NB_BLOCKS     0 * MEM_SCALE
-#    define MEM_MNGT_POOL_ID11          11
-
-#    define MEM_MNGT_MB12_BLOCK_SIZE    MEM_MNGT_MB0_BLOCK_SIZE*4096
-// 262144
-#    define MEM_MNGT_MB12_NB_BLOCKS     32 * MEM_SCALE
-//#    define MEM_MNGT_MB12_NB_BLOCKS     4096 * MEM_SCALE
-
-#    define MEM_MNGT_POOL_ID12          12
-
-
-#    define MEM_MNGT_MBCOPY_NB_BLOCKS   1024
-#    define MEM_MNGT_NB_ELEMENTS        MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS + MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS + MEM_MNGT_MB9_NB_BLOCKS + MEM_MNGT_MB10_NB_BLOCKS + MEM_MNGT_MB11_NB_BLOCKS + MEM_MNGT_MB12_NB_BLOCKS + MEM_MNGT_MBCOPY_NB_BLOCKS
-#    define MEM_MNGT_POOL_ID_COPY        13
-
 #define LIST_NAME_MAX_CHAR 32
 
-
 typedef struct {
   struct mem_block_t *head;
   struct mem_block_t *tail;
@@ -156,31 +73,6 @@ typedef struct {
   char               name[LIST_NAME_MAX_CHAR];
 } list_t;
 
-
-
-typedef struct {
-  //-----------------------------------------------------------
-  // basic memory management
-  //-----------------------------------------------------------
-  char              mem_pool0[MEM_MNGT_MB0_NB_BLOCKS][MEM_MNGT_MB0_BLOCK_SIZE];
-  char              mem_pool1[MEM_MNGT_MB1_NB_BLOCKS][MEM_MNGT_MB1_BLOCK_SIZE];
-  char              mem_pool2[MEM_MNGT_MB2_NB_BLOCKS][MEM_MNGT_MB2_BLOCK_SIZE];
-  char              mem_pool3[MEM_MNGT_MB3_NB_BLOCKS][MEM_MNGT_MB3_BLOCK_SIZE];
-  char              mem_pool4[MEM_MNGT_MB4_NB_BLOCKS][MEM_MNGT_MB4_BLOCK_SIZE];
-  char              mem_pool5[MEM_MNGT_MB5_NB_BLOCKS][MEM_MNGT_MB5_BLOCK_SIZE];
-  char              mem_pool6[MEM_MNGT_MB6_NB_BLOCKS][MEM_MNGT_MB6_BLOCK_SIZE];
-  char              mem_pool7[MEM_MNGT_MB7_NB_BLOCKS][MEM_MNGT_MB7_BLOCK_SIZE];
-  char              mem_pool8[MEM_MNGT_MB8_NB_BLOCKS][MEM_MNGT_MB8_BLOCK_SIZE];
-  char              mem_pool9[MEM_MNGT_MB9_NB_BLOCKS][MEM_MNGT_MB9_BLOCK_SIZE];
-  char              mem_pool10[MEM_MNGT_MB10_NB_BLOCKS][MEM_MNGT_MB10_BLOCK_SIZE];
-  char              mem_pool11[MEM_MNGT_MB11_NB_BLOCKS][MEM_MNGT_MB11_BLOCK_SIZE];
-  char              mem_pool12[MEM_MNGT_MB12_NB_BLOCKS][MEM_MNGT_MB12_BLOCK_SIZE];
-  mem_block_t     mem_blocks[MEM_MNGT_NB_ELEMENTS];
-  list_t          mem_lists[14];
-
-} mem_pool;
-
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/openair2/UTIL/MEM/mem_mngt.c b/openair2/UTIL/MEM/mem_mngt.c
deleted file mode 100644
index 57c90ea4f90..00000000000
--- a/openair2/UTIL/MEM/mem_mngt.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/***************************************************************************
-                          mem_mngt.c  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
-
-
- ***************************************************************************/
-#define MEM_MNGT_C
-#include "rtos_header.h"
-#include "platform.h"
-#include "protocol_vars_extern.h"
-#include "print.h"
-
-#include "mem_block.h"
-#include "mem_pool.h"
-#include "lists_proto_extern.h"
-#include "umts_sched.h"
-//-----------------------------------------------------------------------------
-#define DEBUG_MEM_MNGT_FREE
-#define DEBUG_MEM_MNGT_ALLOC_SIZE
-#define DEBUG_MEM_MNGT_ALLOC
-#ifdef DEBUG_MEM_MNGT_ADDR
-#    define   PRINT_MEM_MNGT_ADDR msg
-#else
-#    define   PRINT_MEM_MNGT_ADDR
-//
-#endif
-//-----------------------------------------------------------------------------
-uint32_t             counters[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-//-----------------------------------------------------------------------------
-/*
- * initialize all ures
- */
-void           *
-pool_buffer_init (void *arg)
-{
-  //-----------------------------------------------------------------------------
-
-  uint32_t             index, mb_index, pool_index;
-  mem_pool       *memory = (mem_pool *) arg;
-  int             pool_sizes[11] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
-                                     MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
-                                     MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
-                                     MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
-                                     MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
-                                     MEM_MNGT_MBCOPY_NB_BLOCKS
-                                   };
-
-  memset (memory, 0, sizeof (mem_pool));
-  mb_index = 0;
-
-  // LG_TEST
-  for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
-    init_list (&memory->mem_lists[pool_index], "POOL");
-
-    for (index = 0; index < pool_sizes[pool_index]; index++) {
-      //memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
-      //memory->mem_blocks[mb_index + index].next     = NULL; -> done in memset 0
-      switch (pool_index) {
-      case 0:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool0[index][0]);
-        break;
-
-      case 1:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool1[index][0]);
-        break;
-
-      case 2:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool2[index][0]);
-        break;
-
-      case 3:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool3[index][0]);
-        break;
-
-      case 4:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool4[index][0]);
-        break;
-
-      case 5:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool5[index][0]);
-        break;
-
-      case 6:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool6[index][0]);
-        break;
-
-      case 7:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool7[index][0]);
-        break;
-
-      case 8:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool8[index][0]);
-        break;
-
-      case 9:
-        memory->mem_blocks[mb_index + index].data = &(memory->mem_pool9[index][0]);
-        break;
-
-      default:
-        ;
-        memory->mem_blocks[mb_index + index].data = NULL;   // pool copy
-
-      }
-
-      memory->mem_blocks[mb_index + index].pool_id = pool_index;
-      add_tail (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
-    }
-
-    mb_index += pool_sizes[pool_index];
-  }
-
-  return 0;
-}
-
-//-----------------------------------------------------------------------------
-void           *
-pool_buffer_clean (void *arg)
-{
-  //-----------------------------------------------------------------------------
-#ifndef NO_THREAD_SAFE
-  mem_pool       *memory = (mem_pool *) arg;
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID0].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID1].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID2].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID3].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID4].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID5].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID6].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID7].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID8].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID9].mutex);
-  pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID_COPY].mutex);
-#endif
-  return 0;
-}
-//-----------------------------------------------------------------------------
-void
-free_mem_block (mem_block_t * leP, __func__)
-{
-  //-----------------------------------------------------------------------------
-
-  if (!(leP)) {
-    msg ("[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
-    return;
-  }
-
-#ifdef DEBUG_MEM_MNGT_FREE
-  msg ("[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id, __func__);
-#endif
-#ifdef DEBUG_MEM_MNGT_ALLOC
-  check_free_mem_block (leP, __func__);
-#endif
-
-  if (leP->pool_id <= MEM_MNGT_POOL_ID_COPY) {
-    add_tail (leP, &mem->mem_lists[leP->pool_id]);
-#ifdef DEBUG_MEM_MNGT_ALLOC
-    counters[leP->pool_id] -= 1;
-#endif
-    leP = NULL;                 // this prevent from freeing the block twice
-  } else {
-    msg ("[MEM_MNGT][FREE] ERROR free_mem_block() unknown pool_id : %d\n", leP->pool_id, __func__);
-  }
-}
-
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-get_free_mem_block (uint16_t sizeP, __func__)
-{
-  //-----------------------------------------------------------------------------
-  mem_block_t      *le = NULL;
-  int             pool_selected;
-  int             size;
-
-  if (sizeP > MEM_MNGT_MB9_BLOCK_SIZE) {
-    msg ("[MEM_MNGT][ERROR][FATAL] size requested  %d out of bounds %d\n",sizeP,MEM_MNGT_MB9_BLOCK_SIZE);
-    wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
-    return NULL;
-  }
-
-  size = sizeP >> 6;
-  pool_selected = 0;
-
-  while ((size)) {
-    pool_selected += 1;
-    size = size >> 1;
-  }
-
-  // pool is selected according to the size requested, now get a block
-  // if no block is available pick one in an other pool
-  do {
-    if ((le = remove_head (&mem->mem_lists[pool_selected]))) {
-#ifdef DEBUG_MEM_MNGT_ALLOC
-      counters[pool_selected] += 1;
-#endif
-#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
-      msg ("[MEM_MNGT][INFO] ALLOC MEM_BLOCK SIZE %d bytes pool %d\n", sizeP, pool_selected);
-#endif
-      return le;
-    }
-
-#ifdef DEBUG_MEM_MNGT_ALLOC
-    msg ("[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
-    display_mem_load ();
-    check_mem_area (mem);
-#endif
-  } while (pool_selected++ < 9);
-
-  msg ("[MEM_MNGT][ERROR][FATAL] size %d requested out of bounds or memory pools empty\n", sizeP);
-  wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
-  return NULL;
-};
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-get_free_copy_mem_block (void)
-{
-  //-----------------------------------------------------------------------------
-  mem_block_t      *le;
-
-  if ((le = remove_head (&mem->mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
-    return le;
-  } else {
-    msg ("[MEM_MNGT][ERROR] POOL COPY IS EMPTY\n");
-    display_mem_load ();
-#ifdef DEBUG_MEM_MNGT_ALLOC
-    check_mem_area (mem);
-    break_point ();
-#endif
-    wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
-
-    return NULL;
-  }
-}
-
-//-----------------------------------------------------------------------------
-mem_block_t      *
-copy_mem_block (mem_block_t * leP, mem_block_t * destP)
-{
-  //-----------------------------------------------------------------------------
-
-  if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
-    destP->data = leP->data;
-  } else {
-    msg ("[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
-  }
-
-  return destP;
-}
-
-//-----------------------------------------------------------------------------
-void
-display_mem_load (void)
-{
-  //-----------------------------------------------------------------------------
-
-  msg ("POOL 0 (%d elements of %d Bytes): \n", MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB0_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID0]);
-  msg ("POOL 1 (%d elements of %d Bytes): \n", MEM_MNGT_MB1_NB_BLOCKS, MEM_MNGT_MB1_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID1]);
-  msg ("POOL 2 (%d elements of %d Bytes): \n", MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB2_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID2]);
-  msg ("POOL 3 (%d elements of %d Bytes): \n", MEM_MNGT_MB3_NB_BLOCKS, MEM_MNGT_MB3_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID3]);
-  msg ("POOL 4 (%d elements of %d Bytes): \n", MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB4_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID4]);
-  msg ("POOL 5 (%d elements of %d Bytes): \n", MEM_MNGT_MB5_NB_BLOCKS, MEM_MNGT_MB5_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID5]);
-  msg ("POOL 6 (%d elements of %d Bytes): \n", MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB6_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID6]);
-  msg ("POOL 7 (%d elements of %d Bytes): \n", MEM_MNGT_MB7_NB_BLOCKS, MEM_MNGT_MB7_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID7]);
-  msg ("POOL 8 (%d elements of %d Bytes): \n", MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB8_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID8]);
-  msg ("POOL 9 (%d elements of %d Bytes): \n", MEM_MNGT_MB9_NB_BLOCKS, MEM_MNGT_MB9_BLOCK_SIZE);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID9]);
-  msg ("POOL C (%d elements): \n", MEM_MNGT_MBCOPY_NB_BLOCKS);
-  display_list (&mem->mem_lists[MEM_MNGT_POOL_ID_COPY]);
-}
-
-//-----------------------------------------------------------------------------
-void
-check_mem_area (void *arg)
-{
-  //-----------------------------------------------------------------------------
-  int             index, mb_index;
-  mem_pool       *memory = (mem_pool *) arg;
-
-  for (index = 0; index < MEM_MNGT_MB0_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[index].data != &(memory->mem_pool0[index][0])) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID0)) {
-      msg ("[MEM] ERROR POOL0 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index = MEM_MNGT_MB0_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool1[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
-      msg ("[MEM] ERROR POOL1 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB1_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool2[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
-      msg ("[MEM] ERROR POOL2 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB2_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool3[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
-      msg ("[MEM] ERROR POOL3 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB3_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool4[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
-      msg ("[MEM] ERROR POOL4 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB4_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool5[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
-      msg ("[MEM] ERROR POOL5 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB5_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool6[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
-      msg ("[MEM] ERROR POOL6 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB6_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool7[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
-      msg ("[MEM] ERROR POOL7 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB7_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool8[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
-      msg ("[MEM] ERROR POOL8 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB8_NB_BLOCKS;
-
-  for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
-    if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool9[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
-      msg ("[MEM] ERROR POOL9 block index %d\n", index);
-      break_point ();
-    }
-  }
-
-  mb_index += MEM_MNGT_MB9_NB_BLOCKS;
-
-  for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
-    if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
-      msg ("[MEM] ERROR POOL COPY block index %d\n", index);
-      break_point ();
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-void
-check_free_mem_block (mem_block_t * leP, __func__)
-{
-  //-----------------------------------------------------------------------------
-  int             block_index;
-
-  if ((leP >= &mem->mem_blocks[0]) && (leP <= &mem->mem_blocks[MEM_MNGT_NB_ELEMENTS])) {
-    block_index = ((uint32_t) leP - (uint32_t) (&mem->mem_blocks[0])) / sizeof (mem_block_t);
-
-    if (block_index < MEM_MNGT_MB0_NB_BLOCKS) {
-      if (((uint32_t) (leP->data) != (uint32_t) (&(mem->mem_pool0[block_index][0]))) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index < (MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS)) {
-      if ((leP->data != &(mem->mem_pool1[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID1)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool2[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID2)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool3[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID3)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool4[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS +
-               MEM_MNGT_MB5_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool5[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index <
-               MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
-               MEM_MNGT_MB6_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool6[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index <
-               MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
-               MEM_MNGT_MB6_NB_BLOCKS +
-               MEM_MNGT_MB7_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool7[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index <
-               MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
-               MEM_MNGT_MB6_NB_BLOCKS +
-               MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool8[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    } else if (block_index <
-               MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
-               MEM_MNGT_MB6_NB_BLOCKS +
-               MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS + MEM_MNGT_MB9_NB_BLOCKS) {
-      if ((leP->data != &(mem->mem_pool9[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
-        msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-      }
-    }
-
-  } else {
-    msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
-  }
-}
-
-//-----------------------------------------------------------------------------
-void
-break_point (void)
-{
-  //-----------------------------------------------------------------------------
-  int             break_var;
-
-  msg ("[BREAK_POINT]\n");
-  break_var = 1;
-}
diff --git a/openair2/UTIL/MEM/mem_mngt_proto_extern.h b/openair2/UTIL/MEM/mem_mngt_proto_extern.h
deleted file mode 100644
index 4690bba42e5..00000000000
--- a/openair2/UTIL/MEM/mem_mngt_proto_extern.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
diff --git a/openair2/UTIL/MEM/mem_pool.h b/openair2/UTIL/MEM/mem_pool.h
deleted file mode 100644
index cc0face78c6..00000000000
--- a/openair2/UTIL/MEM/mem_pool.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-/***************************************************************************
-                          mem_pool.h  -  description
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
-
-
- ***************************************************************************/
-#ifndef __MEM_POOL_H__
-#    define __MEM_POOL_H__
-
-#    include "list.h"
-#    include "mem_block.h"
-
-
-#endif
diff --git a/openair2/UTIL/OCG/OCG_if.h b/openair2/UTIL/OCG/OCG_if.h
index c515d9746df..cc55b56f36c 100644
--- a/openair2/UTIL/OCG/OCG_if.h
+++ b/openair2/UTIL/OCG/OCG_if.h
@@ -30,8 +30,8 @@
 * \warning
 */
 
-#ifndef __CONFIGEN_IF_H__
-#define __CONFIG_IF_H__
+#ifndef __UTIL_OCG_OCG_IF__H__
+#define __UTIL_OCG_OCG_IF__H__
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/openair2/UTIL/OPT/mac_pcap.h b/openair2/UTIL/OPT/mac_pcap.h
index 48b31bb3c07..3141d17d592 100644
--- a/openair2/UTIL/OPT/mac_pcap.h
+++ b/openair2/UTIL/OPT/mac_pcap.h
@@ -1,3 +1,6 @@
+#ifndef __UTIL_OPT_MAC_PCAP__H__
+#define __UTIL_OPT_MAC_PCAP__H__
+
 #include <stdio.h>
 #include <string.h>
 #include <arpa/inet.h>
@@ -42,4 +45,4 @@ typedef struct MAC_Context_Info_t {
   unsigned int   subframesSinceCaptureStart;
 } MAC_Context_Info_t;
 
-
+#endif
diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h
index 86f1a045d85..6861e09cb17 100644
--- a/openair2/UTIL/OPT/opt.h
+++ b/openair2/UTIL/OPT/opt.h
@@ -88,16 +88,12 @@ typedef guint8   gboolean;
     { .s5= {NULL }} ,                   \
   }
 
-#ifdef OCP_FRAMEWORK
-#include <enums.h>
-#else
 typedef enum trace_mode_e {
   OPT_WIRESHARK,
   OPT_PCAP,
   OPT_TSHARK,
   OPT_NONE
 } trace_mode_t;
-#endif
 
 typedef enum radio_type_e {
   RADIO_TYPE_FDD = 1,
diff --git a/openair2/UTIL/OPT/packet-mac-lte.h b/openair2/UTIL/OPT/packet-mac-lte.h
index 4dfbe7912ec..2d36e02df4d 100644
--- a/openair2/UTIL/OPT/packet-mac-lte.h
+++ b/openair2/UTIL/OPT/packet-mac-lte.h
@@ -22,6 +22,8 @@
  modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature 
  */
 
+#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__
+#define __UTIL_OPT_PACKET_MAC_LTE__H__
 
 #include "ws_symbol_export.h"
 
@@ -376,3 +378,5 @@ typedef enum {
  * vi: set shiftwidth=4 tabstop=8 expandtab:
  * :indentSize=4:tabSize=8:noTabs=true:
  */
+
+#endif
diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c
index f8cd0ef64c5..8c6a74e0429 100644
--- a/openair2/UTIL/OPT/probe.c
+++ b/openair2/UTIL/OPT/probe.c
@@ -99,8 +99,8 @@ int opt_enabled=0;
 //static unsigned char g_PDUBuffer[1600];
 //static unsigned int g_PDUOffset;
 
-static char *in_ip;
-static char *in_path;
+static char in_ip[128]={0};
+static char in_path[128]={0};
 FILE *file_fd = NULL;
 pcap_hdr_t file_header = {
   0xa1b2c3d4,   /* magic number */
@@ -447,9 +447,11 @@ int init_opt(void)
   char *in_type=NULL;
   paramdef_t opt_params[]          = OPT_PARAMS_DESC ;
   checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC;
-  uint16_t in_port;
-  config_set_checkfunctions(opt_params, opt_checkParams, sizeof(opt_params)/sizeof(paramdef_t));
-  config_get(opt_params, sizeof(opt_params)/sizeof(paramdef_t), OPT_CONFIGPREFIX);
+  uint16_t in_port=0;
+  config_set_checkfunctions(opt_params, opt_checkParams,
+                            sizeof(opt_params)/sizeof(paramdef_t));
+  config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX);
+
   subframesSinceCaptureStart = 0;
   int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX]));
 
diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h
index 4812d82d916..3df350541f0 100644
--- a/openair2/UTIL/OSA/osa_defs.h
+++ b/openair2/UTIL/OSA/osa_defs.h
@@ -29,8 +29,8 @@
  * @ingroup security
 */
 
-#ifndef SECU_DEFS_H_
-#define SECU_DEFS_H_
+#ifndef __UTIL_OSA_OSA_DEFS__H__
+#define __UTIL_OSA_OSA_DEFS__H__
 
 #define EIA0_ALG_ID     0x00
 #define EIA1_128_ALG_ID 0x01
@@ -115,4 +115,4 @@ int stream_decrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **
 int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t *expected);
 #undef SECU_DEBUG
 
-#endif /* SECU_DEFS_H_ */
+#endif /* __UTIL_OSA_OSA_DEFS__H__ */
diff --git a/openair2/UTIL/OTG/traffic_config.h b/openair2/UTIL/OTG/traffic_config.h
index 2f47682706b..c0a64a34650 100644
--- a/openair2/UTIL/OTG/traffic_config.h
+++ b/openair2/UTIL/OTG/traffic_config.h
@@ -19,6 +19,9 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __UTIL_OTG_TRAFFIC_CONFIG__H__
+#define __UTIL_OTG_TRAFFIC_CONFIG__H__
+
 //IDT DISTRIBUTION PARAMETERS
 #define IDT_DIST GAUSSIAN
 #define IDT_MIN 2
@@ -40,3 +43,5 @@
 //SOCKET MODE
 #define DST_PORT 1234;
 #define DST_IP "127.0.0.1"
+
+#endif
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 47a3475063f..0aeabce0d2c 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -1691,11 +1691,11 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
 
 		// Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted
 		// with values coming from RRC.
-		uint16_t nRencryptionAlgorithms = 0;
-		uint16_t nRintegrityProtectionAlgorithms = 0;
-		uint8_t  SgNBSecurityKey[32] = { 0 };
-		int uEaggregateMaximumBitRateDownlink = 100000000;
-		int uEaggregateMaximumBitRateUplink = 100000000;
+		//uint16_t nRencryptionAlgorithms = 0;
+		//uint16_t nRintegrityProtectionAlgorithms = 0;
+		//uint8_t  SgNBSecurityKey[32] = { 0 };
+		//int uEaggregateMaximumBitRateDownlink = 100000000;
+		//int uEaggregateMaximumBitRateUplink = 100000000;
 		int e_rabs_admitted_tobeadded = 1;
 		int e_RAB_ID = 1;
 		long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index b7a9b705967..afaae1756d4 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -1772,8 +1772,8 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
 		  X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true);
 
   X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
-
-    if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
+  //X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
+    if (container->size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
       { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
 
     memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
@@ -1943,7 +1943,6 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
 	x2ap_eNB_instance_t                *instance_p;
 	x2ap_eNB_data_t                    *x2ap_eNB_data;
 	MessageDef                         *msg;
-	int                                ue_id;
 
 		  DevAssert (pdu != NULL);
 		  x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h
index c5217341c51..7082f5ac95b 100644
--- a/openair2/X2AP/x2ap_eNB_management_procedures.h
+++ b/openair2/X2AP/x2ap_eNB_management_procedures.h
@@ -26,8 +26,8 @@
  * \version 1.0
  */
 
-#ifndef X2AP_ENB_MANAGEMENT_PROCEDURES_H_
-#define X2AP_ENB_MANAGEMENT_PROCEDURES_H
+#ifndef __X2AP_ENB_MANAGEMENT_PROCEDURES__H__
+#define __X2AP_ENB_MANAGEMENT_PROCEDURES__H__
 
 void x2ap_eNB_prepare_internal_data(void);
 
@@ -51,4 +51,4 @@ struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
                                      int32_t assoc_id,
                                      uint16_t cnx_id);
 
-#endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */
+#endif /* __X2AP_ENB_MANAGEMENT_PROCEDURES__H__ */
diff --git a/openair3/M3AP/m3ap_MCE_generate_messages.h b/openair3/M3AP/m3ap_MCE_generate_messages.h
index 0884e8216e0..1a5733acc31 100644
--- a/openair3/M3AP/m3ap_MCE_generate_messages.h
+++ b/openair3/M3AP/m3ap_MCE_generate_messages.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
-#define M2AP_ENB_GENERATE_MESSAGES_H_
+#ifndef __M3AP_MCE_GENERATE_MESSAGES__H__
+#define __M3AP_MCE_GENERATE_MESSAGES__H__
 
 #include "m2ap_eNB_defs.h"
 #include "m2ap_common.h"
@@ -37,27 +37,8 @@ int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p,
 
 int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
 
-/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
-                                       uint32_t assoc_id,
-                                       M2AP_Cause_PR cause_type,
-                                       long cause_value,
-                                       long time_to_wait);*/
-
 int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
                         M2AP_Cause_PR cause_type,
                         long cause_value);
 
-//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
-//                                           m2ap_handover_req_t *m2ap_handover_req, int ue_id);
-//
-//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
-//                                               m2ap_handover_req_ack_t *m2ap_handover_req_ack);
-//
-//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
-//                                             m2ap_ue_context_release_t *m2ap_ue_context_release);
-//
-//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
-//                                          int m2_ue_id,
-//                                          m2ap_handover_cancel_cause_t cause);
-
-#endif /*  M2AP_ENB_GENERATE_MESSAGES_H_ */
+#endif /*  __M3AP_MCE_GENERATE_MESSAGES__H__ */
diff --git a/openair3/M3AP/m3ap_MCE_handler.h b/openair3/M3AP/m3ap_MCE_handler.h
index ce4997e80d7..09eca351b68 100644
--- a/openair3/M3AP/m3ap_MCE_handler.h
+++ b/openair3/M3AP/m3ap_MCE_handler.h
@@ -19,15 +19,15 @@
  *      contact@openairinterface.org
  */
 
-/*! \file m2ap_handler.h
- * \brief m2ap handler procedures for eNB
+/*! \file m3ap_handler.h
+ * \brief m3ap handler procedures for eNB
  * \author Javier Morgade <javier.morgade@ieee.org>
  * \date 2019
  * \version 0.1
  */
 
-#ifndef M2AP_MCE_HANDLERS_H_
-#define M2AP_MCE_HANDLERS_H_
+#ifndef __M3AP_MCE_HANDLER__H__
+#define __M3AP_MCE_HANDLER__H__
 
 #include "m2ap_MCE_defs.h"
 
@@ -40,4 +40,4 @@ int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre
                             const uint8_t * const data, const uint32_t data_length);
 
 
-#endif /* M2AP_MCE_HANDLERS_H_ */
+#endif /* __M3AP_MCE_HANDLER__H__ */
diff --git a/openair3/M3AP/m3ap_MCE_management_procedures.h b/openair3/M3AP/m3ap_MCE_management_procedures.h
index 2d18df8c26d..27e8c928a0f 100644
--- a/openair3/M3AP/m3ap_MCE_management_procedures.h
+++ b/openair3/M3AP/m3ap_MCE_management_procedures.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M3AP_MCE_MANAGEMENT_PROCEDURES_H_
-#define M3AP_MCE_MANAGEMENT_PROCEDURES_H
+#ifndef __M3AP_MCE_MANAGEMENT_PROCEDURES__H__
+#define __M3AP_MCE_MANAGEMENT_PROCEDURES__H__
 
 void m3ap_MCE_prepare_internal_data(void);
 
@@ -50,4 +50,4 @@ struct m3ap_MCE_data_s *m3ap_get_MCE(m3ap_MCE_instance_t *instance_p,
                                      int32_t assoc_id,
                                      uint16_t cnx_id);
 
-#endif /* M3AP_MCE_MANAGEMENT_PROCEDURES_H_ */
+#endif /* __M3AP_MCE_MANAGEMENT_PROCEDURES__H__ */
diff --git a/openair3/M3AP/m3ap_MME_generate_messages.h b/openair3/M3AP/m3ap_MME_generate_messages.h
index 1632dc807ac..146f58825a8 100644
--- a/openair3/M3AP/m3ap_MME_generate_messages.h
+++ b/openair3/M3AP/m3ap_MME_generate_messages.h
@@ -19,15 +19,15 @@
  *      contact@openairinterface.org
  */
 
-/*! \file m2ap_MCE_generate_messages.h
- * \brief m2ap procedures for MCE
+/*! \file m3ap_MCE_generate_messages.h
+ * \brief m3ap procedures for MCE
  * \author Javier Morgade <javier.morgade@ieee.org>
  * \date 2019
  * \version 0.1
  */
 
-#ifndef M2AP_MCE_GENERATE_MESSAGES_H_
-#define M2AP_MCE_GENERATE_MESSAGES_H_
+#ifndef M3AP_MCE_GENERATE_MESSAGES_H_
+#define M3AP_MCE_GENERATE_MESSAGES_H_
 
 #include "m2ap_MCE_defs.h"
 #include "m2ap_common.h"
diff --git a/openair3/M3AP/m3ap_MME_management_procedures.h b/openair3/M3AP/m3ap_MME_management_procedures.h
index e966ee1f17e..b21189b9157 100644
--- a/openair3/M3AP/m3ap_MME_management_procedures.h
+++ b/openair3/M3AP/m3ap_MME_management_procedures.h
@@ -26,8 +26,8 @@
  * \version 0.1
  */
 
-#ifndef M3AP_MME_MANAGEMENT_PROCEDURES_H_
-#define M3AP_MME_MANAGEMENT_PROCEDURES_H
+#ifndef __M3AP_MME_MANAGEMENT_PROCEDURES__H__
+#define __M3AP_MME_MANAGEMENT_PROCEDURES__H__
 
 void m3ap_MME_prepare_internal_data(void);
 
@@ -51,4 +51,4 @@ struct m3ap_MME_data_s *m3ap_get_MME(m3ap_MME_instance_t *instance_p,
                                      int32_t assoc_id,
                                      uint16_t cnx_id);
 
-#endif /* M3AP_MME_MANAGEMENT_PROCEDURES_H_ */
+#endif /* __M3AP_MME_MANAGEMENT_PROCEDURES__H__ */
diff --git a/openair3/MME_APP/enb_paramdef_mme.h b/openair3/MME_APP/enb_paramdef_mme.h
index 3d65036553b..127c1855e77 100644
--- a/openair3/MME_APP/enb_paramdef_mme.h
+++ b/openair3/MME_APP/enb_paramdef_mme.h
@@ -30,6 +30,9 @@
  * \warning
  */
 
+#ifndef __MME_APP_ENB_PARAMDEF_MME__H__
+#define __MME_APP_ENB_PARAMDEF_MME__H__
+
 #include "common/config/config_paramdesc.h"
 #include "RRC_paramsvalues.h"
 
@@ -172,3 +175,4 @@ typedef struct ccparams_MME_s {
              { .s5= {NULL }}						     \
 }
 
+#endif
diff --git a/openair3/MME_APP/mme_config.h b/openair3/MME_APP/mme_config.h
index 4371ad55f6f..2eb0a66e85c 100644
--- a/openair3/MME_APP/mme_config.h
+++ b/openair3/MME_APP/mme_config.h
@@ -26,8 +26,9 @@
   EMAIL   : javier.morgade@ieee.org
 */
 
-#ifndef MME_CONFIG_H_
-#define MME_CONFIG_H_
+#ifndef __MME_APP_MME_CONFIG__H__
+#define __MME_APP_MME_CONFIG__H__
+
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -48,5 +49,5 @@
 
 int RCconfig_MME(void);
 
-#endif /* MME_CONFIG_H_ */
+#endif /* __MME_APP_MME_CONFIG__H__ */
 /** @} */
diff --git a/openair3/NAS/COMMON/API/NETWORK/as_message.h b/openair3/NAS/COMMON/API/NETWORK/as_message.h
deleted file mode 100644
index 30810a325ea..00000000000
--- a/openair3/NAS/COMMON/API/NETWORK/as_message.h
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Copyright (c) 2015, EURECOM (www.eurecom.fr)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those
- * of the authors and should not be interpreted as representing official policies,
- * either expressed or implied, of the FreeBSD Project.
- */
-
-
-/*****************************************************************************
-
-Source      as_message.h
-
-Version     0.1
-
-Date        2012/10/18
-
-Product     NAS stack
-
-Subsystem   Application Programming Interface
-
-Author      Frederic Maurel
-
-Description Defines the messages supported by the Access Stratum sublayer
-        protocol (usually RRC and S1AP for E-UTRAN) and functions used
-        to encode and decode
-
-*****************************************************************************/
-#ifndef __AS_MESSAGE_H__
-#define __AS_MESSAGE_H__
-
-#include "commonDef.h"
-#include "networkDef.h"
-
-/****************************************************************************/
-/*********************  G L O B A L    C O N S T A N T S  *******************/
-/****************************************************************************/
-
-/*
- * --------------------------------------------------------------------------
- *              Access Stratum message types
- * --------------------------------------------------------------------------
- */
-#define AS_REQUEST  0x0100
-#define AS_RESPONSE 0x0200
-#define AS_INDICATION   0x0400
-#define AS_CONFIRM  0x0800
-
-/*
- * --------------------------------------------------------------------------
- *          Access Stratum message identifiers
- * --------------------------------------------------------------------------
- */
-
-/* Broadcast information */
-#define AS_BROADCAST_INFO       0x01
-#define AS_BROADCAST_INFO_IND       (AS_BROADCAST_INFO | AS_INDICATION)
-
-/* Cell information relevant for cell selection processing */
-#define AS_CELL_INFO            0x02
-#define AS_CELL_INFO_REQ        (AS_CELL_INFO | AS_REQUEST)
-#define AS_CELL_INFO_CNF        (AS_CELL_INFO | AS_CONFIRM)
-#define AS_CELL_INFO_IND        (AS_CELL_INFO | AS_INDICATION)
-
-/* Paging information */
-#define AS_PAGING           0x03
-#define AS_PAGING_REQ           (AS_PAGING | AS_REQUEST)
-#define AS_PAGING_IND           (AS_PAGING | AS_INDICATION)
-
-/* NAS signalling connection establishment */
-#define AS_NAS_ESTABLISH        0x04
-#define AS_NAS_ESTABLISH_REQ        (AS_NAS_ESTABLISH | AS_REQUEST)
-#define AS_NAS_ESTABLISH_IND        (AS_NAS_ESTABLISH | AS_INDICATION)
-#define AS_NAS_ESTABLISH_RSP        (AS_NAS_ESTABLISH | AS_RESPONSE)
-#define AS_NAS_ESTABLISH_CNF        (AS_NAS_ESTABLISH | AS_CONFIRM)
-
-/* NAS signalling connection release */
-#define AS_NAS_RELEASE          0x05
-#define AS_NAS_RELEASE_REQ      (AS_NAS_RELEASE | AS_REQUEST)
-#define AS_NAS_RELEASE_IND      (AS_NAS_RELEASE | AS_INDICATION)
-
-/* Uplink information transfer */
-#define AS_UL_INFO_TRANSFER     0x06
-#define AS_UL_INFO_TRANSFER_REQ     (AS_UL_INFO_TRANSFER | AS_REQUEST)
-#define AS_UL_INFO_TRANSFER_CNF     (AS_UL_INFO_TRANSFER | AS_CONFIRM)
-#define AS_UL_INFO_TRANSFER_IND     (AS_UL_INFO_TRANSFER | AS_INDICATION)
-
-/* Downlink information transfer */
-#define AS_DL_INFO_TRANSFER     0x07
-#define AS_DL_INFO_TRANSFER_REQ     (AS_DL_INFO_TRANSFER | AS_REQUEST)
-#define AS_DL_INFO_TRANSFER_CNF     (AS_DL_INFO_TRANSFER | AS_CONFIRM)
-#define AS_DL_INFO_TRANSFER_IND     (AS_DL_INFO_TRANSFER | AS_INDICATION)
-
-/* Radio Access Bearer establishment */
-#define AS_RAB_ESTABLISH        0x08
-#define AS_RAB_ESTABLISH_REQ        (AS_RAB_ESTABLISH | AS_REQUEST)
-#define AS_RAB_ESTABLISH_IND        (AS_RAB_ESTABLISH | AS_INDICATION)
-#define AS_RAB_ESTABLISH_RSP        (AS_RAB_ESTABLISH | AS_RESPONSE)
-#define AS_RAB_ESTABLISH_CNF        (AS_RAB_ESTABLISH | AS_CONFIRM)
-
-/* Radio Access Bearer release */
-#define AS_RAB_RELEASE          0x09
-#define AS_RAB_RELEASE_REQ      (AS_RAB_RELEASE | AS_REQUEST)
-#define AS_RAB_RELEASE_IND      (AS_RAB_RELEASE | AS_INDICATION)
-
-/* NAS Cause */
-#define EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED (8)
-#define EPS_SERVICES_NOT_ALLOWED                      (7)
-#define PLMN_NOT_ALLOWED                              (11)
-#define TRACKING_AREA_NOT_ALLOWED                     (12)
-#define ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA     (13)
-#define EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN         (14)
-#define NO_SUITABLE_CELLS_IN_TRACKING_AREA            (15)
-#define NETWORK_FAILURE                               (17)
-#define ESM_FAILURE                                   (19)
-
-typedef enum nas_cause_s {
-  NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
-  NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED                  = EPS_SERVICES_NOT_ALLOWED,
-  NAS_CAUSE_PLMN_NOT_ALLOWED                          = PLMN_NOT_ALLOWED,
-  NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED                 = TRACKING_AREA_NOT_ALLOWED,
-  NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA,
-  NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN     = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
-  NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA        = NO_SUITABLE_CELLS_IN_TRACKING_AREA,
-  NAS_CAUSE_NETWORK_FAILURE                           = NETWORK_FAILURE,
-  NAS_CAUSE_ESM_FAILURE                               = ESM_FAILURE
-} nas_cause_t;
-
-/*
- * --------------------------------------------------------------------------
- *          Access Stratum message global parameters
- * --------------------------------------------------------------------------
- */
-
-/* Error code */
-typedef enum nas_error_code_s {
-  AS_SUCCESS = 1, /* Success code, transaction is going on    */
-  AS_TERMINATED_NAS,  /* Transaction terminated by NAS        */
-  AS_TERMINATED_AS,   /* Transaction terminated by AS         */
-  AS_FAILURE      /* Failure code                 */
-} nas_error_code_t;
-
-/* Core network domain */
-typedef enum core_network_s {
-  AS_PS = 1,      /* Packet-Switched  */
-  AS_CS       /* Circuit-Switched */
-} core_network_t;
-
-/* SAE Temporary Mobile Subscriber Identity */
-typedef struct as_stmsi_s {
-  uint8_t MMEcode;    /* MME code that allocated the GUTI     */
-  uint32_t m_tmsi;    /* M-Temporary Mobile Subscriber Identity   */
-} as_stmsi_t;
-
-/* Dedicated NAS information */
-typedef struct as_nas_info_s {
-  uint32_t length;    /* Length of the NAS information data       */
-  Byte_t* data;   /* Dedicated NAS information data container */
-} as_nas_info_t;
-
-/* Radio Access Bearer identity */
-typedef uint8_t as_rab_id_t;
-
-/****************************************************************************/
-/************************  G L O B A L    T Y P E S  ************************/
-/****************************************************************************/
-
-/*
- * --------------------------------------------------------------------------
- *              Broadcast information
- * --------------------------------------------------------------------------
- */
-
-/*
- * AS->NAS - Broadcast information indication
- * AS may asynchronously report to NAS available PLMNs within specific
- * location area
- */
-typedef struct broadcast_info_ind_s {
-#define PLMN_LIST_MAX_SIZE  6
-  PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */
-  ci_t cellID;    /* Identity of the cell serving the listed PLMNs */
-  tac_t tac;      /* Code of the tracking area the cell belongs to */
-} broadcast_info_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *     Cell information relevant for cell selection processing
- * --------------------------------------------------------------------------
- */
-
-/* Radio access technologies supported by the network */
-#define AS_GSM              (1 << NET_ACCESS_GSM)
-#define AS_COMPACT          (1 << NET_ACCESS_COMPACT)
-#define AS_UTRAN            (1 << NET_ACCESS_UTRAN)
-#define AS_EGPRS            (1 << NET_ACCESS_EGPRS)
-#define AS_HSDPA            (1 << NET_ACCESS_HSDPA)
-#define AS_HSUPA            (1 << NET_ACCESS_HSUPA)
-#define AS_HSDUPA           (1 << NET_ACCESS_HSDUPA)
-#define AS_EUTRAN           (1 << NET_ACCESS_EUTRAN)
-
-/*
- * NAS->AS - Cell Information request
- * NAS request AS to search for a suitable cell belonging to the selected
- * PLMN to camp on.
- */
-typedef struct cell_info_req_s {
-  plmn_t plmnID;  /* Selected PLMN identity           */
-  Byte_t rat;     /* Bitmap - set of radio access technologies    */
-} cell_info_req_t;
-
-/*
- * AS->NAS - Cell Information confirm
- * AS search for a suitable cell and respond to NAS. If found, the cell
- * is selected to camp on.
- */
-typedef struct cell_info_cnf_s {
-  uint8_t errCode;    /* Error code                     */
-  ci_t cellID;    /* Identity of the cell serving the selected PLMN */
-  tac_t tac;      /* Code of the tracking area the cell belongs to  */
-  AcT_t rat;      /* Radio access technology supported by the cell  */
-  uint8_t rsrq;   /* Reference signal received quality         */
-  uint8_t rsrp;   /* Reference signal received power       */
-} cell_info_cnf_t;
-
-/*
- * AS->NAS - Cell Information indication
- * AS may change cell selection if a more suitable cell is found.
- */
-typedef struct cell_info_ind_s {
-  ci_t cellID;    /* Identity of the new serving cell      */
-  tac_t tac;      /* Code of the tracking area the cell belongs to */
-} cell_info_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *              Paging information
- * --------------------------------------------------------------------------
- */
-
-/* Paging cause */
-typedef enum paging_cause_s {
-  AS_CONNECTION_ESTABLISH,    /* Establish NAS signalling connection  */
-  AS_EPS_ATTACH,      /* Perform local detach and initiate EPS
-                 * attach procedure         */
-  AS_CS_FALLBACK      /* Inititate CS fallback procedure  */
-} paging_cause_t;
-
-/*
- * NAS->AS - Paging Information request
- * NAS requests the AS that NAS signalling messages or user data is pending
- * to be sent.
- */
-typedef struct paging_req_s {
-  as_stmsi_t s_tmsi;  /* UE identity                  */
-  uint8_t CN_domain;  /* Core network domain              */
-} paging_req_t;
-
-/*
- * AS->NAS - Paging Information indication
- * AS reports to the NAS that appropriate procedure has to be initiated.
- */
-typedef struct paging_ind_s {
-  paging_cause_t cause;  /* Paging cause                 */
-} paging_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *          NAS signalling connection establishment
- * --------------------------------------------------------------------------
- */
-
-/* Cause of RRC connection establishment */
-typedef enum as_cause_s {
-  AS_CAUSE_UNKNOWN    = 0,
-  AS_CAUSE_EMERGENCY  = NET_ESTABLISH_CAUSE_EMERGENCY,
-  AS_CAUSE_HIGH_PRIO  = NET_ESTABLISH_CAUSE_HIGH_PRIO,
-  AS_CAUSE_MT_ACCESS  = NET_ESTABLISH_CAUSE_MT_ACCESS,
-  AS_CAUSE_MO_SIGNAL  = NET_ESTABLISH_CAUSE_MO_SIGNAL,
-  AS_CAUSE_MO_DATA    = NET_ESTABLISH_CAUSE_MO_DATA,
-  AS_CAUSE_V1020      = NET_ESTABLISH_CAUSE_V1020
-} as_cause_t;
-
-/* Type of the call associated to the RRC connection establishment */
-typedef enum as_call_type_s {
-  AS_TYPE_ORIGINATING_SIGNAL  = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL,
-  AS_TYPE_EMERGENCY_CALLS     = NET_ESTABLISH_TYPE_EMERGENCY_CALLS,
-  AS_TYPE_ORIGINATING_CALLS   = NET_ESTABLISH_TYPE_ORIGINATING_CALLS,
-  AS_TYPE_TERMINATING_CALLS   = NET_ESTABLISH_TYPE_TERMINATING_CALLS,
-  AS_TYPE_MO_CS_FALLBACK      = NET_ESTABLISH_TYPE_MO_CS_FALLBACK
-} as_call_type_t;
-
-/*
- * NAS->AS - NAS signalling connection establishment request
- * NAS requests the AS to perform the RRC connection establishment procedure
- * to transfer initial NAS message to the network while UE is in IDLE mode.
- */
-typedef struct nas_establish_req_s {
-  as_cause_t      cause;          /* RRC connection establishment cause   */
-  as_call_type_t  type;           /* RRC associated call type             */
-  as_stmsi_t      s_tmsi;         /* UE identity                          */
-  plmn_t          plmnID;         /* Selected PLMN identity               */
-  as_nas_info_t   initialNasMsg;  /* Initial NAS message to transfer      */
-} nas_establish_req_t;
-
-/*
- * AS->NAS - NAS signalling connection establishment indication
- * AS transfers the initial NAS message to the NAS.
- */
-typedef struct nas_establish_ind_s {
-  uint32_t      UEid;          /* UE lower layer identifier               */
-  tac_t         tac;           /* Code of the tracking area the initiating
-                                  * UE belongs to                           */
-  as_cause_t    asCause;       /* Establishment cause                     */
-  as_nas_info_t initialNasMsg; /* Initial NAS message to transfer         */
-} nas_establish_ind_t;
-
-/*
- * NAS->AS - NAS signalling connection establishment response
- * NAS responds to the AS that initial answer message has to be provided to
- * the UE.
- */
-typedef struct nas_establish_rsp_s {
-  uint32_t         UEid;         /* UE lower layer identifier   */
-  as_stmsi_t       s_tmsi;       /* UE identity                 */
-  nas_error_code_t errCode;      /* Transaction status          */
-  as_nas_info_t    nasMsg;       /* NAS message to transfer     */
-  uint32_t         nas_ul_count; /* UL NAS COUNT                */
-  uint16_t         selected_encryption_algorithm;
-  uint16_t         selected_integrity_algorithm;
-} nas_establish_rsp_t;
-
-/*
- * AS->NAS - NAS signalling connection establishment confirm
- * AS transfers the initial answer message to the NAS.
- */
-typedef struct nas_establish_cnf_s {
-  uint32_t         UEid;            /* UE lower layer identifier   */
-  nas_error_code_t errCode;         /* Transaction status          */
-  as_nas_info_t    nasMsg;          /* NAS message to transfer     */
-  uint32_t         ul_nas_count;
-  uint16_t         selected_encryption_algorithm;
-  uint16_t         selected_integrity_algorithm;
-} nas_establish_cnf_t;
-
-/*
- * --------------------------------------------------------------------------
- *          NAS signalling connection release
- * --------------------------------------------------------------------------
- */
-
-/* Release cause */
-typedef enum release_cause_s {
-  AS_AUTHENTICATION_FAILURE = 1,  /* Authentication procedure failed   */
-  AS_DETACH                       /* Detach requested                  */
-} release_cause_t;
-
-/*
- * NAS->AS - NAS signalling connection release request
- * NAS requests the termination of the connection with the UE.
- */
-typedef struct nas_release_req_s {
-  uint32_t UEid;          /* UE lower layer identifier    */
-  as_stmsi_t s_tmsi;      /* UE identity                  */
-  release_cause_t cause;  /* Release cause                */
-} nas_release_req_t;
-
-/*
- * AS->NAS - NAS signalling connection release indication
- * AS reports that connection has been terminated by the network.
- */
-typedef struct nas_release_ind_s {
-  release_cause_t cause;      /* Release cause            */
-} nas_release_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *              NAS information transfer
- * --------------------------------------------------------------------------
- */
-
-/*
- * NAS->AS - Uplink data transfer request
- * NAS requests the AS to transfer uplink information to the NAS that
- * operates at the network side.
- */
-typedef struct ul_info_transfer_req_s {
-  uint32_t UEid;      /* UE lower layer identifier        */
-  as_stmsi_t s_tmsi;      /* UE identity              */
-  as_nas_info_t nasMsg;   /* Uplink NAS message           */
-} ul_info_transfer_req_t;
-
-/*
- * AS->NAS - Uplink data transfer confirm
- * AS immediately notifies the NAS whether uplink information has been
- * successfully sent to the network or not.
- */
-typedef struct ul_info_transfer_cnf_s {
-  uint32_t         UEid;      /* UE lower layer identifier        */
-  nas_error_code_t errCode;   /* Transaction status               */
-} ul_info_transfer_cnf_t;
-
-/*
- * AS->NAS - Uplink data transfer indication
- * AS delivers the uplink information message to the NAS that operates
- * at the network side.
- */
-typedef struct ul_info_transfer_ind_s {
-  uint32_t UEid;          /* UE lower layer identifier        */
-  as_nas_info_t nasMsg;   /* Uplink NAS message           */
-} ul_info_transfer_ind_t;
-
-/*
- * NAS->AS - Downlink data transfer request
- * NAS requests the AS to transfer downlink information to the NAS that
- * operates at the UE side.
- */
-typedef ul_info_transfer_req_t dl_info_transfer_req_t;
-
-/*
- * AS->NAS - Downlink data transfer confirm
- * AS immediately notifies the NAS whether downlink information has been
- * successfully sent to the network or not.
- */
-typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t;
-
-/*
- * AS->NAS - Downlink data transfer indication
- * AS delivers the downlink information message to the NAS that operates
- * at the UE side.
- */
-typedef ul_info_transfer_ind_t dl_info_transfer_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *          Radio Access Bearer establishment
- * --------------------------------------------------------------------------
- */
-
-/* TODO: Quality of Service parameters */
-typedef struct {} as_qos_t;
-
-/*
- * NAS->AS - Radio access bearer establishment request
- * NAS requests the AS to allocate transmission resources to radio access
- * bearer initialized at the network side.
- */
-typedef struct rab_establish_req_s {
-  as_stmsi_t s_tmsi;      /* UE identity                      */
-  as_rab_id_t rabID;      /* Radio access bearer identity     */
-  as_qos_t QoS;           /* Requested Quality of Service     */
-} rab_establish_req_t;
-
-/*
- * AS->NAS - Radio access bearer establishment indication
- * AS notifies the NAS that specific radio access bearer has to be setup.
- */
-typedef struct rab_establish_ind_s {
-  as_rab_id_t rabID;      /* Radio access bearer identity     */
-} rab_establish_ind_t;
-
-/*
- * NAS->AS - Radio access bearer establishment response
- * NAS responds to AS whether the specified radio access bearer has been
- * successfully setup or not.
- */
-typedef struct rab_establish_rsp_s {
-  as_stmsi_t       s_tmsi;        /* UE identity                      */
-  as_rab_id_t      rabID;         /* Radio access bearer identity     */
-  nas_error_code_t errCode;       /* Transaction status               */
-} rab_establish_rsp_t;
-
-/*
- * AS->NAS - Radio access bearer establishment confirm
- * AS notifies NAS whether the specified radio access bearer has been
- * successfully setup at the UE side or not.
- */
-typedef struct rab_establish_cnf_s {
-  as_rab_id_t rabID;          /* Radio access bearer identity     */
-  nas_error_code_t errCode;   /* Transaction status               */
-} rab_establish_cnf_t;
-
-/*
- * --------------------------------------------------------------------------
- *              Radio Access Bearer release
- * --------------------------------------------------------------------------
- */
-
-/*
- * NAS->AS - Radio access bearer release request
- * NAS requests the AS to release transmission resources previously allocated
- * to specific radio access bearer at the network side.
- */
-typedef struct rab_release_req_s {
-  as_stmsi_t s_tmsi;      /* UE identity                      */
-  as_rab_id_t rabID;      /* Radio access bearer identity     */
-} rab_release_req_t;
-
-/*
- * AS->NAS - Radio access bearer release indication
- * AS notifies NAS that specific radio access bearer has been released.
- */
-typedef struct rab_release_ind_s {
-  as_rab_id_t rabID;      /* Radio access bearer identity     */
-} rab_release_ind_t;
-
-/*
- * --------------------------------------------------------------------------
- *  Structure of the AS messages handled by the network sublayer
- * --------------------------------------------------------------------------
- */
-typedef struct as_message_s {
-  uint16_t msgID;
-  union {
-    broadcast_info_ind_t broadcast_info_ind;
-    cell_info_req_t cell_info_req;
-    cell_info_cnf_t cell_info_cnf;
-    cell_info_ind_t cell_info_ind;
-    paging_req_t paging_req;
-    paging_ind_t paging_ind;
-    nas_establish_req_t nas_establish_req;
-    nas_establish_ind_t nas_establish_ind;
-    nas_establish_rsp_t nas_establish_rsp;
-    nas_establish_cnf_t nas_establish_cnf;
-    nas_release_req_t nas_release_req;
-    nas_release_ind_t nas_release_ind;
-    ul_info_transfer_req_t ul_info_transfer_req;
-    ul_info_transfer_cnf_t ul_info_transfer_cnf;
-    ul_info_transfer_ind_t ul_info_transfer_ind;
-    dl_info_transfer_req_t dl_info_transfer_req;
-    dl_info_transfer_cnf_t dl_info_transfer_cnf;
-    dl_info_transfer_ind_t dl_info_transfer_ind;
-    rab_establish_req_t rab_establish_req;
-    rab_establish_ind_t rab_establish_ind;
-    rab_establish_rsp_t rab_establish_rsp;
-    rab_establish_cnf_t rab_establish_cnf;
-    rab_release_req_t rab_release_req;
-    rab_release_ind_t rab_release_ind;
-  } __attribute__((__packed__)) msg;
-} as_message_t;
-
-/****************************************************************************/
-/********************  G L O B A L    V A R I A B L E S  ********************/
-/****************************************************************************/
-
-/****************************************************************************/
-/******************  E X P O R T E D    F U N C T I O N S  ******************/
-/****************************************************************************/
-
-int as_message_decode(const char* buffer, as_message_t* msg, int length);
-
-int as_message_encode(char* buffer, as_message_t* msg, int length);
-
-/* Implemented in the network_api.c body file */
-int as_message_send(as_message_t* as_msg);
-
-#endif /* __AS_MESSAGE_H__*/
diff --git a/openair3/NAS/COMMON/UTIL/socket.c b/openair3/NAS/COMMON/UTIL/socket.c
index 25876c3e6ff..53a6ec8823d 100644
--- a/openair3/NAS/COMMON/UTIL/socket.c
+++ b/openair3/NAS/COMMON/UTIL/socket.c
@@ -107,7 +107,7 @@ void* socket_udp_open(int type, const char* host, const char* port)
 {
   struct addrinfo socket_info; /* endpoint information    */
   struct addrinfo *socket_addr, *sp; /* endpoint address    */
-  int sfd; /* socket file descriptor  */
+  int sfd=-1; /* socket file descriptor  */
 
   /*
    * Parameters sanity check
diff --git a/openair3/NAS/COMMON/UTIL/socket.h b/openair3/NAS/COMMON/UTIL/socket.h
index 033046d98c0..58bc6b85276 100644
--- a/openair3/NAS/COMMON/UTIL/socket.h
+++ b/openair3/NAS/COMMON/UTIL/socket.h
@@ -35,8 +35,8 @@ Author    Frederic Maurel
 Description Implements TCP socket handlers
 
 *****************************************************************************/
-#ifndef __SOCKET_H__
-#define __SOCKET_H__
+#ifndef __NAS_COMMON_UTIL_SOCKET__H__
+#define __NAS_COMMON_UTIL_SOCKET__H__
 
 #include <sys/types.h>
 
@@ -71,4 +71,4 @@ ssize_t socket_send(const void* id, const char* buffer, size_t length);
 
 void socket_close(void* id);
 
-#endif /* __SOCKET_H__*/
+#endif /* __NAS_COMMON_UTIL_SOCKET__H__ */
diff --git a/openair3/NAS/COMMON/commonDef.h b/openair3/NAS/COMMON/commonDef.h
deleted file mode 100644
index e9f769db555..00000000000
--- a/openair3/NAS/COMMON/commonDef.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2015, EURECOM (www.eurecom.fr)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those
- * of the authors and should not be interpreted as representing official policies,
- * either expressed or implied, of the FreeBSD Project.
- */
-/*
-
-Source      commonDef.h
-
-Version     0.1
-
-Date        2012/02/27
-
-Product     NAS stack
-
-Subsystem   include
-
-Author      Frederic Maurel
-
-Description Contains global common definitions
-
-*****************************************************************************/
-#ifndef __COMMONDEF_H__
-#define __COMMONDEF_H__
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-
-typedef signed char        boolean_t;
-
-#if !defined(TRUE)
-#define TRUE               (boolean_t)0x01
-#endif
-
-#if !defined(FALSE)
-#define FALSE              (boolean_t)0x00
-#endif
-
-#define BOOL_NOT(b) (b^TRUE)
-
-#define NAS_UE_ID_FMT "0x%06x"
-
-/****************************************************************************/
-/*********************  G L O B A L    C O N S T A N T S  *******************/
-/****************************************************************************/
-
-#define RETURNok        (0)
-#define RETURNerror     (-1)
-
-/*
- * Name of the environment variable which defines the default directory
- * where the NAS application is executed and where are located files
- * where non-volatile data are stored
- */
-#define DEFAULT_NAS_PATH    "PWD"
-
-/****************************************************************************/
-/************************  G L O B A L    T Y P E S  ************************/
-/****************************************************************************/
-
-/*
------------------------------------------------------------------------------
-            Standard data type definitions
------------------------------------------------------------------------------
-*/
-typedef int8_t      SByte_t;    /* 8 bit  signed integer     */
-typedef uint8_t     Byte_t;     /* 8 bit unsigned integer   */
-
-
-/*
------------------------------------------------------------------------------
-            Common NAS data type definitions
------------------------------------------------------------------------------
-*/
-
-typedef uint8_t     Stat_t;     /* Registration status  */
-typedef uint16_t    lac_t;      /* Location Area Code   */
-typedef uint8_t     rac_t;      /* Routing Area Code    */
-typedef uint16_t    tac_t;      /* Tracking Area Code   */
-typedef uint32_t    ci_t;       /* Cell Identifier  */
-typedef uint8_t     AcT_t;      /* Access Technology    */
-
-/*
- * International Mobile Subscriber Identity
- */
-typedef struct {
-  Byte_t length;
-  union {
-    struct {
-      Byte_t digit2:4;
-      Byte_t digit1:4;
-      Byte_t digit4:4;
-      Byte_t digit3:4;
-      Byte_t digit6:4;
-      Byte_t digit5:4;
-      Byte_t digit8:4;
-      Byte_t digit7:4;
-      Byte_t digit10:4;
-      Byte_t digit9:4;
-      Byte_t digit12:4;
-      Byte_t digit11:4;
-      Byte_t digit14:4;
-      Byte_t digit13:4;
-#define EVEN_PARITY 0
-#define ODD_PARITY  1
-      Byte_t parity:4;
-      Byte_t digit15:4;
-    } num;
-#define IMSI_SIZE   8
-    Byte_t value[IMSI_SIZE];
-  } u;
-} imsi_t;
-
-#define NAS_IMSI2STR(iMsI_t_PtR,iMsI_sTr, MaXlEn) \
-        {\
-          int l_offset = 0;\
-          int l_ret    = 0;\
-          l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u",\
-	    		  iMsI_t_PtR->u.num.digit1, iMsI_t_PtR->u.num.digit2,\
-	    		  iMsI_t_PtR->u.num.digit3, iMsI_t_PtR->u.num.digit4,\
-	    		  iMsI_t_PtR->u.num.digit5);\
-	      if ((iMsI_t_PtR->u.num.digit6 != 0xf)  && (l_ret > 0)) {\
-	    	l_offset += l_ret;\
-	    	l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset,  "%u", iMsI_t_PtR->u.num.digit6);\
-	      }\
-	      if (l_ret > 0) {\
-	    	l_offset += l_ret;\
-	    	l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u%u%u%u",\
-	    		  iMsI_t_PtR->u.num.digit7, iMsI_t_PtR->u.num.digit8,\
-	    		  iMsI_t_PtR->u.num.digit9, iMsI_t_PtR->u.num.digit10,\
-	    		  iMsI_t_PtR->u.num.digit11, iMsI_t_PtR->u.num.digit12,\
-	    		  iMsI_t_PtR->u.num.digit13, iMsI_t_PtR->u.num.digit14);\
-	      }\
-	      if ((iMsI_t_PtR->u.num.digit15 != 0xf)   && (l_ret > 0)) {\
-	    	l_offset += l_ret;\
-	    	l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit15);\
-	      }\
-	    }
-
-/*
- * Mobile subscriber dialing number
- */
-typedef struct {
-  Byte_t ext:1;
-  /* Type Of Number           */
-#define MSISDN_TON_UNKNOWKN     0b000
-#define MSISDN_TON_INTERNATIONAL    0b001
-#define MSISDN_TON_NATIONAL     0b010
-#define MSISDN_TON_NETWORK      0b011
-#define MSISDN_TON_SUBCRIBER        0b100
-#define MSISDN_TON_ABBREVIATED      0b110
-#define MSISDN_TON_RESERVED     0b111
-  Byte_t ton:3;
-  /* Numbering Plan Identification    */
-#define MSISDN_NPI_UNKNOWN      0b0000
-#define MSISDN_NPI_ISDN_TELEPHONY   0b0001
-#define MSISDN_NPI_GENERIC      0b0010
-#define MSISDN_NPI_DATA         0b0011
-#define MSISDN_NPI_TELEX        0b0100
-#define MSISDN_NPI_MARITIME_MOBILE  0b0101
-#define MSISDN_NPI_LAND_MOBILE      0b0110
-#define MSISDN_NPI_ISDN_MOBILE      0b0111
-#define MSISDN_NPI_PRIVATE      0b1110
-#define MSISDN_NPI_RESERVED     0b1111
-  Byte_t npi:4;
-  /* Dialing Number           */
-  struct {
-    Byte_t lsb:4;
-    Byte_t msb:4;
-#define MSISDN_DIGIT_SIZE   10
-  } digit[MSISDN_DIGIT_SIZE];
-} msisdn_t;
-
-/*
- * International Mobile Equipment Identity
- */
-typedef imsi_t imei_t;
-
-/*
- * Public Land Mobile Network identifier
- * PLMN = BCD encoding (Mobile Country Code + Mobile Network Code)
- */
-typedef struct {
-  Byte_t MCCdigit2:4;
-  Byte_t MCCdigit1:4;
-  Byte_t MNCdigit3:4;
-  Byte_t MCCdigit3:4;
-  Byte_t MNCdigit2:4;
-  Byte_t MNCdigit1:4;
-} plmn_t;
-
-/*
- * Location Area Identification
- */
-typedef struct {
-  plmn_t plmn;    /* <MCC> + <MNC>    */
-  lac_t lac;      /* Location Area Code   */
-} lai_t;
-
-/*
- * GPRS Routing Area Identification
- */
-typedef struct {
-  plmn_t plmn;    /* <MCC> + <MNC>    */
-  lac_t lac;      /* Location Area Code   */
-  rac_t rac;      /* Routing Area Code    */
-} RAI_t;
-
-/*
- * EPS Tracking Area Identification
- */
-typedef struct {
-  plmn_t plmn;    /* <MCC> + <MNC>    */
-  tac_t tac;      /* Tracking Area Code   */
-} tai_t;
-
-/*
- * EPS Globally Unique MME Identity
- */
-typedef struct {
-  plmn_t plmn;    /* <MCC> + <MNC>    */
-  uint16_t MMEgid;    /* MME group identifier */
-  uint8_t MMEcode;    /* MME code     */
-} gummei_t;
-
-/*
- * EPS Globally Unique Temporary UE Identity
- */
-typedef struct {
-  gummei_t gummei;    /* Globally Unique MME Identity         */
-  uint32_t m_tmsi;    /* M-Temporary Mobile Subscriber Identity   */
-} GUTI_t;
-#define GUTI2STR(GuTi_PtR, GuTi_StR, MaXlEn) \
-        {\
-          int l_offset = 0;\
-          int l_ret    = 0;\
-          l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u.",\
-	    		  GuTi_PtR->gummei.plmn.MCCdigit3 * 100 +\
-                  GuTi_PtR->gummei.plmn.MCCdigit2 * 10 +\
-                  GuTi_PtR->gummei.plmn.MCCdigit1);\
-          if (l_ret > 0) {\
-        	l_offset += l_ret;\
-          }  else {\
-        	l_offset = MaXlEn;\
-          }\
-          if (GuTi_PtR->gummei.plmn.MNCdigit1 != 0xf) {\
-              l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u|%04x|%02x|%08x",\
-    	    		  GuTi_PtR->gummei.plmn.MNCdigit3 * 100 +\
-                      GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
-                      GuTi_PtR->gummei.plmn.MNCdigit1,\
-                      GuTi_PtR->gummei.MMEgid,\
-                      GuTi_PtR->gummei.MMEcode,\
-                      GuTi_PtR->m_tmsi);\
-          } else {\
-              l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%02u|%04x|%02x|%08x",\
-                      GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
-                      GuTi_PtR->gummei.plmn.MNCdigit1,\
-                      GuTi_PtR->gummei.MMEgid,\
-                      GuTi_PtR->gummei.MMEcode,\
-                      GuTi_PtR->m_tmsi);\
-          }\
-	    }
-
-
-
-
-/* Checks PLMN validity */
-#define PLMN_IS_VALID(plmn) (((plmn).MCCdigit1 &    \
-                              (plmn).MCCdigit2 &    \
-                              (plmn).MCCdigit3) != 0x0F)
-
-/* Checks TAC validity */
-#define TAC_IS_VALID(tac)   (((tac) != 0x0000) && ((tac) != 0xFFF0))
-
-/* Checks TAI validity */
-#define TAI_IS_VALID(tai)   (PLMN_IS_VALID((tai).plmn) &&   \
-                             TAC_IS_VALID((tai).tac))
-/*
- * A list of PLMNs
- */
-#define PLMN_LIST_T(SIZE) struct {Byte_t n_plmns; plmn_t plmn[SIZE];}
-
-/*
- * A list of TACs
- */
-#define TAC_LIST_T(SIZE) struct {Byte_t n_tacs; TAC_t tac[SIZE];}
-
-/*
- * A list of TAIs
- */
-#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];}
-
-typedef enum eps_protocol_discriminator_e {
-  /* Protocol discriminator identifier for EPS Mobility Management */
-  EPS_MOBILITY_MANAGEMENT_MESSAGE =   0x7,
-
-  /* Protocol discriminator identifier for EPS Session Management */
-  EPS_SESSION_MANAGEMENT_MESSAGE =    0x2,
-} eps_protocol_discriminator_t;
-
-/****************************************************************************/
-/********************  G L O B A L    V A R I A B L E S  ********************/
-/****************************************************************************/
-
-/****************************************************************************/
-/******************  E X P O R T E D    F U N C T I O N S  ******************/
-/****************************************************************************/
-
-#endif /* __COMMONDEF_H__*/
diff --git a/openair3/NAS/COMMON/networkDef.h b/openair3/NAS/COMMON/networkDef.h
deleted file mode 100644
index 5390eac2f0b..00000000000
--- a/openair3/NAS/COMMON/networkDef.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (c) 2015, EURECOM (www.eurecom.fr)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those
- * of the authors and should not be interpreted as representing official policies,
- * either expressed or implied, of the FreeBSD Project.
- */
-
-/*****************************************************************************
-
-Source      networkDef.h
-
-Version     0.1
-
-Date        2012/09/21
-
-Product     NAS stack
-
-Subsystem   include
-
-Author      Frederic Maurel
-
-Description Contains network's global definitions
-
-*****************************************************************************/
-#ifndef __NETWORKDEF_H__
-#define __NETWORKDEF_H__
-
-/****************************************************************************/
-/*********************  G L O B A L    C O N S T A N T S  *******************/
-/****************************************************************************/
-
-/*
- * ----------------------
- * Network selection mode
- * ----------------------
- */
-#define NET_PLMN_AUTO           0
-#define NET_PLMN_MANUAL         1
-
-/*
- * ---------------------------
- * Network registration status
- * ---------------------------
- */
-/* not registered, not currently searching an operator to register to */
-#define NET_REG_STATE_OFF       0
-/* registered, home network                       */
-#define NET_REG_STATE_HN        1
-/* not registered, currently trying to attach or searching an operator
- * to register to                         */
-#define NET_REG_STATE_ON        2
-/* registration denied                        */
-#define NET_REG_STATE_DENIED        3
-/* unknown (e.g. out of GERAN/UTRAN/E-UTRAN coverage)         */
-#define NET_REG_STATE_UNKNOWN       4
-/* registered, roaming                        */
-#define NET_REG_STATE_ROAMING       5
-/* registered for "SMS only", home network                */
-#define NET_REG_STATE_SMS_HN        6
-/* registered, for "SMS only", roaming                */
-#define NET_REG_STATE_SMS_ROAMING   7
-/* attached for emergency bearer services only (applicable to UTRAN)  */
-#define NET_REG_STATE_EMERGENCY     8
-
-/*
- * ------------------------------------
- * Network access technology indicators
- * ------------------------------------
- */
-#define NET_ACCESS_UNAVAILABLE  (-1)    /* Not available        */
-#define NET_ACCESS_GSM      0   /* GSM              */
-#define NET_ACCESS_COMPACT  1   /* GSM Compact          */
-#define NET_ACCESS_UTRAN    2   /* UTRAN            */
-#define NET_ACCESS_EGPRS    3   /* GSM w/EGPRS          */
-#define NET_ACCESS_HSDPA    4   /* UTRAN w/HSDPA        */
-#define NET_ACCESS_HSUPA    5   /* UTRAN w/HSUPA        */
-#define NET_ACCESS_HSDUPA   6   /* UTRAN w/HSDPA and HSUPA  */
-#define NET_ACCESS_EUTRAN   7   /* E-UTRAN          */
-
-/*
- * ---------------------------------------
- * Network operator representation formats
- * ---------------------------------------
- */
-#define NET_FORMAT_LONG     0   /* long format alphanumeric */
-#define NET_FORMAT_SHORT    1   /* short format alphanumeric    */
-#define NET_FORMAT_NUM      2   /* numeric format       */
-
-#define NET_FORMAT_MAX_SIZE NET_FORMAT_LONG_SIZE
-
-/*
- * -----------------------------
- * Network operator availability
- * -----------------------------
- */
-#define NET_OPER_UNKNOWN    0   /* unknown operator     */
-#define NET_OPER_AVAILABLE  1   /* available operator       */
-#define NET_OPER_CURRENT    2   /* currently selected operator  */
-#define NET_OPER_FORBIDDEN  3   /* forbidden operator       */
-
-/*
- * --------------------------------------
- * Network connection establishment cause
- * --------------------------------------
- */
-#define NET_ESTABLISH_CAUSE_EMERGENCY       0x01
-#define NET_ESTABLISH_CAUSE_HIGH_PRIO       0x02
-#define NET_ESTABLISH_CAUSE_MT_ACCESS       0x03
-#define NET_ESTABLISH_CAUSE_MO_SIGNAL       0x04
-#define NET_ESTABLISH_CAUSE_MO_DATA     0x05
-#define NET_ESTABLISH_CAUSE_V1020       0x06
-
-/*
- * --------------------------------------
- * Network connection establishment type
- * --------------------------------------
- */
-#define NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL   0x10
-#define NET_ESTABLISH_TYPE_EMERGENCY_CALLS  0x20
-#define NET_ESTABLISH_TYPE_ORIGINATING_CALLS    0x30
-#define NET_ESTABLISH_TYPE_TERMINATING_CALLS    0x40
-#define NET_ESTABLISH_TYPE_MO_CS_FALLBACK   0x50
-
-/*
- * -------------------
- * PDN connection type
- * -------------------
- */
-#define NET_PDN_TYPE_IPV4   (0 + 1)
-#define NET_PDN_TYPE_IPV6   (1 + 1)
-#define NET_PDN_TYPE_IPV4V6 (2 + 1)
-
-/****************************************************************************/
-/************************  G L O B A L    T Y P E S  ************************/
-/****************************************************************************/
-
-/*
- * ---------------------
- * PDN connection status
- * ---------------------
- */
-typedef enum {
-  /* MT = The Mobile Terminal, NW = The Network               */
-  NET_PDN_MT_DEFAULT_ACT = 1, /* MT has activated a PDN connection        */
-  NET_PDN_NW_DEFAULT_DEACT,   /* NW has deactivated a PDN connection      */
-  NET_PDN_MT_DEFAULT_DEACT,   /* MT has deactivated a PDN connection      */
-  NET_PDN_NW_DEDICATED_ACT,   /* NW has activated an EPS bearer context   */
-  NET_PDN_MT_DEDICATED_ACT,   /* MT has activated an EPS bearer context   */
-  NET_PDN_NW_DEDICATED_DEACT, /* NW has deactivated an EPS bearer context */
-  NET_PDN_MT_DEDICATED_DEACT, /* MT has deactivated an EPS bearer context */
-} network_pdn_state_t;
-
-/*
- * ---------------------------
- * Network operator identifier
- * ---------------------------
- */
-typedef struct {
-#define NET_FORMAT_LONG_SIZE    16  /* Long alphanumeric format     */
-#define NET_FORMAT_SHORT_SIZE   8   /* Short alphanumeric format        */
-#define NET_FORMAT_NUM_SIZE 6   /* Numeric format (PLMN identifier  */
-  union {
-    unsigned char alpha_long[NET_FORMAT_LONG_SIZE+1];
-    unsigned char alpha_short[NET_FORMAT_SHORT_SIZE+1];
-    unsigned char num[NET_FORMAT_NUM_SIZE+1];
-  } id;
-} network_plmn_t;
-
-/*
- * -------------------------------
- * EPS bearer level QoS parameters
- * -------------------------------
- */
-typedef struct {
-  int gbrUL;      /* Guaranteed Bit Rate for uplink   */
-  int gbrDL;      /* Guaranteed Bit Rate for downlink */
-  int mbrUL;      /* Maximum Bit Rate for uplink      */
-  int mbrDL;      /* Maximum Bit Rate for downlink    */
-  int qci;        /* QoS Class Identifier         */
-} network_qos_t;
-
-/*
- * -----------------------------
- * IPv4 packet filter parameters
- * -----------------------------
- */
-typedef struct {
-  unsigned char protocol; /* Protocol identifier      */
-  unsigned char tos;      /* Type of service      */
-#define NET_PACKET_FILTER_IPV4_ADDR_SIZE    4
-  unsigned char addr[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
-  unsigned char mask[NET_PACKET_FILTER_IPV4_ADDR_SIZE];
-} network_ipv4_data_t;
-
-/*
- * -----------------------------
- * IPv6 packet filter parameters
- * -----------------------------
- */
-typedef struct {
-  unsigned char nh;       /* Next header type     */
-  unsigned char tf;       /* Traffic class        */
-#define NET_PACKET_FILTER_IPV6_ADDR_SIZE    16
-  unsigned char addr[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
-  unsigned char mask[NET_PACKET_FILTER_IPV6_ADDR_SIZE];
-  unsigned int ipsec;     /* IPSec security parameter index */
-  unsigned int fl;        /* Flow label             */
-} network_ipv6_data_t;
-
-/*
- * -------------
- * Packet Filter
- * -------------
- */
-typedef struct {
-  unsigned char id;       /* Packet filter identifier */
-#define NET_PACKET_FILTER_DOWNLINK  0x01
-#define NET_PACKET_FILTER_UPLINK    0x02
-#define NET_PACKET_FILTER_BIDIR     0x03
-  unsigned char dir;      /* Packet filter direction  */
-  unsigned char precedence;   /* Evaluation precedence    */
-  union {
-    network_ipv4_data_t ipv4;
-    network_ipv6_data_t ipv6;
-  } data;
-  unsigned short lport;   /* Local (UE) port number   */
-  unsigned short rport;   /* Remote (network) port number */
-} network_pkf_t;
-
-/*
- * ---------------------
- * Traffic Flow Template
- * ---------------------
- */
-typedef struct {
-  int n_pkfs;
-#define NET_PACKET_FILTER_MAX   16
-  network_pkf_t* pkf[NET_PACKET_FILTER_MAX];
-} network_tft_t;
-
-/****************************************************************************/
-/********************  G L O B A L    V A R I A B L E S  ********************/
-/****************************************************************************/
-
-/****************************************************************************/
-/******************  E X P O R T E D    F U N C T I O N S  ******************/
-/****************************************************************************/
-
-#endif /* __NETWORKDEF_H__*/
diff --git a/openair3/NAS/TEST/USER/user_parser.h b/openair3/NAS/TEST/USER/user_parser.h
index d1972de0289..e7fc07ee329 100644
--- a/openair3/NAS/TEST/USER/user_parser.h
+++ b/openair3/NAS/TEST/USER/user_parser.h
@@ -39,8 +39,8 @@ Description Command line parser of the user simulator process
 
 *****************************************************************************/
 
-#ifndef __USER_PARSER_H__
-#define __USER_PARSER__H__
+#ifndef __NAS_TEST_USER_USER_PARSER__H__
+#define __NAS_TEST_USER_USER_PARSER__H__
 
 /****************************************************************************/
 /*********************  G L O B A L    C O N S T A N T S  *******************/
@@ -74,4 +74,4 @@ const char* user_parser_get_port(void);
 const char* user_parser_get_devpath(void);
 const char* user_parser_get_devattr(void);
 
-#endif /* __USER_PARSER_H__*/
+#endif /* __NAS_TEST_USER_USER_PARSER__H__ */
diff --git a/openair3/NAS/TOOLS/conf_network.c b/openair3/NAS/TOOLS/conf_network.c
index 96e2183327a..054189a130c 100644
--- a/openair3/NAS/TOOLS/conf_network.c
+++ b/openair3/NAS/TOOLS/conf_network.c
@@ -43,7 +43,7 @@ void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_
 		strcpy(record->fullname, conf->fullname);
 		strcpy(record->shortname, conf->shortname);
 
-		char num[6];
+		char num[60];
 		sprintf(num, "%s%s", conf->mcc, conf->mnc);
 		record->num = atoi(num);
 
@@ -80,7 +80,7 @@ bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) {
 
 bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) {
 	config_setting_t *plmn_setting = NULL;
-	char plmn[10];
+	char plmn[100];
 	int size = 0;
 
 	size = config_setting_length(all_plmn_setting);
diff --git a/openair3/NAS/TOOLS/conf_parser.c b/openair3/NAS/TOOLS/conf_parser.c
index d46142c4614..3ea1e29554f 100644
--- a/openair3/NAS/TOOLS/conf_parser.c
+++ b/openair3/NAS/TOOLS/conf_parser.c
@@ -13,7 +13,7 @@ bool parse_config_file(const char *output_dir, const char *conf_filename, int ou
     config_setting_t *root_setting = NULL;
     config_setting_t *ue_setting = NULL;
     config_setting_t *all_plmn_setting = NULL;
-    char user[10];
+    char user[100];
     config_t cfg;
 
 	networks_t networks;;
diff --git a/openair3/TEST/oaisim_mme_test_s1c_s1ap.h b/openair3/TEST/oaisim_mme_test_s1c_s1ap.h
index 3633f11e867..4faec0e66e5 100644
--- a/openair3/TEST/oaisim_mme_test_s1c_s1ap.h
+++ b/openair3/TEST/oaisim_mme_test_s1c_s1ap.h
@@ -19,6 +19,9 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __TEST_OAISIM_MME_TEST_S1C_S1AP__H__
+#define __TEST_OAISIM_MME_TEST_S1C_S1AP__H__
+
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -53,3 +56,5 @@ void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
                                   uint16_t             out_streams);
 void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
 void *s1ap_eNB_task(void *arg);
+
+#endif
diff --git a/openair3/TEST/oaisim_mme_test_s1c_scenario.h b/openair3/TEST/oaisim_mme_test_s1c_scenario.h
index 8c33f457418..8b9a8dd54a1 100644
--- a/openair3/TEST/oaisim_mme_test_s1c_scenario.h
+++ b/openair3/TEST/oaisim_mme_test_s1c_scenario.h
@@ -19,6 +19,9 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __TEST_OAISIM_MME_TEST_S1C_SCENARIO__H__
+#define __TEST_OAISIM_MME_TEST_S1C_SCENARIO__H__
+
 #include <stdlib.h>
 #include <stdint.h>
 
@@ -49,3 +52,5 @@ int      compare_buffer(const uint8_t *buffer, const uint32_t length_buffer, con
 unsigned decode_hex_length(const char *h);
 int      decode_hex(uint8_t *dst, const char *h);
 uint8_t *decode_hex_dup(const char *hex);
+
+#endif
diff --git a/openair3/UTILS/mme_config.h b/openair3/UTILS/mme_config.h
index 37b7dff8651..417c8bbd5f4 100644
--- a/openair3/UTILS/mme_config.h
+++ b/openair3/UTILS/mme_config.h
@@ -19,14 +19,14 @@
  *      contact@openairinterface.org
  */
 
+#ifndef __UTILS_MME_CONFIG__H__
+#define __UTILS_MME_CONFIG__H__
+
 #include <pthread.h>
 #include <stdint.h>
 
 #include "mme_default_values.h"
 
-#ifndef MME_CONFIG_H_
-#define MME_CONFIG_H_
-
 #define MME_CONFIG_STRING_MME_CONFIG                     "MME"
 #define MME_CONFIG_STRING_REALM                          "REALM"
 #define MME_CONFIG_STRING_MAXENB                         "MAXENB"
@@ -183,4 +183,4 @@ int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config);
 
 //int yyparse(struct mme_config_s *mme_config_p);
 
-#endif /* MME_CONFIG_H_ */
+#endif /* __UTILS_MME_CONFIG__H__ */
diff --git a/openair3/UTILS/queue.h b/openair3/UTILS/queue.h
deleted file mode 100644
index f8665c0f1a3..00000000000
--- a/openair3/UTILS/queue.h
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (c) 1991, 1993
- *  The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *  @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * lists, simple queues, tail queues, and circular queues.
- *
- * A singly-linked list is headed by a single forward pointer. The
- * elements are singly linked for minimum space and pointer manipulation
- * overhead at the expense of O(n) removal for arbitrary elements. New
- * elements can be added to the list after an existing element or at the
- * head of the list.  Elements being removed from the head of the list
- * should use the explicit macro for this purpose for optimum
- * efficiency. A singly-linked list may only be traversed in the forward
- * direction.  Singly-linked lists are ideal for applications with large
- * datasets and few or no removals or for implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- *                      SLIST   LIST    STAILQ  TAILQ   CIRCLEQ
- * _HEAD                +       +       +       +       +
- * _HEAD_INITIALIZER    +       +       +       +       +
- * _ENTRY               +       +       +       +       +
- * _INIT                +       +       +       +       +
- * _EMPTY               +       +       +       +       +
- * _FIRST               +       +       +       +       +
- * _NEXT                +       +       +       +       +
- * _PREV                -       -       -       +       +
- * _LAST                -       -       +       +       +
- * _FOREACH             +       +       +       +       +
- * _FOREACH_REVERSE     -       -       -       +       +
- * _INSERT_HEAD         +       +       +       +       +
- * _INSERT_BEFORE       -       +       -       +       +
- * _INSERT_AFTER        +       +       +       +       +
- * _INSERT_TAIL         -       -       +       +       +
- * _REMOVE_HEAD         +       -       +       -       -
- * _REMOVE              +       +       +       +       +
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type)           \
-struct name {               \
-  struct type *lh_first;  /* first element */     \
-}
-
-#define LIST_HEAD_INITIALIZER(head)         \
-  { NULL }
-
-#define LIST_ENTRY(type)            \
-struct {                \
-  struct type *le_next; /* next element */      \
-  struct type **le_prev;  /* address of previous next element */  \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do {            \
-  (head)->lh_first = NULL;          \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
-  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
-    (listelm)->field.le_next->field.le_prev =   \
-        &(elm)->field.le_next;        \
-  (listelm)->field.le_next = (elm);       \
-  (elm)->field.le_prev = &(listelm)->field.le_next;   \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
-  (elm)->field.le_prev = (listelm)->field.le_prev;    \
-  (elm)->field.le_next = (listelm);       \
-  *(listelm)->field.le_prev = (elm);        \
-  (listelm)->field.le_prev = &(elm)->field.le_next;   \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do {       \
-  if (((elm)->field.le_next = (head)->lh_first) != NULL)    \
-    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-  (head)->lh_first = (elm);         \
-  (elm)->field.le_prev = &(head)->lh_first;     \
-} while (/*CONSTCOND*/0)
-
-#define LIST_REMOVE(elm, field) do {          \
-  if ((elm)->field.le_next != NULL)       \
-    (elm)->field.le_next->field.le_prev =       \
-        (elm)->field.le_prev;       \
-  *(elm)->field.le_prev = (elm)->field.le_next;     \
-} while (/*CONSTCOND*/0)
-
-#define LIST_FOREACH(var, head, field)          \
-  for ((var) = ((head)->lh_first);        \
-    (var);              \
-    (var) = ((var)->field.le_next))
-
-/*
- * List access methods.
- */
-#define LIST_EMPTY(head)    ((head)->lh_first == NULL)
-#define LIST_FIRST(head)    ((head)->lh_first)
-#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
-
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type)            \
-struct name {               \
-  struct type *slh_first; /* first element */     \
-}
-
-#define SLIST_HEAD_INITIALIZER(head)          \
-  { NULL }
-
-#define SLIST_ENTRY(type)           \
-struct {                \
-  struct type *sle_next;  /* next element */      \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_INIT(head) do {           \
-  (head)->slh_first = NULL;         \
-} while (/*CONSTCOND*/0)
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
-  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
-  (slistelm)->field.sle_next = (elm);       \
-} while (/*CONSTCOND*/0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do {      \
-  (elm)->field.sle_next = (head)->slh_first;      \
-  (head)->slh_first = (elm);          \
-} while (/*CONSTCOND*/0)
-
-#define SLIST_REMOVE_HEAD(head, field) do {       \
-  (head)->slh_first = (head)->slh_first->field.sle_next;    \
-} while (/*CONSTCOND*/0)
-
-#define SLIST_REMOVE(head, elm, type, field) do {     \
-  if ((head)->slh_first == (elm)) {       \
-    SLIST_REMOVE_HEAD((head), field);     \
-  }               \
-  else {                \
-    struct type *curelm = (head)->slh_first;    \
-    while(curelm->field.sle_next != (elm))      \
-      curelm = curelm->field.sle_next;    \
-    curelm->field.sle_next =        \
-        curelm->field.sle_next->field.sle_next;   \
-  }               \
-} while (/*CONSTCOND*/0)
-
-#define SLIST_FOREACH(var, head, field)         \
-  for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-/*
- * Singly-linked List access methods.
- */
-#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
-#define SLIST_FIRST(head) ((head)->slh_first)
-#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
-
-
-/*
- * Singly-linked Tail queue declarations.
- */
-#define STAILQ_HEAD(name, type)         \
-struct name {               \
-  struct type *stqh_first;  /* first element */     \
-  struct type **stqh_last;  /* addr of last next element */   \
-}
-
-#define STAILQ_HEAD_INITIALIZER(head)         \
-  { NULL, &(head).stqh_first }
-
-#define STAILQ_ENTRY(type)            \
-struct {                \
-  struct type *stqe_next; /* next element */      \
-}
-
-/*
- * Singly-linked Tail queue functions.
- */
-#define STAILQ_INIT(head) do {            \
-  (head)->stqh_first = NULL;          \
-  (head)->stqh_last = &(head)->stqh_first;        \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_INSERT_HEAD(head, elm, field) do {     \
-  if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)  \
-    (head)->stqh_last = &(elm)->field.stqe_next;    \
-  (head)->stqh_first = (elm);         \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_INSERT_TAIL(head, elm, field) do {     \
-  (elm)->field.stqe_next = NULL;          \
-  *(head)->stqh_last = (elm);         \
-  (head)->stqh_last = &(elm)->field.stqe_next;      \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
-  if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
-    (head)->stqh_last = &(elm)->field.stqe_next;    \
-  (listelm)->field.stqe_next = (elm);       \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_REMOVE_HEAD(head, field) do {        \
-  if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
-    (head)->stqh_last = &(head)->stqh_first;      \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_REMOVE(head, elm, type, field) do {      \
-  if ((head)->stqh_first == (elm)) {        \
-    STAILQ_REMOVE_HEAD((head), field);      \
-  } else {              \
-    struct type *curelm = (head)->stqh_first;   \
-    while (curelm->field.stqe_next != (elm))      \
-      curelm = curelm->field.stqe_next;   \
-    if ((curelm->field.stqe_next =        \
-      curelm->field.stqe_next->field.stqe_next) == NULL) \
-          (head)->stqh_last = &(curelm)->field.stqe_next; \
-  }               \
-} while (/*CONSTCOND*/0)
-
-#define STAILQ_FOREACH(var, head, field)        \
-  for ((var) = ((head)->stqh_first);        \
-    (var);              \
-    (var) = ((var)->field.stqe_next))
-
-#define STAILQ_CONCAT(head1, head2) do {        \
-  if (!STAILQ_EMPTY((head2))) {         \
-    *(head1)->stqh_last = (head2)->stqh_first;    \
-    (head1)->stqh_last = (head2)->stqh_last;    \
-    STAILQ_INIT((head2));         \
-  }               \
-} while (/*CONSTCOND*/0)
-
-/*
- * Singly-linked Tail queue access methods.
- */
-#define STAILQ_EMPTY(head)  ((head)->stqh_first == NULL)
-#define STAILQ_FIRST(head)  ((head)->stqh_first)
-#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
-
-
-/*
- * Simple queue definitions.
- */
-#define SIMPLEQ_HEAD(name, type)          \
-struct name {               \
-  struct type *sqh_first; /* first element */     \
-  struct type **sqh_last; /* addr of last next element */   \
-}
-
-#define SIMPLEQ_HEAD_INITIALIZER(head)          \
-  { NULL, &(head).sqh_first }
-
-#define SIMPLEQ_ENTRY(type)           \
-struct {                \
-  struct type *sqe_next;  /* next element */      \
-}
-
-/*
- * Simple queue functions.
- */
-#define SIMPLEQ_INIT(head) do {           \
-  (head)->sqh_first = NULL;         \
-  (head)->sqh_last = &(head)->sqh_first;        \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
-  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
-    (head)->sqh_last = &(elm)->field.sqe_next;    \
-  (head)->sqh_first = (elm);          \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {      \
-  (elm)->field.sqe_next = NULL;         \
-  *(head)->sqh_last = (elm);          \
-  (head)->sqh_last = &(elm)->field.sqe_next;      \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
-  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
-    (head)->sqh_last = &(elm)->field.sqe_next;    \
-  (listelm)->field.sqe_next = (elm);        \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_REMOVE_HEAD(head, field) do {       \
-  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
-    (head)->sqh_last = &(head)->sqh_first;      \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_REMOVE(head, elm, type, field) do {     \
-  if ((head)->sqh_first == (elm)) {       \
-    SIMPLEQ_REMOVE_HEAD((head), field);     \
-  } else {              \
-    struct type *curelm = (head)->sqh_first;    \
-    while (curelm->field.sqe_next != (elm))     \
-      curelm = curelm->field.sqe_next;    \
-    if ((curelm->field.sqe_next =       \
-      curelm->field.sqe_next->field.sqe_next) == NULL) \
-          (head)->sqh_last = &(curelm)->field.sqe_next; \
-  }               \
-} while (/*CONSTCOND*/0)
-
-#define SIMPLEQ_FOREACH(var, head, field)       \
-  for ((var) = ((head)->sqh_first);       \
-    (var);              \
-    (var) = ((var)->field.sqe_next))
-
-/*
- * Simple queue access methods.
- */
-#define SIMPLEQ_EMPTY(head)   ((head)->sqh_first == NULL)
-#define SIMPLEQ_FIRST(head)   ((head)->sqh_first)
-#define SIMPLEQ_NEXT(elm, field)  ((elm)->field.sqe_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define _TAILQ_HEAD(name, type, qual)         \
-struct name {               \
-  qual type *tqh_first;   /* first element */   \
-  qual type *qual *tqh_last;  /* addr of last next element */ \
-}
-#define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type,)
-
-#define TAILQ_HEAD_INITIALIZER(head)          \
-  { NULL, &(head).tqh_first }
-
-#define _TAILQ_ENTRY(type, qual)          \
-struct {                \
-  qual type *tqe_next;    /* next element */    \
-  qual type *qual *tqe_prev;  /* address of previous next element */\
-}
-#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do {           \
-  (head)->tqh_first = NULL;         \
-  (head)->tqh_last = &(head)->tqh_first;        \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do {      \
-  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)  \
-    (head)->tqh_first->field.tqe_prev =     \
-        &(elm)->field.tqe_next;       \
-  else                \
-    (head)->tqh_last = &(elm)->field.tqe_next;    \
-  (head)->tqh_first = (elm);          \
-  (elm)->field.tqe_prev = &(head)->tqh_first;     \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do {      \
-  (elm)->field.tqe_next = NULL;         \
-  (elm)->field.tqe_prev = (head)->tqh_last;     \
-  *(head)->tqh_last = (elm);          \
-  (head)->tqh_last = &(elm)->field.tqe_next;      \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {    \
-  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-    (elm)->field.tqe_next->field.tqe_prev =     \
-        &(elm)->field.tqe_next;       \
-  else                \
-    (head)->tqh_last = &(elm)->field.tqe_next;    \
-  (listelm)->field.tqe_next = (elm);        \
-  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
-  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
-  (elm)->field.tqe_next = (listelm);        \
-  *(listelm)->field.tqe_prev = (elm);       \
-  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_REMOVE(head, elm, field) do {       \
-  if (((elm)->field.tqe_next) != NULL)        \
-    (elm)->field.tqe_next->field.tqe_prev =     \
-        (elm)->field.tqe_prev;        \
-  else                \
-    (head)->tqh_last = (elm)->field.tqe_prev;   \
-  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_FOREACH(var, head, field)         \
-  for ((var) = ((head)->tqh_first);       \
-    (var);              \
-    (var) = ((var)->field.tqe_next))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
-  for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));  \
-    (var);              \
-    (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
-
-#define TAILQ_CONCAT(head1, head2, field) do {        \
-  if (!TAILQ_EMPTY(head2)) {          \
-    *(head1)->tqh_last = (head2)->tqh_first;    \
-    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
-    (head1)->tqh_last = (head2)->tqh_last;      \
-    TAILQ_INIT((head2));          \
-  }               \
-} while (/*CONSTCOND*/0)
-
-/*
- * Tail queue access methods.
- */
-#define TAILQ_EMPTY(head)   ((head)->tqh_first == NULL)
-#define TAILQ_FIRST(head)   ((head)->tqh_first)
-#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
-
-#define TAILQ_LAST(head, headname) \
-  (*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define TAILQ_PREV(elm, headname, field) \
-  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type)          \
-struct name {               \
-  struct type *cqh_first;   /* first element */   \
-  struct type *cqh_last;    /* last element */    \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head)          \
-  { (void *)&head, (void *)&head }
-
-#define CIRCLEQ_ENTRY(type)           \
-struct {                \
-  struct type *cqe_next;    /* next element */    \
-  struct type *cqe_prev;    /* previous element */    \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do {           \
-  (head)->cqh_first = (void *)(head);       \
-  (head)->cqh_last = (void *)(head);        \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
-  (elm)->field.cqe_next = (listelm)->field.cqe_next;    \
-  (elm)->field.cqe_prev = (listelm);        \
-  if ((listelm)->field.cqe_next == (void *)(head))    \
-    (head)->cqh_last = (elm);       \
-  else                \
-    (listelm)->field.cqe_next->field.cqe_prev = (elm);  \
-  (listelm)->field.cqe_next = (elm);        \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {   \
-  (elm)->field.cqe_next = (listelm);        \
-  (elm)->field.cqe_prev = (listelm)->field.cqe_prev;    \
-  if ((listelm)->field.cqe_prev == (void *)(head))    \
-    (head)->cqh_first = (elm);        \
-  else                \
-    (listelm)->field.cqe_prev->field.cqe_next = (elm);  \
-  (listelm)->field.cqe_prev = (elm);        \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {      \
-  (elm)->field.cqe_next = (head)->cqh_first;      \
-  (elm)->field.cqe_prev = (void *)(head);       \
-  if ((head)->cqh_last == (void *)(head))       \
-    (head)->cqh_last = (elm);       \
-  else                \
-    (head)->cqh_first->field.cqe_prev = (elm);    \
-  (head)->cqh_first = (elm);          \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {      \
-  (elm)->field.cqe_next = (void *)(head);       \
-  (elm)->field.cqe_prev = (head)->cqh_last;     \
-  if ((head)->cqh_first == (void *)(head))      \
-    (head)->cqh_first = (elm);        \
-  else                \
-    (head)->cqh_last->field.cqe_next = (elm);   \
-  (head)->cqh_last = (elm);         \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do {       \
-  if ((elm)->field.cqe_next == (void *)(head))      \
-    (head)->cqh_last = (elm)->field.cqe_prev;   \
-  else                \
-    (elm)->field.cqe_next->field.cqe_prev =     \
-        (elm)->field.cqe_prev;        \
-  if ((elm)->field.cqe_prev == (void *)(head))      \
-    (head)->cqh_first = (elm)->field.cqe_next;    \
-  else                \
-    (elm)->field.cqe_prev->field.cqe_next =     \
-        (elm)->field.cqe_next;        \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_FOREACH(var, head, field)       \
-  for ((var) = ((head)->cqh_first);       \
-    (var) != (const void *)(head);        \
-    (var) = ((var)->field.cqe_next))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field)     \
-  for ((var) = ((head)->cqh_last);        \
-    (var) != (const void *)(head);        \
-    (var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define CIRCLEQ_EMPTY(head)   ((head)->cqh_first == (void *)(head))
-#define CIRCLEQ_FIRST(head)   ((head)->cqh_first)
-#define CIRCLEQ_LAST(head)    ((head)->cqh_last)
-#define CIRCLEQ_NEXT(elm, field)  ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field)  ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_LOOP_NEXT(head, elm, field)       \
-  (((elm)->field.cqe_next == (void *)(head))      \
-      ? ((head)->cqh_first)         \
-      : (elm->field.cqe_next))
-#define CIRCLEQ_LOOP_PREV(head, elm, field)       \
-  (((elm)->field.cqe_prev == (void *)(head))      \
-      ? ((head)->cqh_last)          \
-      : (elm->field.cqe_prev))
-
-#endif  /* sys/queue.h */
diff --git a/openair3/UTILS/tree.h b/openair3/UTILS/tree.h
deleted file mode 100644
index 351df9dfc5a..00000000000
--- a/openair3/UTILS/tree.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Copyright 2002 Niels Provos <provos@citi.umich.edu>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SYS_TREE_H_
-#define _SYS_TREE_H_
-
-/*
- * This file defines data structures for different types of trees:
- * splay trees and red-black trees.
- *
- * A splay tree is a self-organizing data structure.  Every operation
- * on the tree causes a splay to happen.  The splay moves the requested
- * node to the root of the tree and partly rebalances it.
- *
- * This has the benefit that request locality causes faster lookups as
- * the requested nodes move to the top of the tree.  On the other hand,
- * every lookup causes memory writes.
- *
- * The Balance Theorem bounds the total access time for m operations
- * and n inserts on an initially empty tree as O((m + n)lg n).  The
- * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
- *
- * A red-black tree is a binary search tree with the node color as an
- * extra attribute.  It fulfills a set of conditions:
- *  - every search path from the root to a leaf consists of the
- *    same number of black nodes,
- *  - each red node (except for the root) has a black parent,
- *  - each leaf node is black.
- *
- * Every operation on a red-black tree is bounded as O(lg n).
- * The maximum height of a red-black tree is 2lg (n+1).
- */
-
-#define SPLAY_HEAD(name, type)            \
-struct name {               \
-  struct type *sph_root; /* root of the tree */     \
-}
-
-#define SPLAY_INITIALIZER(root)           \
-  { NULL }
-
-#define SPLAY_INIT(root) do {           \
-  (root)->sph_root = NULL;          \
-} while (0)
-
-#define SPLAY_ENTRY(type)           \
-struct {                \
-  struct type *spe_left; /* left element */     \
-  struct type *spe_right; /* right element */     \
-}
-
-#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
-#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
-#define SPLAY_ROOT(head)    (head)->sph_root
-#define SPLAY_EMPTY(head)   (SPLAY_ROOT(head) == NULL)
-
-/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
-#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {     \
-  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \
-  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
-  (head)->sph_root = tmp;           \
-} while (0)
-
-#define SPLAY_ROTATE_LEFT(head, tmp, field) do {      \
-  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \
-  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
-  (head)->sph_root = tmp;           \
-} while (0)
-
-#define SPLAY_LINKLEFT(head, tmp, field) do {       \
-  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
-  tmp = (head)->sph_root;           \
-  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);   \
-} while (0)
-
-#define SPLAY_LINKRIGHT(head, tmp, field) do {        \
-  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
-  tmp = (head)->sph_root;           \
-  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
-} while (0)
-
-#define SPLAY_ASSEMBLE(head, node, left, right, field) do {   \
-  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
-  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
-  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
-  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
-} while (0)
-
-/* Generates prototypes and inline functions */
-
-#define SPLAY_PROTOTYPE(name, type, field, cmp)       \
-void name##_SPLAY(struct name *, struct type *);      \
-void name##_SPLAY_MINMAX(struct name *, int);       \
-struct type *name##_SPLAY_INSERT(struct name *, struct type *);   \
-struct type *name##_SPLAY_REMOVE(struct name *, struct type *);   \
-                  \
-/* Finds the node with the same key as elm */       \
-static __inline struct type *           \
-name##_SPLAY_FIND(struct name *head, struct type *elm)      \
-{                 \
-  if (SPLAY_EMPTY(head))            \
-    return(NULL);           \
-  name##_SPLAY(head, elm);          \
-  if ((cmp)(elm, (head)->sph_root) == 0)        \
-    return (head->sph_root);        \
-  return (NULL);              \
-}                 \
-                  \
-static __inline struct type *           \
-name##_SPLAY_NEXT(struct name *head, struct type *elm)      \
-{                 \
-  name##_SPLAY(head, elm);          \
-  if (SPLAY_RIGHT(elm, field) != NULL) {        \
-    elm = SPLAY_RIGHT(elm, field);        \
-    while (SPLAY_LEFT(elm, field) != NULL) {    \
-      elm = SPLAY_LEFT(elm, field);     \
-    }             \
-  } else                \
-    elm = NULL;           \
-  return (elm);             \
-}                 \
-                  \
-static __inline struct type *           \
-name##_SPLAY_MIN_MAX(struct name *head, int val)      \
-{                 \
-  name##_SPLAY_MINMAX(head, val);         \
-        return (SPLAY_ROOT(head));          \
-}
-
-/* Main splay operation.
- * Moves node close to the key of elm to top
- */
-#define SPLAY_GENERATE(name, type, field, cmp)        \
-struct type *               \
-name##_SPLAY_INSERT(struct name *head, struct type *elm)    \
-{                 \
-    if (SPLAY_EMPTY(head)) {            \
-      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;  \
-    } else {                \
-      int __comp;             \
-      name##_SPLAY(head, elm);          \
-      __comp = (cmp)(elm, (head)->sph_root);      \
-      if(__comp < 0) {            \
-        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
-        SPLAY_RIGHT(elm, field) = (head)->sph_root;   \
-        SPLAY_LEFT((head)->sph_root, field) = NULL;   \
-      } else if (__comp > 0) {          \
-        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
-        SPLAY_LEFT(elm, field) = (head)->sph_root;    \
-        SPLAY_RIGHT((head)->sph_root, field) = NULL;  \
-      } else              \
-        return ((head)->sph_root);        \
-    }                 \
-    (head)->sph_root = (elm);           \
-    return (NULL);              \
-}                 \
-                  \
-struct type *               \
-name##_SPLAY_REMOVE(struct name *head, struct type *elm)    \
-{                 \
-  struct type *__tmp;           \
-  if (SPLAY_EMPTY(head))            \
-    return (NULL);            \
-  name##_SPLAY(head, elm);          \
-  if ((cmp)(elm, (head)->sph_root) == 0) {      \
-    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \
-      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
-    } else {            \
-      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
-      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
-      name##_SPLAY(head, elm);      \
-      SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
-    }             \
-    return (elm);           \
-  }               \
-  return (NULL);              \
-}                 \
-                  \
-void                  \
-name##_SPLAY(struct name *head, struct type *elm)     \
-{                 \
-  struct type __node, *__left, *__right, *__tmp;      \
-  int __comp;             \
-\
-  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
-  __left = __right = &__node;         \
-\
-  while ((__comp = (cmp)(elm, (head)->sph_root))) {   \
-    if (__comp < 0) {         \
-      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
-      if (__tmp == NULL)        \
-        break;          \
-      if ((cmp)(elm, __tmp) < 0){     \
-        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
-        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
-          break;        \
-      }           \
-      SPLAY_LINKLEFT(head, __right, field);   \
-    } else if (__comp > 0) {        \
-      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
-      if (__tmp == NULL)        \
-        break;          \
-      if ((cmp)(elm, __tmp) > 0){     \
-        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
-        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
-          break;        \
-      }           \
-      SPLAY_LINKRIGHT(head, __left, field);   \
-    }             \
-  }               \
-  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
-}                 \
-                  \
-/* Splay with either the minimum or the maximum element     \
- * Used to find minimum or maximum element in tree.     \
- */                 \
-void name##_SPLAY_MINMAX(struct name *head, int __comp) \
-{                 \
-  struct type __node, *__left, *__right, *__tmp;      \
-\
-  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
-  __left = __right = &__node;         \
-\
-  while (1) {             \
-    if (__comp < 0) {         \
-      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
-      if (__tmp == NULL)        \
-        break;          \
-      if (__comp < 0){        \
-        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
-        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
-          break;        \
-      }           \
-      SPLAY_LINKLEFT(head, __right, field);   \
-    } else if (__comp > 0) {        \
-      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
-      if (__tmp == NULL)        \
-        break;          \
-      if (__comp > 0) {       \
-        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
-        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
-          break;        \
-      }           \
-      SPLAY_LINKRIGHT(head, __left, field);   \
-    }             \
-  }               \
-  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
-}
-
-#define SPLAY_NEGINF  -1
-#define SPLAY_INF 1
-
-#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
-#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
-#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
-#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
-#define SPLAY_MIN(name, x)    (SPLAY_EMPTY(x) ? NULL  \
-          : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
-#define SPLAY_MAX(name, x)    (SPLAY_EMPTY(x) ? NULL  \
-          : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
-
-#define SPLAY_FOREACH(x, name, head)          \
-  for ((x) = SPLAY_MIN(name, head);       \
-       (x) != NULL;           \
-       (x) = SPLAY_NEXT(name, head, x))
-
-/* Macros that define a red-back tree */
-#define RB_HEAD(name, type)           \
-struct name {               \
-  struct type *rbh_root; /* root of the tree */     \
-}
-
-#define RB_INITIALIZER(root)            \
-  { NULL }
-
-#define RB_INIT(root) do {            \
-  (root)->rbh_root = NULL;          \
-} while (0)
-
-#define RB_BLACK  0
-#define RB_RED    1
-#define RB_ENTRY(type)              \
-struct {                \
-  struct type *rbe_left;    /* left element */    \
-  struct type *rbe_right;   /* right element */   \
-  struct type *rbe_parent;  /* parent element */    \
-  int rbe_color;      /* node color */    \
-}
-
-#define RB_LEFT(elm, field)   (elm)->field.rbe_left
-#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
-#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
-#define RB_COLOR(elm, field)    (elm)->field.rbe_color
-#define RB_ROOT(head)     (head)->rbh_root
-#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
-
-#define RB_SET(elm, parent, field) do {         \
-  RB_PARENT(elm, field) = parent;         \
-  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
-  RB_COLOR(elm, field) = RB_RED;          \
-} while (0)
-
-#define RB_SET_BLACKRED(black, red, field) do {       \
-  RB_COLOR(black, field) = RB_BLACK;        \
-  RB_COLOR(red, field) = RB_RED;          \
-} while (0)
-
-#ifndef RB_AUGMENT
-#define RB_AUGMENT(x)
-#endif
-
-#define RB_ROTATE_LEFT(head, elm, tmp, field) do {      \
-  (tmp) = RB_RIGHT(elm, field);         \
-  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {   \
-    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);    \
-  }               \
-  RB_AUGMENT(elm);            \
-  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
-    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
-      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
-    else              \
-      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
-  } else                \
-    (head)->rbh_root = (tmp);       \
-  RB_LEFT(tmp, field) = (elm);          \
-  RB_PARENT(elm, field) = (tmp);          \
-  RB_AUGMENT(tmp);            \
-  if ((RB_PARENT(tmp, field)))          \
-    RB_AUGMENT(RB_PARENT(tmp, field));      \
-} while (0)
-
-#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
-  (tmp) = RB_LEFT(elm, field);          \
-  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {   \
-    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);   \
-  }               \
-  RB_AUGMENT(elm);            \
-  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
-    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
-      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
-    else              \
-      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
-  } else                \
-    (head)->rbh_root = (tmp);       \
-  RB_RIGHT(tmp, field) = (elm);         \
-  RB_PARENT(elm, field) = (tmp);          \
-  RB_AUGMENT(tmp);            \
-  if ((RB_PARENT(tmp, field)))          \
-    RB_AUGMENT(RB_PARENT(tmp, field));      \
-} while (0)
-
-/* Generates prototypes and inline functions */
-#define RB_PROTOTYPE(name, type, field, cmp)        \
-void name##_RB_INSERT_COLOR(struct name *, struct type *);  \
-void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
-struct type *name##_RB_REMOVE(struct name *, struct type *);    \
-struct type *name##_RB_INSERT(struct name *, struct type *);    \
-struct type *name##_RB_FIND(struct name *, struct type *);    \
-struct type *name##_RB_NEXT(struct type *);       \
-struct type *name##_RB_MINMAX(struct name *, int);      \
-                  \
- 
-/* Main rb operation.
- * Moves node close to the key of elm to top
- */
-#define RB_GENERATE(name, type, field, cmp)       \
-void                  \
-name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
-{                 \
-  struct type *parent, *gparent, *tmp;        \
-  while ((parent = RB_PARENT(elm, field)) &&      \
-      RB_COLOR(parent, field) == RB_RED) {      \
-    gparent = RB_PARENT(parent, field);     \
-    if (parent == RB_LEFT(gparent, field)) {    \
-      tmp = RB_RIGHT(gparent, field);     \
-      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
-        RB_COLOR(tmp, field) = RB_BLACK;  \
-        RB_SET_BLACKRED(parent, gparent, field);\
-        elm = gparent;        \
-        continue;       \
-      }           \
-      if (RB_RIGHT(parent, field) == elm) {   \
-        RB_ROTATE_LEFT(head, parent, tmp, field);\
-        tmp = parent;       \
-        parent = elm;       \
-        elm = tmp;        \
-      }           \
-      RB_SET_BLACKRED(parent, gparent, field);  \
-      RB_ROTATE_RIGHT(head, gparent, tmp, field); \
-    } else {            \
-      tmp = RB_LEFT(gparent, field);      \
-      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
-        RB_COLOR(tmp, field) = RB_BLACK;  \
-        RB_SET_BLACKRED(parent, gparent, field);\
-        elm = gparent;        \
-        continue;       \
-      }           \
-      if (RB_LEFT(parent, field) == elm) {    \
-        RB_ROTATE_RIGHT(head, parent, tmp, field);\
-        tmp = parent;       \
-        parent = elm;       \
-        elm = tmp;        \
-      }           \
-      RB_SET_BLACKRED(parent, gparent, field);  \
-      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
-    }             \
-  }               \
-  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
-}                 \
-                  \
-void                  \
-name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
-{                 \
-  struct type *tmp;           \
-  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
-      elm != RB_ROOT(head)) {         \
-    if (RB_LEFT(parent, field) == elm) {      \
-      tmp = RB_RIGHT(parent, field);      \
-      if (RB_COLOR(tmp, field) == RB_RED) {   \
-        RB_SET_BLACKRED(tmp, parent, field);  \
-        RB_ROTATE_LEFT(head, parent, tmp, field);\
-        tmp = RB_RIGHT(parent, field);    \
-      }           \
-      if ((RB_LEFT(tmp, field) == NULL ||   \
-          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
-          (RB_RIGHT(tmp, field) == NULL ||    \
-          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
-        RB_COLOR(tmp, field) = RB_RED;    \
-        elm = parent;       \
-        parent = RB_PARENT(elm, field);   \
-      } else {          \
-        if (RB_RIGHT(tmp, field) == NULL || \
-            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
-          struct type *oleft;   \
-          if ((oleft = RB_LEFT(tmp, field)))\
-            RB_COLOR(oleft, field) = RB_BLACK;\
-          RB_COLOR(tmp, field) = RB_RED;  \
-          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
-          tmp = RB_RIGHT(parent, field);  \
-        }         \
-        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
-        RB_COLOR(parent, field) = RB_BLACK; \
-        if (RB_RIGHT(tmp, field))   \
-          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
-        RB_ROTATE_LEFT(head, parent, tmp, field);\
-        elm = RB_ROOT(head);      \
-        break;          \
-      }           \
-    } else {            \
-      tmp = RB_LEFT(parent, field);     \
-      if (RB_COLOR(tmp, field) == RB_RED) {   \
-        RB_SET_BLACKRED(tmp, parent, field);  \
-        RB_ROTATE_RIGHT(head, parent, tmp, field);\
-        tmp = RB_LEFT(parent, field);   \
-      }           \
-      if ((RB_LEFT(tmp, field) == NULL ||   \
-          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
-          (RB_RIGHT(tmp, field) == NULL ||    \
-          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
-        RB_COLOR(tmp, field) = RB_RED;    \
-        elm = parent;       \
-        parent = RB_PARENT(elm, field);   \
-      } else {          \
-        if (RB_LEFT(tmp, field) == NULL ||  \
-            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
-          struct type *oright;    \
-          if ((oright = RB_RIGHT(tmp, field)))\
-            RB_COLOR(oright, field) = RB_BLACK;\
-          RB_COLOR(tmp, field) = RB_RED;  \
-          RB_ROTATE_LEFT(head, tmp, oright, field);\
-          tmp = RB_LEFT(parent, field); \
-        }         \
-        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
-        RB_COLOR(parent, field) = RB_BLACK; \
-        if (RB_LEFT(tmp, field))    \
-          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
-        RB_ROTATE_RIGHT(head, parent, tmp, field);\
-        elm = RB_ROOT(head);      \
-        break;          \
-      }           \
-    }             \
-  }               \
-  if (elm)              \
-    RB_COLOR(elm, field) = RB_BLACK;      \
-}                 \
-                  \
-struct type *               \
-name##_RB_REMOVE(struct name *head, struct type *elm)     \
-{                 \
-  struct type *child, *parent, *old = elm;      \
-  int color;              \
-  if (RB_LEFT(elm, field) == NULL)        \
-    child = RB_RIGHT(elm, field);       \
-  else if (RB_RIGHT(elm, field) == NULL)        \
-    child = RB_LEFT(elm, field);        \
-  else {                \
-    struct type *left;          \
-    elm = RB_RIGHT(elm, field);       \
-    while ((left = RB_LEFT(elm, field)))      \
-      elm = left;         \
-    child = RB_RIGHT(elm, field);       \
-    parent = RB_PARENT(elm, field);       \
-    color = RB_COLOR(elm, field);       \
-    if (child)            \
-      RB_PARENT(child, field) = parent;   \
-    if (parent) {           \
-      if (RB_LEFT(parent, field) == elm)    \
-        RB_LEFT(parent, field) = child;   \
-      else            \
-        RB_RIGHT(parent, field) = child;  \
-      RB_AUGMENT(parent);       \
-    } else              \
-      RB_ROOT(head) = child;        \
-    if (RB_PARENT(elm, field) == old)     \
-      parent = elm;         \
-    (elm)->field = (old)->field;        \
-    if (RB_PARENT(old, field)) {        \
-      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
-        RB_LEFT(RB_PARENT(old, field), field) = elm;\
-      else            \
-        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
-      RB_AUGMENT(RB_PARENT(old, field));    \
-    } else              \
-      RB_ROOT(head) = elm;        \
-    RB_PARENT(RB_LEFT(old, field), field) = elm;    \
-    if (RB_RIGHT(old, field))       \
-      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
-    if (parent) {           \
-      left = parent;          \
-      do {            \
-        RB_AUGMENT(left);     \
-      } while ((left = RB_PARENT(left, field)));  \
-    }             \
-    goto color;           \
-  }               \
-  parent = RB_PARENT(elm, field);         \
-  color = RB_COLOR(elm, field);         \
-  if (child)              \
-    RB_PARENT(child, field) = parent;     \
-  if (parent) {             \
-    if (RB_LEFT(parent, field) == elm)      \
-      RB_LEFT(parent, field) = child;     \
-    else              \
-      RB_RIGHT(parent, field) = child;    \
-    RB_AUGMENT(parent);         \
-  } else                \
-    RB_ROOT(head) = child;          \
-color:                  \
-  if (color == RB_BLACK)            \
-    name##_RB_REMOVE_COLOR(head, parent, child);    \
-  return (old);             \
-}                 \
-                  \
-/* Inserts a node into the RB tree */         \
-struct type *               \
-name##_RB_INSERT(struct name *head, struct type *elm)     \
-{                 \
-  struct type *tmp;           \
-  struct type *parent = NULL;         \
-  int comp = 0;             \
-  tmp = RB_ROOT(head);            \
-  while (tmp) {             \
-    parent = tmp;           \
-    comp = (cmp)(elm, parent);        \
-    if (comp < 0)           \
-      tmp = RB_LEFT(tmp, field);      \
-    else if (comp > 0)          \
-      tmp = RB_RIGHT(tmp, field);     \
-    else              \
-      return (tmp);         \
-  }               \
-  RB_SET(elm, parent, field);         \
-  if (parent != NULL) {           \
-    if (comp < 0)           \
-      RB_LEFT(parent, field) = elm;     \
-    else              \
-      RB_RIGHT(parent, field) = elm;      \
-    RB_AUGMENT(parent);         \
-  } else                \
-  {                                                                     \
-    RB_ROOT(head) = elm;          \
-  }                                                                     \
-  name##_RB_INSERT_COLOR(head, elm);        \
-  return (NULL);              \
-}                 \
-                  \
-/* Finds the node with the same key as elm */       \
-struct type *               \
-name##_RB_FIND(struct name *head, struct type *elm)     \
-{                 \
-  struct type *tmp = RB_ROOT(head);       \
-  int comp;             \
-  while (tmp) {             \
-    comp = cmp(elm, tmp);         \
-    if (comp < 0)           \
-      tmp = RB_LEFT(tmp, field);      \
-    else if (comp > 0)          \
-      tmp = RB_RIGHT(tmp, field);     \
-    else              \
-      return (tmp);         \
-  }               \
-  return (NULL);              \
-}                 \
-                  \
-struct type *               \
-name##_RB_NEXT(struct type *elm)          \
-{                 \
-  if (RB_RIGHT(elm, field)) {         \
-    elm = RB_RIGHT(elm, field);       \
-    while (RB_LEFT(elm, field))       \
-      elm = RB_LEFT(elm, field);      \
-  } else {              \
-    if (RB_PARENT(elm, field) &&        \
-        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
-      elm = RB_PARENT(elm, field);      \
-    else {              \
-      while (RB_PARENT(elm, field) &&     \
-          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
-        elm = RB_PARENT(elm, field);    \
-      elm = RB_PARENT(elm, field);      \
-    }             \
-  }               \
-  return (elm);             \
-}                 \
-                  \
-struct type *               \
-name##_RB_MINMAX(struct name *head, int val)        \
-{                 \
-  struct type *tmp = RB_ROOT(head);       \
-  struct type *parent = NULL;         \
-  while (tmp) {             \
-    parent = tmp;           \
-    if (val < 0)            \
-      tmp = RB_LEFT(tmp, field);      \
-    else              \
-      tmp = RB_RIGHT(tmp, field);     \
-  }               \
-  return (parent);            \
-}
-
-#define RB_NEGINF -1
-#define RB_INF  1
-
-#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
-#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
-#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
-#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
-#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
-#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
-
-#define RB_FOREACH(x, name, head)         \
-  for ((x) = RB_MIN(name, head);          \
-       (x) != NULL;           \
-       (x) = name##_RB_NEXT(x))
-
-#endif  /* _SYS_TREE_H_ */
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index ecadb68c0ca..d086c0e13a0 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -52,6 +52,9 @@
 #define RAU_LOCAL_RADIO_HEAD  0
 #define RAU_REMOTE_RADIO_HEAD 1
 
+#define MAX_WRITE_THREAD_PACKAGE     10
+#define MAX_WRITE_THREAD_BUFFER_SIZE 8
+
 #ifndef MAX_CARDS
   #define MAX_CARDS 8
 #endif
@@ -69,13 +72,9 @@ typedef enum {
   max_gain=0,med_gain,byp_gain
 } rx_gain_t;
 
-#if OCP_FRAMEWORK
-#include <enums.h>
-#else
 typedef enum {
   duplex_mode_TDD=1,duplex_mode_FDD=0
 } duplex_mode_t;
-#endif
 
 
 /** @addtogroup _GENERIC_PHY_RF_INTERFACE_
@@ -275,8 +274,37 @@ typedef struct {
   void *rx;
 } if_buffer_t;
 
+typedef struct {
+  openair0_timestamp timestamp;
+  void *buff[MAX_WRITE_THREAD_BUFFER_SIZE];// buffer to be write;
+  int nsamps;
+  int cc;
+  signed char first_packet;
+  signed char last_packet;
+  int flags_msb;
+} openair0_write_package_t;
+
+typedef struct {
+  openair0_write_package_t write_package[MAX_WRITE_THREAD_PACKAGE];
+  int start;
+  int end;
+  /// \internal This variable is protected by \ref mutex_write
+  int count_write;
+  /// pthread struct for trx write thread
+  pthread_t pthread_write;
+  /// pthread attributes for trx write thread
+  pthread_attr_t attr_write;
+  /// condition varible for trx write thread
+  pthread_cond_t cond_write;
+  /// mutex for trx write thread
+  pthread_mutex_t mutex_write;
+} openair0_thread_t;
+
 /*!\brief structure holds the parameters to configure USRP devices */
 struct openair0_device_t {
+  /*!tx write thread*/
+  openair0_thread_t write_thread;
+
   /*!brief Module ID of this device */
   int Mod_id;
 
@@ -400,6 +428,12 @@ struct openair0_device_t {
    * \param arg pointer to capabilities or configuration
    */
   void (*configure_rru)(int idx, void *arg);
+
+  /*! \brief RRU Configuration callback
+   * \param idx RU index
+   * \param arg pointer to capabilities or configuration
+   */
+  int (*trx_write_init)(openair0_device *device);
 };
 
 /* type of device init function, implemented in shared lib */
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
index 95d00290271..0f2147847a6 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
@@ -30,6 +30,9 @@
 * \warning
 */
 
+#ifndef __ETHERNET_USERSPACE_LIB_IF_DEFS__H__
+#define __ETHERNET_USERSPACE_LIB_IF_DEFS__H__
+
 #include <netinet/ether.h>
 #include <stdint.h>
 
@@ -37,15 +40,11 @@
 #include "PHY/LTE_TRANSPORT/if5_tools.h"
 
 // ETH transport preference modes
-#ifdef OCP_FRAMEWORK
-#include "enums.h"
-#else
 #define ETH_UDP_MODE        0
 #define ETH_RAW_MODE        1
 #define ETH_UDP_IF4p5_MODE    2
 #define ETH_RAW_IF4p5_MODE    3
 #define ETH_RAW_IF5_MOBIPASS    4    
-#endif
 
 // COMMOM HEADER LENGTHS
 
@@ -84,3 +83,5 @@
 #define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280
 #define RAW_IF5_MOBIPASS_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES)
 #define PAYLOAD_MOBIPASS_NUM_SAMPLES  640
+
+#endif
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index f37c8cf5cf5..08f0cd720b0 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -50,6 +50,8 @@
 #include "common_lib.h"
 #include "assertions.h"
 
+#include "common/utils/LOG/vcd_signal_dumper.h"
+
 #include <sys/resource.h>
 
 #ifdef __SSE4_1__
@@ -341,37 +343,13 @@ static int trx_usrp_write(openair0_device *device,
 
   int flags_lsb = flags&0xff;
   int flags_msb = (flags>>8)&0xff;
-    
-#if defined(__x86_64) || defined(__i386__)
-  #ifdef __AVX2__
-      nsamps2 = (nsamps+7)>>3;
-      __m256i buff_tx[8][nsamps2];
-  #else
-    nsamps2 = (nsamps+3)>>2;
-    __m128i buff_tx[8][nsamps2];
-  #endif
-#elif defined(__arm__)
-    nsamps2 = (nsamps+3)>>2;
-    int16x8_t buff_tx[8][nsamps2];
-#else
-#error Unsupported CPU architecture, USRP device cannot be built
-#endif
 
-  // bring RX data into 12 LSBs for softmodem RX
-  for (int i=0; i<cc; i++) {
-    for (int j=0; j<nsamps2; j++) {
-#if defined(__x86_64__) || defined(__i386__)
-#ifdef __AVX2__
-      buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4);
-#else
-      buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4);
-#endif
-#elif defined(__arm__)
-      buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4);
-#endif
-    }
-  }
+  int end;
+  int write_tread = 0;
+  openair0_thread_t *write_thread = &device->write_thread;
+  openair0_write_package_t *write_package = write_thread->write_package;
 
+  AssertFatal( MAX_WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", MAX_WRITE_THREAD_BUFFER_SIZE);
 
     boolean_t first_packet_state=false,last_packet_state=false;
 
@@ -404,7 +382,37 @@ static int trx_usrp_write(openair0_device *device,
      last_packet_state  = true;
     }
 
-    
+  if(write_tread == 0){
+#if defined(__x86_64) || defined(__i386__)
+  #ifdef __AVX2__
+      nsamps2 = (nsamps+7)>>3;
+      __m256i buff_tx[8][nsamps2];
+  #else
+    nsamps2 = (nsamps+3)>>2;
+    __m128i buff_tx[8][nsamps2];
+  #endif
+#elif defined(__arm__)
+    nsamps2 = (nsamps+3)>>2;
+    int16x8_t buff_tx[8][nsamps2];
+#else
+#error Unsupported CPU architecture, USRP device cannot be built
+#endif
+
+    // bring RX data into 12 LSBs for softmodem RX
+    for (int i=0; i<cc; i++) {
+      for (int j=0; j<nsamps2; j++) {
+#if defined(__x86_64__) || defined(__i386__)
+#ifdef __AVX2__
+        buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4);
+#else
+        buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4);
+#endif
+#elif defined(__arm__)
+        buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4);
+#endif
+      }
+    }
+
     s->tx_md.has_time_spec  = true;
     s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state;
     s->tx_md.end_of_burst   = last_packet_state;
@@ -432,11 +440,170 @@ static int trx_usrp_write(openair0_device *device,
       ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
     }
 
-  if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps);
+    if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps);
+    return ret;
+  }
+  else{
+    pthread_mutex_lock(&write_thread->mutex_write);
+
+    if(write_thread->count_write >= MAX_WRITE_THREAD_PACKAGE){
+      LOG_W(HW,"Buffer overflow, count_write = %d, start = %d end = %d, resetting write package\n", write_thread->count_write, write_thread->start, write_thread->end);
+      write_thread->end = write_thread->start;
+      write_thread->count_write = 0;
+    }
+
+    end = write_thread->end;
+    write_package[end].timestamp    = timestamp;
+    write_package[end].nsamps       = nsamps;
+    write_package[end].cc           = cc;
+    write_package[end].first_packet = first_packet_state;
+    write_package[end].last_packet  = last_packet_state;
+    write_package[end].flags_msb    = flags_msb;
+    for (int i = 0; i < cc; i++)
+      write_package[end].buff[i]    = buff[i];
+    write_thread->count_write++;
+    write_thread->end = (write_thread->end + 1)% MAX_WRITE_THREAD_PACKAGE;
+    pthread_cond_signal(&write_thread->cond_write);
+    pthread_mutex_unlock(&write_thread->mutex_write);
+    return 0;
+  }
 
-  return ret;
 }
 
+//-----------------------start--------------------------
+/*! \brief Called to send samples to the USRP RF target
+      @param device pointer to the device structure specific to the RF hardware target
+      @param timestamp The timestamp at which the first sample MUST be sent
+      @param buff Buffer which holds the samples
+      @param nsamps number of samples to be sent
+      @param antenna_id index of the antenna if the device has multiple antennas
+      @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+*/
+void *trx_usrp_write_thread(void * arg){ 
+  int ret=0;
+  openair0_device *device=(openair0_device *)arg;
+  openair0_thread_t *write_thread = &device->write_thread;
+  openair0_write_package_t *write_package = write_thread->write_package;
+
+  usrp_state_t *s;
+  int nsamps2;  // aligned to upper 32 or 16 byte boundary
+  int start;
+  openair0_timestamp timestamp;
+  void               **buff;
+  int                nsamps;
+  int                cc;
+  signed char        first_packet;
+  signed char        last_packet;
+  int                flags_msb;
+
+  while(1){
+    pthread_mutex_lock(&write_thread->mutex_write);
+    while (write_thread->count_write == 0) {
+      pthread_cond_wait(&write_thread->cond_write,&write_thread->mutex_write); // this unlocks mutex_rxtx while waiting and then locks it again
+    }
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 1 );
+    s = (usrp_state_t *)device->priv;
+    start = write_thread->start;
+    timestamp    = write_package[start].timestamp;
+    buff         = write_package[start].buff;
+    nsamps       = write_package[start].nsamps;
+    cc           = write_package[start].cc;
+    first_packet = write_package[start].first_packet;
+    last_packet  = write_package[start].last_packet;
+    flags_msb    = write_package[start].flags_msb;
+    write_thread->start = (write_thread->start + 1)% MAX_WRITE_THREAD_PACKAGE;
+    write_thread->count_write--;
+    pthread_mutex_unlock(&write_thread->mutex_write);
+    /*if(write_thread->count_write != 0){
+      LOG_W(HW,"count write = %d, start = %d, end = %d\n", write_thread->count_write, write_thread->start, write_thread->end);
+    }*/
+
+    #if defined(__x86_64) || defined(__i386__)
+      #ifdef __AVX2__
+        nsamps2 = (nsamps+7)>>3;
+        __m256i buff_tx[8][nsamps2];
+      #else
+        nsamps2 = (nsamps+3)>>2;
+        __m128i buff_tx[8][nsamps2];
+      #endif
+    #elif defined(__arm__)
+      nsamps2 = (nsamps+3)>>2;
+      int16x8_t buff_tx[8][nsamps2];
+    #else
+    #error Unsupported CPU architecture, USRP device cannot be built
+    #endif
+
+    // bring RX data into 12 LSBs for softmodem RX
+    for (int i=0; i<cc; i++) {
+      for (int j=0; j<nsamps2; j++) {
+        #if defined(__x86_64__) || defined(__i386__)
+          #ifdef __AVX2__
+            buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4);
+          #else
+            buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4);
+          #endif
+        #elif defined(__arm__)
+          buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4);
+        #endif
+      }
+    }
+
+    
+    s->tx_md.has_time_spec  = true;
+    s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet;
+    s->tx_md.end_of_burst   = last_packet;
+    s->tx_md.time_spec      = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
+    s->tx_count++;
+
+    // bit 3 enables gpio (for backward compatibility)
+    if (flags_msb&8) {
+      // push GPIO bits 7-9 from flags_msb
+      int gpio789=(flags_msb&7)<<7;
+      s->usrp->set_command_time(s->tx_md.time_spec);
+      s->usrp->set_gpio_attr("FP0", "OUT", gpio789, 0x380);
+      s->usrp->clear_command_time();
+    }
+
+    if (cc>1) {
+      std::vector<void *> buff_ptrs;
+
+      for (int i=0; i<cc; i++)
+        buff_ptrs.push_back(&(((int16_t *)buff_tx[i])[0]));
+
+      ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md);
+    } 
+    else {
+      ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
+    }
+
+    if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps);
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret );
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 );
+
+    if(0) break;
+  }
+
+  return NULL;
+}
+
+int trx_write_init(openair0_device *device){
+
+  uhd::set_thread_priority_safe(1.0);
+  openair0_thread_t *write_thread = &device->write_thread;
+  printf("initializing tx write thread\n");
+
+  write_thread->start              = 0;
+  write_thread->end                = 0;
+  write_thread->count_write        = 0;
+  printf("end of tx write thread\n");
+
+  pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device);
+
+  return(0);
+}
+
+//---------------------end-------------------------
+
 /*! \brief Receive samples from hardware.
  * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
  * the first channel. *ptimestamp is the time at which the first sample
@@ -765,6 +932,7 @@ extern "C" {
     device->trx_stop_func  = trx_usrp_stop;
     device->trx_set_freq_func = trx_usrp_set_freq;
     device->trx_set_gains_func   = trx_usrp_set_gains;
+    device->trx_write_init = trx_write_init;
 
 
     // hotfix! to be checked later
@@ -835,22 +1003,16 @@ extern "C" {
   
     if (args.find("clock_source")==std::string::npos) {
 	if (openair0_cfg[0].clock_source == internal) {
-	  //in UHD 3.14 we could use
-	  //s->usrp->set_sync_source("clock_source=internal","time_source=internal");
-	  s->usrp->set_time_source("internal");
 	  s->usrp->set_clock_source("internal");
-	  LOG_D(HW,"Setting time and clock source to internal\n");
+	  LOG_D(HW,"Setting clock source to internal\n");
 	}
 	else if (openair0_cfg[0].clock_source == external ) {
-	  //s->usrp->set_sync_source("clock_source=external","time_source=external");
-	  s->usrp->set_time_source("external");
 	  s->usrp->set_clock_source("external");
-	  LOG_D(HW,"Setting time and clock source to external\n");
+	  LOG_D(HW,"Setting clock source to external\n");
 	}
 	else if (openair0_cfg[0].clock_source==gpsdo) {
 	  s->usrp->set_clock_source("gpsdo");
-	  s->usrp->set_time_source("gpsdo");
-	  LOG_D(HW,"Setting time and clock source to gpsdo\n");
+	  LOG_D(HW,"Setting clock source to gpsdo\n");
 	}
 	else { 
 	  LOG_W(HW,"Clock source set neither in usrp_args nor on command line, using default!\n");
@@ -861,7 +1023,31 @@ extern "C" {
 	  LOG_W(HW,"Clock source set in both usrp_args and in clock_source, ingnoring the latter!\n");
 	}
   }
-  
+
+    if (args.find("time_source")==std::string::npos) {
+	if (openair0_cfg[0].time_source == internal) {
+	  s->usrp->set_time_source("internal");
+	  LOG_D(HW,"Setting time source to internal\n");
+	}
+	else if (openair0_cfg[0].time_source == external ) {
+	  s->usrp->set_time_source("external");
+	  LOG_D(HW,"Setting time source to external\n");
+	}
+	else if (openair0_cfg[0].time_source==gpsdo) {
+	  s->usrp->set_time_source("gpsdo");
+	  LOG_D(HW,"Setting time source to gpsdo\n");
+	}
+	else { 
+	  LOG_W(HW,"Time source set neither in usrp_args nor on command line, using default!\n");
+	}
+    }
+    else {
+	if (openair0_cfg[0].clock_source != unset) {
+	  LOG_W(HW,"Time source set in both usrp_args and in time_source, ingnoring the latter!\n");
+	}
+  }
+
+    
   if (s->usrp->get_clock_source(0) == "gpsdo") {
     s->use_gps = 1;
   
@@ -1061,7 +1247,9 @@ extern "C" {
   //s->usrp->set_time_source("external");
   // display USRP settings
   LOG_I(HW,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6);
-  sleep(1);
+  LOG_I(HW,"Actual clock source %s...\n",s->usrp->get_clock_source(0).c_str());
+  LOG_I(HW,"Actual time source %s...\n",s->usrp->get_time_source(0).c_str());
+   sleep(1);
   // create tx & rx streamer
   uhd::stream_args_t stream_args_rx("sc16", "sc16");
   int samples=openair0_cfg[0].sample_rate;
diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md
index e3ce219d736..421cc662bb2 100644
--- a/targets/ARCH/rfsimulator/README.md
+++ b/targets/ARCH/rfsimulator/README.md
@@ -3,6 +3,12 @@ This is an RF simulator that allows to test OAI without an RF board. It replaces
 
 As much as possible, it works like an RF board, but not in real-time: It can run faster than real-time if there is enough CPU, or slower (it is CPU-bound instead of real-time RF sampling-bound).
 
+It can be run either in:
+
+- "noS1" mode: the generated IP traffic is sent and received between gNB and UE IP tunnel interfaces ("oaitun") by applications like ping and iperf
+- "phy-test" mode: random UL and DL traffic is generated at every scheduling opportunity 
+
+
 # build
 
 ## From [build_oai](../../../doc/BUILD.md) script
@@ -84,19 +90,40 @@ make rfsimulator
 ### Launch gNB in one window
 
 ```bash
-sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
+sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD --rfsim --phy-test
 ```
 
 ### Launch UE in another window
 
 ```bash
-sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 
+sudo RFSIMULATOR=<TARGET_GNB_INTERFACE_ADDRESS> ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path ../../../ci-scripts/rrc-files 
 ```
+Note:
+1. <TARGET_GNB_INTERFACE_ADDRESS> can be 127.0.0.1 if both gNB and nrUE executables run on the same host, OR the IP interface address of the remote host running the gNB executable, if the gNB and nrUE run on separate hosts
+2. the --rrc_config_path parameter can be omitted (but not necessarily) if the gNB and nrUE run on the same host, in which case the gNB provides the nrUE with the necessary rrc configuration
+3. to enable the noS1 mode --noS1 and --nokrnmod 1 options should be added to the command line
 
-Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine.
 
 In the UE, you can add `-d` option to get the softscope.
 
+### Testing IP traffic (ping and iperf)
+
+```
+ping -I oaitun_enb1 10.0.1.2 (from gNB mchine)
+ping -I oaitun_ue1 10.0.1.1 (from nrUE mchine)
+``` 
+
+```iperf (Downlink):
+Server nrUE machine: iperf -s -i 1 -u -B 10.0.1.2
+Client gNB machine: iperf -c 10.0.1.2 -u -b 0.1M --bind 10.0.1.1
+```
+
+```iperf (Uplink):
+Server gNB machine: iperf -s -i 1 -u -B 10.0.1.1
+Client nrUE machine: iperf -c 10.0.1.1 -u -b 0.1M --bind 10.0.1.2
+Note: iperf tests can be performed only when running gNB and nrUE on separate hosts. 
+```
+
 ### Store and replay
 
 You can store emitted I/Q samples. If you set the option `saviq`, the simulator will write all the I/Q samples into this file. Then, you can replay with the executable `replay_node`.
diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/targets/ARCH/rfsimulator/apply_channelmod.c
index ef4e564343f..faf84bb0aaa 100644
--- a/targets/ARCH/rfsimulator/apply_channelmod.c
+++ b/targets/ARCH/rfsimulator/apply_channelmod.c
@@ -1,7 +1,24 @@
 /*
-  Author: Laurent THOMAS, Open Cells for Nokia
-  copyleft: OpenAirInterface Software Alliance and it's licence
-
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
 
 
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 54dfd3b888a..222a3e9f80f 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -1,8 +1,27 @@
 /*
-  Author: Laurent THOMAS, Open Cells for Nokia
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* 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
 */
 
+
 /*
  * Open issues and limitations
  * The read and write should be called in the same thread, that is not new USRP UHD design
@@ -33,7 +52,7 @@
 #include <openair1/SIMULATION/TOOLS/sim.h>
 
 #define PORT 4043 //default TCP port for this simulator
-#define CirSize 3072000 // 100ms is enough
+#define CirSize 307200 // 100ms is enough
 #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
 #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
 
@@ -346,7 +365,8 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
   if ( t->lastWroteTS != 0 && abs((double)t->lastWroteTS-timestamp) > (double)CirSize)
     LOG_E(HW,"Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp);
 
-  AssertFatal(t->lastWroteTS <= timestamp+1, " Not supported to send Tx out of order (same in USRP) %lu, %lu\n",
+  if (t->lastWroteTS > timestamp+nsamps)
+    LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n",
               t->lastWroteTS, timestamp);
   t->lastWroteTS=timestamp+nsamps;
 
@@ -420,7 +440,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
       if ( sz < 0 ) {
         if ( errno != EAGAIN ) {
           LOG_E(HW,"socket failed %s\n", strerror(errno));
-          abort();
+          //abort();
         }
       } else if ( sz == 0 )
         continue;
@@ -439,11 +459,15 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
         b->headerMode=false;
 
         if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS
-          t->nextTimestamp  = b->th.timestamp > nsamps_for_initial ? b->th.timestamp - nsamps_for_initial : 0;
-          b->lastReceivedTS = b->th.timestamp > nsamps_for_initial ? b->th.timestamp : nsamps_for_initial;
-          LOG_W(HW,"UE got first timestamp: starting at %lu\n",  t->nextTimestamp);
-          b->trashingPacket=true;
-        } else if ( b->lastReceivedTS < b->th.timestamp) {
+	  t->nextTimestamp=b->th.timestamp> nsamps_for_initial ?
+	    b->th.timestamp -  nsamps_for_initial :
+	    0;
+	  b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ?
+	    b->th.timestamp :
+	    nsamps_for_initial;
+	  LOG_W(HW,"UE got first timestamp: starting at %lu\n",  t->nextTimestamp);
+	  b->trashingPacket=true;
+	} else if ( b->lastReceivedTS < b->th.timestamp) {
           int nbAnt= b->th.nbAnt;
 	  
           for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
@@ -463,8 +487,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
         } else if ( b->lastReceivedTS == b->th.timestamp ) {
           // normal case
         } else {
-          abort();
-          AssertFatal(false, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
+          LOG_E(HW, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp);
+	  b->trashingPacket=true;
         }
 
         pthread_mutex_lock(&Sockmutex);
@@ -655,6 +679,9 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf
 int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
   return 0;
 }
+int rfsimulator_write_init(openair0_device *device){
+  return 0;
+}
 __attribute__((__visibility__("default")))
 int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   // to change the log level, use this on command line
@@ -678,6 +705,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
   device->type = USRP_B200_DEV;
   device->openair0_cfg=&openair0_cfg[0];
   device->priv = rfsimulator;
+  device->trx_write_init = rfsimulator_write_init;
 
   for (int i=0; i<FD_SETSIZE; i++)
     rfsimulator->buf[i].conn_sock=-1;
diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c
index 2b77c5322de..73f6321ffeb 100644
--- a/targets/ARCH/rfsimulator/stored_node.c
+++ b/targets/ARCH/rfsimulator/stored_node.c
@@ -1,8 +1,27 @@
 /*
-  Author: Laurent THOMAS, Open Cells
-  copyleft: OpenAirInterface Software Alliance and it's licence
+* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The OpenAirInterface Software Alliance licenses this file to You under
+* the OAI Public License, Version 1.1  (the "License"); you may not use this file
+* except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.openairinterface.org/?page_id=698
+*
+* Author and copyright: Laurent Thomas, open-cells.com
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*-------------------------------------------------------------------------------
+* For more information about the OpenAirInterface (OAI) Software Alliance:
+*      contact@openairinterface.org
 */
 
+
 #include <common/utils/simple_executable.h>
 
 volatile int             oai_exit = 0;
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index cbbd30b62ca..4d57ab4e166 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -41,6 +41,7 @@
 # include "f1ap_du_task.h"
 # include "enb_app.h"
 # include "openair2/LAYER2/MAC/mac_proto.h"
+#include <executables/split_headers.h> 
 
 extern RAN_CONTEXT_t RC;
 
@@ -59,12 +60,12 @@ int create_tasks(uint32_t enb_nb) {
   rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL);
   AssertFatal(rc >= 0, "Create task for RRC eNB failed\n");
 
-  if (EPC_MODE_ENABLED) {
+  if (EPC_MODE_ENABLED && ! ( split73==SPLIT73_DU ) ) {
     rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL);
     AssertFatal(rc >= 0, "Create task for SCTP failed\n");
   }
 
-  if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) {
+  if (EPC_MODE_ENABLED && !NODE_IS_DU(type) && ! ( split73==SPLIT73_DU ) ) {
     rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL);
     AssertFatal(rc >= 0, "Create task for S1AP failed\n");
     if (!(get_softmodem_params()->emulate_rf)){
diff --git a/targets/COMMON/create_tasks_mbms.h b/targets/COMMON/create_tasks_mbms.h
deleted file mode 100644
index 843897cefb4..00000000000
--- a/targets/COMMON/create_tasks_mbms.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1  (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- *      contact@openairinterface.org
- */
-
-#ifndef CREATE_TASKS_H_
-#define CREATE_TASKS_H_
-
-/* External declaration of L2L1 task that depend on the target */
-extern void *l2l1_task(void *arg);
-
-int create_tasks(uint32_t enb_nb);
-int create_tasks_ue(uint32_t ue_nb);
-int create_tasks_mbms(uint32_t enb_nb);
-
-#endif /* CREATE_TASKS_H_ */
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index 904a4556007..fed15739cf5 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -237,8 +237,8 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-	 sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2";
-         #clock_src = "external";
+	 sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+         clock_src = "external";
     }
 );  
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index f5e2298a997..08bfeea7eec 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -237,7 +237,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 114;
          eNB_instances  = [0];
-	 sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2";
+	 sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
          clock_src = "external";
     }
 );  
diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw
index e6726e7d9fe..6ece894bb61 100644
--- a/targets/RT/USER/gNB_usrp.gtkw
+++ b/targets/RT/USER/gNB_usrp.gtkw
@@ -1,21 +1,25 @@
 [*]
 [*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI
-[*] Tue Dec 17 15:31:51 2019
+[*] Wed Mar  4 14:05:43 2020
 [*]
-[dumpfile] "/tmp/gNB.vcd"
-[dumpfile_mtime] "Tue Dec 17 15:25:49 2019"
-[dumpfile_size] 6343431
+[dumpfile] "/tmp/gNB_trx_thread.vcd"
+[dumpfile_mtime] "Wed Mar  4 14:05:10 2020"
+[dumpfile_size] 10750468
 [savefile] "/home/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw"
-[timestart] 1517712000
-[size] 1920 1018
-[pos] -9 -33
-*-19.276148 1518358451 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[timestart] 31148700000
+[size] 1916 1002
+[pos] -1 -25
+*-23.852516 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 [sst_width] 386
 [signals_width] 344
 [sst_expanded] 1
-[sst_vpaned_height] 267
+[sst_vpaned_height] 262
 @28
 functions.trx_read
+functions.trx_write_thread
+@25
+variables.trx_write_flags[63:0]
+@28
 functions.trx_write
 @420
 variables.frame_number_TX0_UE[63:0]
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 8c5c50836f8..147bc955aeb 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -235,10 +235,10 @@ static inline int rxtx(PHY_VARS_eNB *eNB,
     new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
     dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
     // L2-emulator can work only one eNB.
-    //      memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
-    //      memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
-    memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
-    memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
+    //      memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+    //      memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
+    memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+    memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
     AssertFatal((ret= pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd, return %d\n",ret);
     ru->proc.instance_pre_scd++;
 
@@ -261,7 +261,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,
   eNB->UL_INFO.subframe  = proc->subframe_rx;
   eNB->UL_INFO.module_id = eNB->Mod_id;
   eNB->UL_INFO.CC_id     = eNB->CC_id;
-  eNB->if_inst->UL_indication(&eNB->UL_INFO);
+  eNB->if_inst->UL_indication(&eNB->UL_INFO, proc);
   AssertFatal((ret= pthread_mutex_unlock(&eNB->UL_INFO_mutex))==0,"error unlocking UL_INFO_mutex, return %d\n",ret);
   /* this conflict resolution may be totally wrong, to be tested */
   /* CONFLICT RESOLUTION: BEGIN */
@@ -851,9 +851,7 @@ void init_eNB_proc(int inst) {
 
   for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
     eNB = RC.eNB[inst][CC_id];
-#ifndef OCP_FRAMEWORK
     LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
-#endif
     proc = &eNB->proc;
     L1_proc                        = &proc->L1_proc;
     L1_proc_tx                     = &proc->L1_proc_tx;
@@ -1247,9 +1245,7 @@ void init_eNB(int single_thread_flag,
       eNB->abstraction_flag   = 0;
       eNB->single_thread_flag = single_thread_flag;
       LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
-#ifndef OCP_FRAMEWORK
       LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
-#endif
       LOG_I(PHY,"Registering with MAC interface module\n");
       AssertFatal((eNB->if_inst         = IF_Module_init(inst))!=NULL,"Cannot register interface");
       eNB->if_inst->schedule_response   = schedule_response;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index e6364cad237..d2e734f2055 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1405,7 +1405,6 @@ void fill_rf_config(RU_t *ru,
   cfg->num_rb_dl=fp->N_RB_DL;
   cfg->tx_num_channels=ru->nb_tx;
   cfg->rx_num_channels=ru->nb_rx;
-  cfg->clock_source=get_softmodem_params()->clock_source;
 
   for (int i=0; i<ru->nb_tx; i++) {
     cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
@@ -1866,8 +1865,8 @@ static void *ru_thread( void *param ) {
 #if defined(PRE_SCD_THREAD)
         new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
         dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
-        memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
-        memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
+        memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+        memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
         AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd\n");
         ru->proc.instance_pre_scd++;
 
@@ -2234,9 +2233,7 @@ void init_RU_proc(RU_t *ru) {
   RU_proc_t *proc;
   pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL;
   //pthread_attr_t *attr_fep=NULL;
-#ifndef OCP_FRAMEWORK
   LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
-#endif
   proc = &ru->proc;
   memset((void *)proc,0,sizeof(RU_proc_t));
   proc->ru = ru;
@@ -2683,7 +2680,7 @@ void set_function_spec_param(RU_t *ru) {
 //extern void RCconfig_RU(void);
 
 
-void init_RU(char *rf_config_file, clock_source_t clock_source, clock_source_t time_source, int send_dmrssync) {
+void init_RU(char *rf_config_file, int send_dmrssync) {
   int ru_id, i, CC_id;
   RU_t *ru;
   PHY_VARS_eNB *eNB0     = (PHY_VARS_eNB *)NULL;
@@ -2718,8 +2715,6 @@ void init_RU(char *rf_config_file, clock_source_t clock_source, clock_source_t t
     ru->south_out_cnt = 0;
     // use eNB_list[0] as a reference for RU frame parameters
     // NOTE: multiple CC_id are not handled here yet!
-    ru->openair0_cfg.clock_source = clock_source;
-    ru->openair0_cfg.time_source  = time_source;
 
     //ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
     if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
@@ -2956,6 +2951,27 @@ void RCconfig_RU(void) {
           LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
         }
       }
+      else {
+	RC.ru[j]->openair0_cfg.clock_source = unset;
+      }
+
+      if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) {
+        if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = internal;
+          LOG_D(PHY, "RU time source set as internal\n");
+        } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = external;
+          LOG_D(PHY, "RU time source set as external\n");
+        } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) {
+          RC.ru[j]->openair0_cfg.time_source = gpsdo;
+          LOG_D(PHY, "RU time source set as gpsdo\n");
+        } else {
+          LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr));
+        }
+      }
+      else {
+	RC.ru[j]->openair0_cfg.time_source = unset;
+      }      
 
       if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
         if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 0b365ea938e..d8c5e255939 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -80,7 +80,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 //#include "PHY/TOOLS/time_meas.h"
 
 #ifndef OPENAIR2
-#include "UTIL/OTG/otg_vars.h"
+  #include "UTIL/OTG/otg_vars.h"
 #endif
 
 
@@ -93,6 +93,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 
 #include "lte-softmodem.h"
 #include "NB_IoT_interface.h"
+#include <executables/split_headers.h>
 
 
 pthread_cond_t nfapi_sync_cond;
@@ -152,6 +153,13 @@ int otg_enabled;
 
 uint64_t num_missed_slots=0; // counter for the number of missed slots
 
+int split73=0;
+void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
+void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
+  AssertFatal(false, "Must not be called in this context\n");
+}
 
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
@@ -170,7 +178,7 @@ eth_params_t *eth_params;
 double cpuf;
 
 int oaisim_flag=0;
-//threads_t threads= {-1,-1,-1,-1,-1,-1,-1,-1};
+
 
 /* forward declarations */
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
@@ -435,7 +443,7 @@ int restart_L1L2(module_id_t enb_id) {
   set_function_spec_param(RC.ru[enb_id]);
   /* reset the list of connected UEs in the MAC, since in this process with
    * loose all UEs (have to reconnect) */
-  init_UE_list(&RC.mac[enb_id]->UE_list);
+  init_UE_info(&RC.mac[enb_id]->UE_info);
   LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
 
   if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
@@ -539,7 +547,7 @@ int main ( int argc, char **argv )
   cpuf=get_cpu_freq_GHz();
   printf("ITTI init, useMME: %i\n",EPC_MODE_ENABLED);
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
-
+  // allows to forward in wireshark L2 protocol for decoding
   // initialize mscgen log after ITTI
   if (get_softmodem_params()->start_msc) {
     load_module_shlib("msc",NULL,0,&msc_interface);
@@ -547,8 +555,6 @@ int main ( int argc, char **argv )
 
   MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
   init_opt();
-  // to make a graceful exit when ctrl-c is pressed
-  set_softmodem_sighandler();
   check_clock();
 #ifndef PACKAGE_VERSION
 #  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
@@ -579,11 +585,11 @@ int main ( int argc, char **argv )
     for (i = 0; i < RC.nb_inst; i++) {
       flexran_agent_start(i);
     }
-
+    
     /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks
      * for monolithic/F1 modes */
-    init_pdcp();
-
+   init_pdcp();
+    
     if (create_tasks(1) < 0) {
       printf("cannot create ITTI tasks\n");
       exit(-1);
@@ -607,7 +613,7 @@ int main ( int argc, char **argv )
     ctxt.subframe = 0;
     pdcp_run(&ctxt);
   }
-    
+
   /* start threads if only L1 or not a CU */
   if (RC.nb_inst == 0 || !NODE_IS_CU(node_type) || NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) {
     // init UE_PF_PO and mutex lock
@@ -618,31 +624,44 @@ int main ( int argc, char **argv )
     pthread_mutex_init(&sync_mutex, NULL);
 
     rt_sleep_ns(10*100000000ULL);
-    
+
     if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
       LOG_I(ENB_APP,"NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
       pthread_cond_init(&sync_cond,NULL);
       pthread_mutex_init(&sync_mutex, NULL);
     }
-    
+
     if (NFAPI_MODE==NFAPI_MODE_VNF) {// VNF
 #if defined(PRE_SCD_THREAD)
       init_ru_vnf();  // ru pointer is necessary for pre_scd.
 #endif
       wait_nfapi_init("main?");
     }
-    
+
     LOG_I(ENB_APP,"START MAIN THREADS\n");
     // start the main threads
     number_of_cards = 1;
     printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
-    
+
     if (RC.nb_L1_inst > 0) {
       printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
       init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync);
-      //      for (inst=0;inst<RC.nb_L1_inst;inst++)
-      //  for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
     }
+    for (int x=0; x < RC.nb_L1_inst; x++) 
+      for (int CC_id=0; CC_id<RC.nb_L1_CC[x]; CC_id++) {
+        L1_rxtx_proc_t *L1proc= &RC.eNB[x][CC_id]->proc.L1_proc;
+	L1proc->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
+        L1proc->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+        L1proc->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+        if ( strlen(get_softmodem_params()->threadPoolConfig) > 0 )
+         initTpool(get_softmodem_params()->threadPoolConfig, L1proc->threadPool, true);
+        else
+         initTpool("n", L1proc->threadPool, true);
+      initNotifiedFIFO(L1proc->respEncode);
+      initNotifiedFIFO(L1proc->respDecode);
+    }
+
+
   }
 
   printf("wait_eNBs()\n");
@@ -654,29 +673,29 @@ int main ( int argc, char **argv )
   // some initialization is necessary and init_ru_vnf do this.
   if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) {
     printf("Initializing RU threads\n");
-    init_RU(get_softmodem_params()->rf_config_file,get_softmodem_params()->clock_source,get_softmodem_params()->timing_source,get_softmodem_params()->send_dmrs_sync);
+    init_RU(get_softmodem_params()->rf_config_file,get_softmodem_params()->send_dmrs_sync);
     
     for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
       RC.ru[ru_id]->rf_map.card=0;
       RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset);
     }
-    
+
     config_sync_var=0;
-    
+
     if (NFAPI_MODE==NFAPI_MODE_PNF) { // PNF
       wait_nfapi_init("main?");
     }
-    
+
     printf("wait RUs\n");
-    // CI -- Flushing the std outputs for the previous marker to show on the eNB / RRU log file
+    // end of CI modifications
     fflush(stdout);
     fflush(stderr);
-    // end of CI modifications
+    // wait_RUs() is wrong and over complex!
     wait_RUs();
     LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU);
     // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
     printf("ALL RUs ready - init eNBs\n");
-
+    
     if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) {
       LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n");
       init_eNB_afterRU();
@@ -723,7 +742,7 @@ int main ( int argc, char **argv )
     for (int inst = 0; inst < NB_eNB_INST; inst++) {
       for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) {
 	free_transport(RC.eNB[inst][cc_id]);
-	phy_free_lte_eNB(RC.eNB[inst][cc_id]);
+        phy_free_lte_eNB(RC.eNB[inst][cc_id]);
       }
     }
 
@@ -741,17 +760,17 @@ int main ( int argc, char **argv )
 
     for(ru_id=0; ru_id<RC.nb_RU; ru_id++) {
       if (RC.ru[ru_id]->rfdevice.trx_end_func) {
-	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
-	RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
+        RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
+        RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
       }
 
       if (RC.ru[ru_id]->ifdevice.trx_end_func) {
-	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
-	RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
+        RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
+        RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
       }
     }
   }
-   
+
   terminate_opt();
   logClean();
   printf("Bye.\n");
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 5e1bf361605..c5fdb5f5468 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -81,7 +81,6 @@
 #define CONFIG_HLP_DLSHIFT       "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
 #define CONFIG_HLP_USRP_ARGS     "set the arguments to identify USRP (same syntax as in UHD)\n"
 #define CONFIG_HLP_DMAMAP        "sets flag for improved EXMIMO UE performance\n"
-#define CONFIG_HLP_CLK           "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
 #define CONFIG_HLP_TDD           "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
 #define CONFIG_HLP_TADV          "Set timing_advance\n"
 
@@ -115,7 +114,6 @@
     {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT,     0,               iptr:(int32_t *)&dlsch_demod_shift, defintval:0,          TYPE_INT,      0},   \
     {"usrp-args",         CONFIG_HLP_USRP_ARGS,   0,               strptr:(char **)&usrp_args,         defstrval:"type=b200",TYPE_STRING,   0},   \
     {"mmapped-dma",       CONFIG_HLP_DMAMAP,      PARAMFLAG_BOOL,  uptr:&mmapped_dma,                  defintval:0,          TYPE_INT,      0},   \
-    {"clock-source",      CONFIG_HLP_CLK,         0,               iptr:&clock_source,                 defintval:0,          TYPE_INT,      0},   \
     {"T" ,                CONFIG_HLP_TDD,         PARAMFLAG_BOOL,  iptr:&tddflag,                      defintval:0,          TYPE_INT,      0},   \
     {"A",                 CONFIG_HLP_TADV,        0,               iptr:&(timingadv),                  defintval:0,          TYPE_INT,      0}    \
   }
@@ -169,7 +167,7 @@ extern void init_RU_proc(RU_t *ru);
 extern void stop_RU(int nb_ru);
 extern void kill_RU_proc(RU_t *ru);
 extern void set_function_spec_param(RU_t *ru);
-extern void init_RU(char *, clock_source_t clock_source, clock_source_t time_source, int send_dmrssync);
+extern void init_RU(char *, int send_dmrssync);
 
 // In lte-ue.c
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 75ed0184346..0962bb6a2d4 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -589,7 +589,7 @@ static void *UE_thread_synch(void *arg)
         LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
 
         if (initial_sync( UE, UE->mode ) == 0) {
-          LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
+          LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n",
                  (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti,
                  freq_offset,
                  UE->rx_total_gain_dB,
@@ -714,7 +714,7 @@ static void *UE_thread_synch(void *arg)
             }
           }
 
-          LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
+          LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %lu, UL %lu)\n",
                 freq_offset,
                 UE->rx_total_gain_dB,
                 downlink_frequency[0][0]+freq_offset,
@@ -1108,6 +1108,50 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
       }
     }
 
+    if (dl_config_req && tx_request_pdu_list) {
+      nfapi_dl_config_request_body_t* dl_config_req_body = &dl_config_req->dl_config_request_body;
+      for (int i = 0; i < dl_config_req_body->number_pdu; ++i) {
+        nfapi_dl_config_request_pdu_t* pdu = &dl_config_req_body->dl_config_pdu_list[i];
+        if (pdu->pdu_type ==  NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) {
+          i += 1;
+          AssertFatal(i < dl_config_req->dl_config_request_body.number_pdu,
+                      "Need PDU following DCI at index %d, but not found\n",
+                      i);
+          nfapi_dl_config_request_pdu_t *dlsch = &dl_config_req_body->dl_config_pdu_list[i];
+          if (dlsch->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) {
+            LOG_E(MAC, "expected DLSCH PDU at index %d\n", i);
+            continue;
+          }
+          dl_config_req_UE_MAC_dci(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),
+                                   NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
+                                   pdu,
+                                   dlsch,
+                                   ue_num);
+        } else if (pdu->pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) {
+          dl_config_req_UE_MAC_bch(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),
+                                   NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
+                                   pdu,
+                                   ue_num);
+        } else if (pdu->pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE) {
+          dl_config_req_UE_MAC_mch(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),
+                                   NFAPI_SFNSF2SF(dl_config_req->sfn_sf),
+                                   pdu,
+                                   ue_num);
+        }
+      }
+    }
+
+    if (hi_dci0_req) {
+      nfapi_hi_dci0_request_body_t *hi_dci0_body = &hi_dci0_req->hi_dci0_request_body;
+      for (int i = 0; i < hi_dci0_body->number_of_dci + hi_dci0_body->number_of_hi; i++) {
+        nfapi_hi_dci0_request_pdu_t* pdu = &hi_dci0_body->hi_dci0_pdu_list[i];
+        hi_dci0_req_UE_MAC(NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf),
+                           NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf),
+                           pdu,
+                           ue_num);
+      }
+    }
+
     //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) {
     for (ue_index=0; ue_index < ue_num; ue_index++) {
       ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index;
@@ -1136,15 +1180,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
 
         phy_procedures_UE_SL_RX(UE,proc);
 
-        if (dl_config_req!=NULL && tx_request_pdu_list!=NULL) {
-          //if(dl_config_req!= NULL) {
-          dl_config_req_UE_MAC(dl_config_req, ue_Mod_id);
-        }
-
-        if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) {
-          hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id);
-        }
-
         if(NFAPI_MODE!=NFAPI_UE_STUB_PNF)
           phy_procedures_UE_SL_TX(UE,proc);
       }
@@ -1183,7 +1218,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg)
           if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH  && ue_Mod_id == next_Mod_id) {
             next_ra_frame++;
 
-            if(next_ra_frame > 200) {
+            if(next_ra_frame > 500) {
               // check if we have PRACH opportunity
               if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) &&  UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
                 // The one working strangely...
@@ -1413,12 +1448,14 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg)
       oai_subframe_ind(timer_frame, timer_subframe);
 
       if(dl_config_req!= NULL) {
-        dl_config_req_UE_MAC(dl_config_req, Mod_id);
+        AssertFatal(0, "dl_config_req_UE_MAC() not handled\n");
+        //dl_config_req_UE_MAC(dl_config_req, Mod_id);
       }
 
       //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){
       if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) {
-        hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id);
+        AssertFatal(0, "hi_dci0_req_UE_MAC() not handled\n");
+        //hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id);
         //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
         free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
         hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
@@ -1525,12 +1562,12 @@ void write_dummy(PHY_VARS_UE *UE,  openair0_timestamp timestamp) {
   for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++)
     samplesVoid[i]=(void *)&v;
   
-  AssertFatal(1 == UE->rfdevice.trx_write_func(&UE->rfdevice,
-                      timestamp+2*UE->frame_parms.samples_per_tti,
-                      samplesVoid, 
-                      1,
-                      UE->frame_parms.nb_antennas_tx,
-                      1),"");
+  AssertFatal( 1 == UE->rfdevice.trx_write_func(&UE->rfdevice,
+						timestamp+2*UE->frame_parms.samples_per_tti,
+						samplesVoid, 
+						1,
+						UE->frame_parms.nb_antennas_tx,
+						1),"");
 }
 
 void *UE_thread(void *arg)
@@ -1581,36 +1618,36 @@ void *UE_thread(void *arg)
     int instance_cnt_synch = UE->proc.instance_cnt_synch;
     int is_synchronized    = UE->is_synchronized;
     AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-
+    
     if (is_synchronized == 0) {
       if (instance_cnt_synch < 0) {  // we can invoke the synch
         // grab 10 ms of signal and wakeup synch thread
 
         if (UE->mode != loop_through_memory) {
-          if (IS_SOFTMODEM_RFSIM) {
-            for(int sf=0; sf<10; sf++) {
-              for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-                rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf];
-
+          if (IS_SOFTMODEM_RFSIM ) {
+	    for(int sf=0; sf<10; sf++) {
+	      for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+		rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.samples_per_tti*sf];
+	      
               AssertFatal(UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice,
-                              &timestamp,
-                              rxp,
-                              UE->frame_parms.samples_per_tti,
-                              UE->frame_parms.nb_antennas_rx), "");
-              write_dummy(UE, timestamp);
-            }
-          } else {
-            for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
-              rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
-
-            AssertFatal( UE->frame_parms.samples_per_tti*10 ==
+						      &timestamp,
+						      rxp,
+						      UE->frame_parms.samples_per_tti,
+						      UE->frame_parms.nb_antennas_rx), "");
+	      write_dummy(UE, timestamp);
+	    }
+	  } else {
+	    for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
+	      rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
+	    
+	    AssertFatal( UE->frame_parms.samples_per_tti*10 ==
                          UE->rfdevice.trx_read_func(&UE->rfdevice,
                                                     &timestamp,
                                                     rxp,
                                                     UE->frame_parms.samples_per_tti*10,
                                                     UE->frame_parms.nb_antennas_rx), "");
-          }
-        }
+	      }
+	}
 
         AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
         instance_cnt_synch = ++UE->proc.instance_cnt_synch;
@@ -1640,10 +1677,10 @@ void *UE_thread(void *arg)
                                        rxp,
                                        UE->frame_parms.samples_per_tti,
                                        UE->frame_parms.nb_antennas_rx);
-            if (IS_SOFTMODEM_RFSIM )
-              write_dummy(UE, timestamp);
-          }
-        }
+	    if (IS_SOFTMODEM_RFSIM )
+	      write_dummy(UE, timestamp);
+	  }
+	  }
 #endif
       }
     } // UE->is_synchronized==0
@@ -1654,17 +1691,17 @@ void *UE_thread(void *arg)
         if (UE->mode != loop_through_memory) {
           if (UE->no_timing_correction==0) {
             LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
-            while ( UE->rx_offset ) {
-              size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti);
+	    while ( UE->rx_offset ) {
+	      size_t s=min(UE->rx_offset,UE->frame_parms.samples_per_tti);
               AssertFatal(s == UE->rfdevice.trx_read_func(&UE->rfdevice,
-                             &timestamp,
-                             (void **)UE->common_vars.rxdata,
-                             s,
-                             UE->frame_parms.nb_antennas_rx),"");
-              if (IS_SOFTMODEM_RFSIM )
-                write_dummy(UE, timestamp);
-              UE->rx_offset-=s;
-            }
+						     &timestamp,
+						     (void **)UE->common_vars.rxdata,
+						     s,
+						     UE->frame_parms.nb_antennas_rx),"");
+	      if (IS_SOFTMODEM_RFSIM )
+		write_dummy(UE, timestamp);
+	      UE->rx_offset-=s;
+	    }
           }
 
           UE->rx_offset=0;
@@ -1705,7 +1742,7 @@ void *UE_thread(void *arg)
 
             pthread_mutex_unlock(&proc->mutex_rxtx);
           }
-          usleep(300);
+	  usleep(300);
         }
 
         LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
@@ -2071,7 +2108,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
     txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) );
 
     for (i=0; i<frame_parms->nb_antennas_rx; i++) {
-      LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
+      LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %lu on card %d, chain %d\n",
             CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
       free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
       rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
@@ -2079,7 +2116,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
     }
 
     for (i=0; i<frame_parms->nb_antennas_tx; i++) {
-      LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
+      LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %lu on card %d, chain %d\n",
             CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
       free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
       txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 25371260bf9..2c9271888bd 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -113,10 +113,6 @@ uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75,
 
 volatile int             oai_exit = 0;
 
-
-clock_source_t clock_source = internal,time_source=internal;
-
-
 unsigned int                    mmapped_dma=0;
 
 
@@ -285,13 +281,13 @@ void exit_function(const char *file, const char *function, const int line, const
 extern int16_t dlsch_demod_shift;
 
 static void get_options(void) {
-  int CC_id;
-  int tddflag = 0;
-  char *loopfile = NULL;
-  int dumpframe = 0;
-  int timingadv = 0;
+  int CC_id=0;
+  int tddflag=0;
+  char *loopfile=NULL;
+  int dumpframe=0;
+  int timingadv=0;
   uint8_t nfapi_mode = NFAPI_MONOLITHIC;
-  int simL1flag = 0;
+  int simL1flag =0;
 
   set_default_frame_parms(frame_parms);
   CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
@@ -467,7 +463,8 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) {
 
     openair0_cfg[card].Mod_id = 0;
     openair0_cfg[card].num_rb_dl=frame_parms->N_RB_DL;
-    openair0_cfg[card].clock_source = clock_source;
+    openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
+    openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
     openair0_cfg[card].tx_num_channels=min(2,frame_parms->nb_antennas_tx);
     openair0_cfg[card].rx_num_channels=min(2,frame_parms->nb_antennas_rx);
 
diff --git a/targets/RT/USER/rfsim.c b/targets/RT/USER/rfsim.c
index bd8305682c6..a9a09124333 100644
--- a/targets/RT/USER/rfsim.c
+++ b/targets/RT/USER/rfsim.c
@@ -64,7 +64,7 @@ sim_t sim;
 
 void init_ru_devices(void);
 
-void init_RU(char *,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync);
+void init_RU(char *,int send_dmrssync);
 
 void *rfsim_top(void *n_frames);
 
@@ -101,7 +101,7 @@ void RCConfig_sim(void) {
   RC.nb_RU     = RUParamList.numelt;
   AssertFatal(RC.nb_RU>0,"we need at least 1 RU for simulation\n");
   printf("returned with %d rus\n",RC.nb_RU);
-  init_RU(NULL,internal,internal,0);
+  init_RU(NULL,0);
   printf("Waiting for RUs to get set up\n");
   wait_RUs();
   init_ru_devices();
-- 
GitLab