diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e58b19b2ba..f0e0ecb4b9 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -27,8 +27,8 @@ cmake_minimum_required (VERSION 2.8) # Base directories, compatible with legacy OAI building ################################################ set (OPENAIR_DIR $ENV{OPENAIR_DIR}) -#set (NFAPI_DIR $ENV{NFAPI_DIR}) -set (NFAPI_DIR ${OPENAIR_DIR}/nfapi) +set (NFAPI_DIR ${OPENAIR_DIR}/nfapi/open-nFAPI) +set (NFAPI_USER_DIR ${OPENAIR_DIR}/nfapi/oai_integration) set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1) set (OPENAIR2_DIR ${OPENAIR_DIR}/openair2) set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3) @@ -262,9 +262,6 @@ if (${ENABLE_ITTI}) set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) endif (${ENABLE_ITTI}) -add_boolean_option(RTAI False "Use RTAI") - - ############################# # ASN.1 grammar C code generation & dependancies ################################ @@ -485,7 +482,6 @@ include_directories ("${X2AP_DIR}") ################################### add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") -add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR") @@ -587,15 +583,13 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}") add_boolean_option(ENABLE_SECURITY True "Enable LTE integrity and ciphering between RRC UE and eNB") add_boolean_option(ENABLE_USE_MME True "eNB connected to MME (INTERFACE S1-C), not standalone eNB") add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO") -add_boolean_option(USER_MODE True "????") 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(DISABLE_USE_NAS False "???") add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only valid without deadline scheduler). It is enabled only with >2 CPUs") add_boolean_option(NAS_ADDRESS_FIX False "specific to oaisim: for nasmesh driver") -add_boolean_option(NAS_NETLINK False "???? Must be True to compile nasmesh driver without rtai") +add_boolean_option(NAS_NETLINK False "useless ??? Must be True to compile nasmesh driver without rtai ????") add_boolean_option(OAISIM False "specific to oaisim") add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") @@ -613,22 +607,12 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w ########################## add_boolean_option(ENB_MODE True "Swap the include directories between openair2 and openair3" ) -########################## -# Emulation options -########################## -add_boolean_option(ENABLE_PGM_TRANSPORT False "specific to oaisim, emulation through ethernet, reliable multicast") -add_boolean_option(ADDR_CONF False "specific to oaisim, IP autoconf of user-plane IP interface") -add_boolean_option(OPENAIR_EMU False "specific to oaisim") -add_boolean_option(OAI_EMU False "specific to oaisim") -add_boolean_option(PHY_ABSTRACTION False "specific to oaisim") - ########################## # SCHEDULING/REAL-TIME/PERF options ########################## add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME True "Add data in vcd traces: disable it if perf issues") add_boolean_option(ENABLE_VCD True "always true now, time measurements of proc calls and var displays") add_boolean_option(ENABLE_VCD_FIFO True "time measurements of proc calls and var displays sent to FIFO (one more thread)") -add_boolean_option(HARD_RT False "???") add_boolean_option(LINUX False "used in weird memcpy() in pdcp.c ???") add_boolean_option(LINUX_LIST False "used only in lists.c: either use OAI implementation of lists or Linux one (should be True, but it is False") add_boolean_option(LOG_NO_THREAD True "Disable thread for log, seems always set to true") @@ -638,24 +622,15 @@ add_boolean_option(OPENAIR_LTE True "Seems legacy: keep it to true") # PHY options ########################## add_boolean_option(DRIVER2013 True "only relevant for EXMIMO") -add_boolean_option(ENABLE_FXP True "????") add_boolean_option(ENABLE_NEW_MULTICAST False "specific to oaisim") add_boolean_option(EXMIMO_IOT True "????") add_boolean_option(LARGE_SCALE False "specific to oaisim: defines max eNB=2 and max UE=120") add_boolean_option(LOCALIZATION False "???") add_integer_option(MAX_NUM_CCs 1 "????") add_boolean_option(MU_RECEIVER False "????") -add_boolean_option(NEW_FFT True "????") -add_boolean_option(OPENAIR1 True "????") -add_boolean_option(PBS_SIM False "????") -add_boolean_option(PC_DSP True "????") -add_boolean_option(PC_TARGET True "????") -add_boolean_option(PERFECT_CE False "????") add_boolean_option(PHYSIM True "for L1 simulators (dlsim, ulsim, ...)") add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim") add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim") -add_boolean_option(PUCCH True "????") -add_boolean_option(RANDOM_BF False "????") add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator") add_boolean_option(DEBUG_PHY False "Enable PHY layer debugging options") add_boolean_option(DEBUG_PHY_PROC False "Enable debugging of PHY layer procedures") @@ -728,23 +703,7 @@ add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "Otherwise it is UM, confi ########################## # none -########################## -# PROJECTS (IST, FRENCH COLL., etc) -# SPECIFIC OPTIONS -########################## -add_boolean_option(SPECTRA False "???") -add_boolean_option(MIH_C_MEDIEVAL_EXTENSIONS False "EXTENSIONS TO MIH 802.21 IN CONTEXT OF IST PROJECT CALLED MEDIEVAL") - - - -add_boolean_option(EMOS False "????") -if(${EMOS}) - add_definitions("-D_FILE_OFFSET_BITS=64") - set(EMOS_LIB gps) -endif(${EMOS}) - - - # add the binary tree to the search path for include files +# add the binary tree to the search path for include files ####################################################### # We will find ConfigOAI.h after generation in target directory include_directories("${OPENAIR_BIN_DIR}") @@ -770,9 +729,13 @@ else() include_directories("${OPENAIR2_DIR}/UTIL") include_directories("${OPENAIR2_DIR}/UTIL/LOG") endif() -include_directories("${NFAPI_DIR}") +include_directories("${NFAPI_DIR}/nfapi/public_inc") +include_directories("${NFAPI_DIR}/common/public_inc") +include_directories("${NFAPI_DIR}/pnf/public_inc") +include_directories("${NFAPI_DIR}/nfapi/inc") +include_directories("${NFAPI_DIR}/sim_common/inc") +include_directories("${NFAPI_DIR}/pnf_sim/inc") include_directories("${OPENAIR1_DIR}") -include_directories("${OPENAIR2_DIR}/NAS") include_directories("${OPENAIR2_DIR}") include_directories("${OPENAIR2_DIR}/LAYER2/RLC") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0") @@ -1012,6 +975,58 @@ set(SCHED_SRC ) add_library(SCHED_LIB ${SCHED_SRC}) +# nFAPI +################################# +set(NFAPI_COMMON_SRC + ${NFAPI_DIR}/common/src/debug.c +) +add_library(NFAPI_COMMON_LIB ${NFAPI_COMMON_SRC}) + +include_directories(${NFAPI_DIR}/common/public_inc) + +set(NFAPI_SRC + ${NFAPI_DIR}/nfapi/src/nfapi.c + ${NFAPI_DIR}/nfapi/src/nfapi_p4.c + ${NFAPI_DIR}/nfapi/src/nfapi_p5.c + ${NFAPI_DIR}/nfapi/src/nfapi_p7.c +) +add_library(NFAPI_LIB ${NFAPI_SRC}) + +include_directories(${NFAPI_DIR}/nfapi/public_inc) +include_directories(${NFAPI_DIR}/nfapi/inc) + +set(NFAPI_PNF_SRC + ${NFAPI_DIR}/pnf/src/pnf.c + ${NFAPI_DIR}/pnf/src/pnf_interface.c + ${NFAPI_DIR}/pnf/src/pnf_p7.c + ${NFAPI_DIR}/pnf/src/pnf_p7_interface.c +) +add_library(NFAPI_PNF_LIB ${NFAPI_PNF_SRC}) + +include_directories(${NFAPI_DIR}/pnf/public_inc) +include_directories(${NFAPI_DIR}/pnf/inc) + +set(NFAPI_VNF_SRC + ${NFAPI_DIR}/vnf/src/vnf.c + ${NFAPI_DIR}/vnf/src/vnf_interface.c + ${NFAPI_DIR}/vnf/src/vnf_p7.c + ${NFAPI_DIR}/vnf/src/vnf_p7_interface.c +) +add_library(NFAPI_VNF_LIB ${NFAPI_VNF_SRC}) + +include_directories(${NFAPI_DIR}/vnf/public_inc) +include_directories(${NFAPI_DIR}/vnf/inc) + +# nFAPI user defined code +############################# +set(NFAPI_USER_SRC + ${NFAPI_USER_DIR}/nfapi.c + ${NFAPI_USER_DIR}/nfapi_pnf.c + ${NFAPI_USER_DIR}/nfapi_vnf.c +) +add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC}) +include_directories(${NFAPI_USER_DIR}) + # Layer 1 ############################# set(PHY_SRC @@ -1207,6 +1222,8 @@ add_library(L2 ${ENB_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) +include_directories(${NFAPI_USER_DIR}) + if (FLEXRAN_AGENT_SB_IF) #Test for adding a shared library @@ -1244,26 +1261,6 @@ if (${ENABLE_RAL}) set(RAL_LIB RAL) endif() -if(${MIH_C_MEDIEVAL_EXTENSIONS}) - set(MIH_SRC - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_header_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_msg_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_primitive_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F1_basic_data_types_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F2_general_data_types_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F3_data_types_for_address_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F4_data_types_for_links_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F9_data_types_for_qos_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_F13_data_types_for_information_elements_codec.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_L2_type_values_for_tlv_encoding.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_Medieval_extensions.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C_bit_buffer.c - ${RAL_LTE_DIR}INTERFACE-802.21/C/MIH_C.c - ) - add_library(MIH ${MIH_SRC}) - set(MIH_LIB MIH) -endif() - # CN libs ########################## @@ -1613,13 +1610,19 @@ ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c #${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c -${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/pgm_link.c ) add_library(OPENAIR0_LIB ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c ) +include_directories("${NFAPI_DIR}/nfapi/public_inc") +include_directories("${NFAPI_DIR}/common/public_inc") +include_directories("${NFAPI_DIR}/pnf/public_inc") +include_directories("${NFAPI_DIR}/nfapi/inc") +include_directories("${NFAPI_DIR}/sim_common/inc") +include_directories("${NFAPI_DIR}/pnf_sim/inc") + # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # or cmake provide a generic interface to pkg-config that widely used @@ -1778,7 +1781,6 @@ add_executable(lte-softmodem ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${GTPU_need_ITTI} - ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${T_SOURCE} @@ -1786,10 +1788,12 @@ add_executable(lte-softmodem ${SHLIB_LOADER_SOURCES} ) -target_link_libraries (lte-softmodem -ldl +target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - -Wl,--end-group ) + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB + NFAPI_USER_LIB + -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) @@ -1815,7 +1819,6 @@ add_executable(lte-softmodem-nos1 ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/common/utils/system.c - ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${T_SOURCE} @@ -1824,7 +1827,7 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 -Wl,--end-group ) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) @@ -1832,27 +1835,6 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) -# rrh -################################ -#Note: only one RF type (USRP) is currently supported for RRH -add_executable(rrh_gw - ${OPENAIR_TARGETS}/RT/USER/rrh_gw.c - ${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c - ${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c - ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${T_SOURCE} - ) -target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti) -target_link_libraries(rrh_gw - -Wl,--start-group - UTIL LFDS -ldl - -Wl,--end-group ) -target_link_libraries (rrh_gw rt pthread m ) -target_link_libraries (rrh_gw ${LIB_LMS_LIBRARIES}) -target_link_libraries (rrh_gw ${T_LIB}) - - # USIM process ################# #add_executable(usim @@ -1916,18 +1898,19 @@ add_executable(oaisim target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim -Wl,-ldl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB + NFAPI_USER_LIB -Wl,--end-group ) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) -target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp - ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) +target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp z + ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) target_link_libraries (oaisim ${T_LIB}) - # A all in one network simulator ################ add_executable(oaisim_nos1 @@ -1960,7 +1943,7 @@ add_executable(oaisim_nos1 target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER) target_link_libraries (oaisim_nos1 -Wl,--start-group - RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} SIMU SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 -Wl,--end-group ) target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) @@ -2068,7 +2051,7 @@ endforeach(myExe) if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) - lte-softmodem lte-softmodem-nos1 rrh_gw oaisim oaisim_nos1 + lte-softmodem lte-softmodem-nos1 oaisim oaisim_nos1 dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim #all "add_library" definitions @@ -2076,7 +2059,7 @@ if (${T_TRACER}) oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA - SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL MIH CN_UTILS + SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB) if (TARGET ${i}) add_dependencies(${i} generate_T) @@ -2138,7 +2121,6 @@ get_directory_property(DirDefs COMPILE_DEFINITIONS ) foreach( d ${DirDefs} ) set(module_cc_opt_tmp "${module_cc_opt_tmp} -D${d}") endforeach() -string(REPLACE "-DUSER_MODE" "" module_cc_opt ${module_cc_opt_tmp}) get_directory_property( DirDefs INCLUDE_DIRECTORIES ) foreach( d ${DirDefs} ) set(module_cc_opt "${module_cc_opt} -I${d}") @@ -2170,15 +2152,7 @@ endfunction(make_driver name dir src) # nashmesh module ################ list(APPEND nasmesh_src device.c common.c ioctl.c classifier.c tool.c mesh.c) -# Actually nasty stuff to be FIXED: the hereafter flag is for RTAI compilation in the driver, -# but has different meaning in the other parts of the code -# We should change the constant name to xxx_RTAI or likely -if(NOT ${module_cc_opt} MATCHES "DRTAI") - set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK") -else() - string(REPLACE "-DNAS_NETLINK" "" tmp "${module_cc_opt}") - set(module_cc_opt ${tmp}) -endif() +set(module_cc_opt "${module_cc_opt} -DNAS_NETLINK -DPDCP_USE_NETLINK") # legacy Makefile was using NAS_NETLINK flag, but other drivers the hereafter flag # so, this cmake use OAI_NW_DRIVER_USE_NETLINK everywhere if (OAI_NW_DRIVER_USE_NETLINK) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 51a0d47006..fb81a0a268 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -101,8 +101,6 @@ Options Specify conf_nvram_path (default \"$conf_nvram_path\") --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") ---RRH - Makes the RRH -a | --agent Enables agent for software-defined control of the eNB -r | --3gpp-release @@ -200,7 +198,7 @@ function main() { GDB=1 CMAKE_BUILD_TYPE="Debug" echo_info "Will Compile with gdb symbols and disable compiler optimization" - CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug" + CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug --trace-expand" shift;; --eNB) eNB=1 @@ -224,10 +222,6 @@ function main() { --UE-gen-nvram) gen_nvram_path=$(readlink -f $2) shift 2;; - --RRH) - RRH=1 - echo_info "Will compile RRH" - shift;; -r | --3gpp-release) REL=$2 echo_info "Setting release to: $REL" @@ -376,7 +370,7 @@ function main() { echo_info "CMAKE_CMD=$CMAKE_CMD" ######################################################### - # check validity of HW and TP parameters for RRH and eNB + # check validity of HW and TP parameters for eNB ######################################################### # to be discussed @@ -392,15 +386,6 @@ function main() { fi fi - if [ "$RRH" = "1" ] ; then - if [ "$TP" = "None" ] ; then - echo_fatal "A transport protocol (e.g. -t ETHERNET) must be defined!" - fi - if [ "$HW" = "None" ] ; then - echo_info "No radio head has been selected (HW set to $HW)" - fi - fi - echo_info "RF HW set to $HW" #Now we set flags to enable deadline scheduler settings #By default: USRP: disable, @@ -801,36 +786,6 @@ function main() { # oaisim_mme $dbin/oaisim_mme.$REL fi - # RRH compilation - ##################### - if [ "$RRH" = "1" ] ; then - - rrh_exec=rrh_gw - rrh_build_dir=rrh_gw - - echo_info "Compiling $rrh_exec ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build - mkdir -p $DIR/$rrh_build_dir/build - cmake_file=$DIR/$rrh_build_dir/CMakeLists.txt - echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file - echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file - echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file - echo "set ( ENABLE_ITTI False )" >> $cmake_file - echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file - echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file - echo 'set ( PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file - echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >>$cmake_file - echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file - echo "set ( T_TRACER $T_TRACER )" >> $cmake_file - echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file - cd $DIR/$rrh_build_dir/build - eval $CMAKE_CMD - compilations \ - rrh_gw rrh_gw \ - rrh_gw $dbin/rrh_gw - - fi # Telnet server compilation ##################### if [ "$BUILD_TELNETSRV" = "1" ] ; then @@ -849,13 +804,9 @@ function main() { fi # build RF device and transport protocol libraries ##################################### - if [ "$eNB" = "1" -o "$UE" = "1" -o "$RRH" = "1" ] ; then + if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - build_dir=$lte_build_dir - else - build_dir=$rrh_build_dir - fi + build_dir=$lte_build_dir # build RF device libraries if [ "$HW" != "None" ] ; then diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template index 76defbc7d7..e046bb7539 100644 --- a/cmake_targets/epc_test/CMakeLists.template +++ b/cmake_targets/epc_test/CMakeLists.template @@ -2,17 +2,13 @@ cmake_minimum_required(VERSION 2.8) set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) set ( ASN_DEBUG False) -set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) -set ( EMOS False ) set ( EMIT_ASN_DEBUG False ) -set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_PGM_TRANSPORT True ) set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) set ( ENABLE_USE_CPU_EXECUTION_TIME True ) @@ -21,7 +17,6 @@ set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True) set ( ENABLE_VCD_FIFO False ) set ( ENB_MODE True ) set ( EXMIMO_IOT True ) -set ( HARD_RT False ) set ( JUMBO_FRAME True ) set ( LARGE_SCALE False ) set ( LINK_ENB_PDCP_TO_GTPV1U True) @@ -33,7 +28,6 @@ set ( DEADLINE_SCHEDULER False ) set ( MAC_CONTEXT 1 ) set ( MAX_NUM_CCs 1 ) set ( MESSAGE_CHART_GENERATOR False) -set ( MIH_C_MEDIEVAL_EXTENSIONS False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) set ( NAS_ADDRESS_FIX False ) @@ -42,38 +36,25 @@ set ( NAS_MME False ) set ( NAS_UE True ) set ( NB_ANTENNAS_RX "2" ) set ( NB_ANTENNAS_TX "2" ) -set ( NB_ANTENNAS_TXRX "2" ) -set ( NEW_FFT True ) set ( NO_RRM True ) -set ( OAI_EMU False ) set ( OAISIM False ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR1 True ) set ( OPENAIR2 True ) set ( OPENAIR_LTE True ) set ( PACKAGE_NAME "epc_test" ) -set ( PBS_SIM False ) set ( PDCP_USE_NETLINK True ) -set ( PC_DSP True ) -set ( PC_TARGET True ) set ( PDCP_MSG_PRINT False ) -set ( PERFECT_CE False ) -set ( PHY_ABSTRACTION True ) set ( PHY_CONTEXT False ) set ( PHY_EMUL False ) set ( PHYSIM True ) -set ( PUCCH True ) -set ( RANDOM_BF False ) set ( RF_BOARD "False" ) set ( RLC_STOP_ON_LOST_PDU False ) set ( RRC_ASN1_VERSION "Rel10" ) set ( RRC_DEFAULT_RAB_IS_AM True) set ( RRC_MSG_PRINT False ) -set ( RTAI False ) set ( SECU False ) set ( SMBV False ) set ( TEST_OMG False ) set ( USE_MME "R10" ) -set ( USER_MODE True ) set ( XER_PRINT True ) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index ab718a8503..ca754449d7 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -6,9 +6,6 @@ set(XFORMS True) set(ENABLE_ITTI False) set(DEBUG_PHY False) set(MU_RECIEVER False) -set(RANDOM_BF False) -set(PBS_SIM False) -set(PERFECT_CE True) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) diff --git a/cmake_targets/oaisim_build_oai/CMakeLists.template b/cmake_targets/oaisim_build_oai/CMakeLists.template index 0a05d68d10..22faac75b5 100644 --- a/cmake_targets/oaisim_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_build_oai/CMakeLists.template @@ -1,16 +1,12 @@ cmake_minimum_required(VERSION 2.8) set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) -set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) -set ( EMOS False ) -set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_PGM_TRANSPORT True ) set ( ENABLE_RAL False ) set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) @@ -20,7 +16,6 @@ set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True) set ( ENABLE_VCD_FIFO False ) set ( ENB_MODE True ) set ( EXMIMO_IOT True ) -set ( HARD_RT False ) set ( JUMBO_FRAME True ) set ( LARGE_SCALE False ) set ( LINK_ENB_PDCP_TO_GTPV1U True) @@ -32,7 +27,6 @@ set ( DEADLINE_SCHEDULER False ) set ( MAC_CONTEXT 1 ) set ( MAX_NUM_CCs 1 ) set ( MESSAGE_CHART_GENERATOR False) -set ( MIH_C_MEDIEVAL_EXTENSIONS False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) set ( NAS_ADDRESS_FIX False ) @@ -41,40 +35,26 @@ set ( NAS_MME False ) set ( NAS_UE True ) set ( NB_ANTENNAS_RX "2" ) set ( NB_ANTENNAS_TX "2" ) -set ( NB_ANTENNAS_TXRX "2" ) -set ( NEW_FFT True ) set ( NO_RRM True ) -set ( OAI_EMU True ) set ( OAISIM True ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR1 True ) set ( OPENAIR2 True ) set ( OPENAIR_LTE True ) set ( PACKAGE_NAME "oaisim" ) -set ( PBS_SIM False ) set ( PDCP_USE_NETLINK True ) -set ( PC_DSP True ) -set ( PC_TARGET True ) set ( PDCP_MSG_PRINT False ) -set ( PERFECT_CE False ) -set ( PHY_ABSTRACTION True ) set ( PHY_CONTEXT False ) set ( PHY_EMUL False ) set ( PHYSIM True ) -set ( PUCCH True ) -set ( RANDOM_BF False ) set ( RF_BOARD "False" ) set ( RLC_STOP_ON_LOST_PDU False ) set ( RRC_ASN1_VERSION "Rel10" ) set ( RRC_DEFAULT_RAB_IS_AM True) set ( RRC_MSG_PRINT False ) -set ( RTAI False ) set ( SECU False ) set ( SMBV False ) -set ( SPECTRA False ) set ( TEST_OMG False ) set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) set ( USE_MME "R10" ) -set ( USER_MODE True ) set ( XER_PRINT False ) diff --git a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template index 69fa209b16..b18b23ee9a 100644 --- a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template @@ -1,16 +1,12 @@ cmake_minimum_required(VERSION 2.8) set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) -set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 False ) -set ( EMOS False ) -set ( ENABLE_FXP False ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING False ) set ( ENABLE_NEW_MULTICAST False ) -set ( ENABLE_PGM_TRANSPORT False ) set ( ENABLE_RAL False ) set ( ENABLE_SECURITY False ) set ( ENABLE_STANDALONE_EPC False ) @@ -21,7 +17,6 @@ set ( ENABLE_VCD_FIFO False ) set ( ENB_MODE False ) set ( EPC_BUILD True ) set ( EXMIMO_IOT False ) -set ( HARD_RT False ) set ( JUMBO_FRAME False ) set ( LARGE_SCALE False ) set ( LINK_ENB_PDCP_TO_GTPV1U True) @@ -32,7 +27,6 @@ set ( LOG_NO_THREAD False ) set ( DEADLINE_SCHEDULER False ) set ( MAC_CONTEXT 1 ) set ( MAX_NUM_CCs 1 ) -set ( MIH_C_MEDIEVAL_EXTENSIONS False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) set ( NAS_ADDRESS_FIX False ) @@ -42,42 +36,27 @@ set ( NAS_NETLINK False ) set ( NAS_UE False ) set ( NB_ANTENNAS_RX "2" ) set ( NB_ANTENNAS_TX "2" ) -set ( NB_ANTENNAS_TXRX "2" ) -set ( NEW_FFT False ) set ( NO_RRM False ) -set ( OAI_EMU False ) set ( OAISIM False ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK False ) -set ( OPENAIR1 False ) set ( OPENAIR2 False ) -set ( OPENAIR_EMU False ) set ( OPENAIR_LTE False ) set ( PACKAGE_NAME "EPC" ) -set ( PBS_SIM False ) -set ( PC_DSP False ) -set ( PC_TARGET False ) set ( PDCP_MSG_PRINT False ) -set ( PERFECT_CE False ) -set ( PHY_ABSTRACTION False ) set ( PHY_CONTEXT False ) set ( PHY_EMUL False ) set ( PHYSIM False ) -set ( PUCCH False ) -set ( RANDOM_BF False ) set ( RF_BOARD "False" ) set ( RRC_ASN1_VERSION "Rel10" ) set ( RLC_STOP_ON_LOST_PDU False ) set ( RRC_MSG_PRINT False ) -set ( RTAI False ) set ( SECU False ) set ( SMBV False ) -set ( SPECTRA False ) set ( TEST_OMG False ) set ( UPDATE_RELEASE_9 True) set ( UPDATE_RELEASE_10 True) set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) set ( USE_MME "R10" ) -set ( USER_MODE True ) set ( XER_PRINT False ) set ( XFORMS False ) diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template index 8e1670ea43..e0f100ca0a 100644 --- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template @@ -1,15 +1,11 @@ cmake_minimum_required(VERSION 2.8) -set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) -set ( EMOS False ) -set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING False ) set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_PGM_TRANSPORT True ) set ( ENABLE_RAL False ) set ( ENABLE_SECURITY False ) set ( ENABLE_STANDALONE_EPC False) @@ -19,7 +15,6 @@ set ( ENABLE_USE_RAW_SOCKET_FOR_SGI False) set ( ENABLE_VCD_FIFO False ) set ( ENB_MODE True ) set ( EXMIMO_IOT True ) -set ( HARD_RT False ) set ( JUMBO_FRAME True ) set ( LARGE_SCALE False ) set ( LINK_ENB_PDCP_TO_GTPV1U False) @@ -33,7 +28,6 @@ set ( MAX_NUM_CCs 1 ) set ( MESSAGE_CHART_GENERATOR False ) set ( MESSAGE_CHART_GENERATOR_RLC_MAC False ) set ( MESSAGE_CHART_GENERATOR_PHY False ) -set ( MIH_C_MEDIEVAL_EXTENSIONS False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) set ( NAS_ADDRESS_FIX True ) @@ -42,42 +36,27 @@ set ( NAS_MME False ) set ( NAS_UE False ) set ( NB_ANTENNAS_RX "2" ) set ( NB_ANTENNAS_TX "2" ) -set ( NB_ANTENNAS_TXRX "2" ) -set ( NEW_FFT True ) set ( NO_RRM True ) -set ( OAI_EMU True ) set ( OAISIM True ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR1 True ) set ( OPENAIR2 True ) -set ( OPENAIR_EMU False ) set ( OPENAIR_LTE True ) set ( PACKAGE_NAME "oaisim" ) -set ( PBS_SIM False ) set ( PDCP_USE_NETLINK True ) -set ( PC_DSP True ) -set ( PC_TARGET True ) set ( PDCP_MSG_PRINT False ) -set ( PERFECT_CE False ) -set ( PHY_ABSTRACTION True ) set ( PHY_CONTEXT False ) set ( PHY_EMUL False ) set ( PHYSIM True ) -set ( PUCCH True ) -set ( RANDOM_BF False ) set ( RF_BOARD "False" ) set ( RRC_ASN1_VERSION "Rel10" ) set ( RLC_STOP_ON_LOST_PDU False ) set ( RRC_MSG_PRINT False ) -set ( RTAI False ) set ( SECU False ) set ( SMBV False ) -set ( SPECTRA False ) set ( TEST_OMG False ) set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) set ( USE_MME "R10" ) -set ( USER_MODE True ) set ( XER_PRINT False ) set ( DEBUG_PHY False ) set ( DEBUG_PHY_PROC False) diff --git a/cmake_targets/s1c_mme_test/CMakeLists.template b/cmake_targets/s1c_mme_test/CMakeLists.template index 994edf8352..9f1ff3e360 100644 --- a/cmake_targets/s1c_mme_test/CMakeLists.template +++ b/cmake_targets/s1c_mme_test/CMakeLists.template @@ -1,17 +1,13 @@ cmake_minimum_required(VERSION 2.8) set ( CMAKE_BUILD_TYPE "RelWithDebInfo" ) -set ( ADDR_CONF False ) set ( DEBUG_OMG False ) set ( DISABLE_XER_PRINT False ) set ( DRIVER2013 True ) -set ( EMOS False ) -set ( ENABLE_FXP True ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) set ( ENABLE_PDCP_NETLINK_FIFO False ) -set ( ENABLE_PGM_TRANSPORT True ) set ( ENABLE_RAL False ) set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) @@ -21,7 +17,6 @@ set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True) set ( ENABLE_VCD_FIFO False ) set ( ENB_MODE True ) set ( EXMIMO_IOT True ) -set ( HARD_RT False ) set ( JUMBO_FRAME True ) set ( LARGE_SCALE False ) set ( LINK_ENB_PDCP_TO_GTPV1U True) @@ -33,7 +28,6 @@ set ( DEADLINE_SCHEDULER False ) set ( MAC_CONTEXT 1 ) set ( MAX_NUM_CCs 1 ) set ( MESSAGE_CHART_GENERATOR False) -set ( MIH_C_MEDIEVAL_EXTENSIONS False ) set ( MSG_PRINT False ) set ( MU_RECEIVER False ) set ( NAS_ADDRESS_FIX False ) @@ -42,44 +36,30 @@ set ( NAS_MME False ) set ( NAS_UE True ) set ( NB_ANTENNAS_RX "2" ) set ( NB_ANTENNAS_TX "2" ) -set ( NB_ANTENNAS_TXRX "2" ) -set ( NEW_FFT True ) set ( NO_RRM True ) -set ( OAI_EMU True ) set ( OAISIM True ) set ( OAI_NW_DRIVER_TYPE_ETHERNET False ) set ( OAI_NW_DRIVER_USE_NETLINK True ) -set ( OPENAIR1 True ) set ( OPENAIR2 True ) set ( OPENAIR_LTE True ) set ( PACKAGE_NAME "oaisim" ) -set ( PBS_SIM False ) set ( PDCP_USE_NETLINK True ) -set ( PC_DSP True ) -set ( PC_TARGET True ) set ( PDCP_MSG_PRINT False ) -set ( PERFECT_CE False ) -set ( PHY_ABSTRACTION True ) set ( PHY_CONTEXT False ) set ( PHY_EMUL False ) set ( PHYSIM True ) -set ( PUCCH True ) -set ( RANDOM_BF False ) set ( RF_BOARD "False" ) set ( RLC_STOP_ON_LOST_PDU False ) set ( RRC_ASN1_VERSION "Rel10" ) set ( RRC_DEFAULT_RAB_IS_AM True) set ( RRC_MSG_PRINT False ) -set ( RTAI False ) set ( SECU False ) set ( SMBV False ) -set ( SPECTRA False ) set ( TEST_OMG False ) set ( TEST_S1C_MME True ) set ( USE_3GPP_ADDR_AS_LINK_ADDR False ) set ( USE_MME "R10" ) -set ( USER_MODE True ) set ( XER_PRINT False ) set ( XFORMS False ) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 8cf0d22e91..1ea97c030f 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -95,6 +95,8 @@ get_distribution_release() { check_supported_distribution() { local distribution=$(get_distribution_release) case "$distribution" in + "ubuntu17.10") return 0 ;; + "ubuntu17.04") return 0 ;; "ubuntu16.04") return 0 ;; "ubuntu14.04") return 0 ;; "fedora24") return 0 ;; @@ -230,6 +232,7 @@ install_protobuf_c_from_source(){ rm -rf /tmp/protobuf-c git clone https://github.com/protobuf-c/protobuf-c.git cd protobuf-c + git checkout 2a46af42784abf86804d536f6e0122d47cfeea45 ./autogen.sh ./configure echo "Compiling protobuf-c" @@ -479,16 +482,26 @@ check_install_oai_software() { fi $SUDO $INSTALLER update -y if [[ "$OS_DISTRO" == "ubuntu" ]]; then + local LAPACK_LIBNAME="liblapack.so" + local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so" $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in "ubuntu14.04") - specific_packages="libtasn1-3-dev" + specific_packages="libtasn1-3-dev gccxml libgnutls-dev libatlas-dev" # For iperf3 $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe" $SUDO apt-get update ;; "ubuntu16.04") - specific_packages="libtasn1-6-dev" + specific_packages="libtasn1-6-dev gccxml libgnutls-dev libatlas-dev" + ;; + "ubuntu17.04") + specific_packages="libtasn1-6-dev castxml libgnutls28-dev libatlas-dev" + ;; + "ubuntu17.10") + specific_packages="libtasn1-6-dev castxml libgnutls28-dev" + LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" + LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" ;; esac $SUDO apt-get install -y \ @@ -504,7 +517,6 @@ check_install_oai_software() { texlive-latex-base \ ethtool \ flex \ - gccxml \ gdb \ git \ graphviz \ @@ -515,7 +527,6 @@ check_install_oai_software() { iptables \ iptables-dev \ libatlas-base-dev \ - libatlas-dev \ libblas-dev \ libconfig8-dev \ libffi-dev \ @@ -553,11 +564,9 @@ check_install_oai_software() { wget \ libxpm-dev - $SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so - - $SUDO apt-get install -y nettle-dev nettle-bin + $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" - $SUDO apt-get install -y libgnutls-dev + $SUDO apt-get install -y nettle-dev nettle-bin elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then if rpm -q epel-release > /dev/null; then diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 4e49f2c56a..acee5646cd 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -128,6 +128,7 @@ int config_get(paramdef_t *params,int numparams, char *prefix) { int ret= -1; +printf("numparams:%d prefix:%s\n", numparams, prefix); if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); return ret; diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 24845b6b9e..6bdda0edac 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -29,7 +29,7 @@ typedef struct { #define T_SHM_FILENAME "/T_shm_segment" /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS 178 +#define VCD_NUM_FUNCTIONS 187 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ #define VCD_NUM_VARIABLES 128 diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 3e37b5ea15..8d531f9067 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -185,6 +185,10 @@ ID = ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST DESC = RRC connection reestablishment request GROUP = ALL:RRC:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti +ID = ENB_RRC_CONNECTION_REESTABLISHMENT + DESC = RRC connection reestablishment + GROUP = ALL:RRC:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti ID = ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE DESC = RRC connection reestablishment complete GROUP = ALL:RRC:ENB @@ -2157,3 +2161,39 @@ ID = VCD_FUNCTION_TRX_DECOMPR_IF DESC = VCD function TRX_DECOMPR_IF GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value +ID = VCD_FUNCTION_NFAPI + DESC = VCD function NFAPI + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_GENERATE_PCFICH + DESC = VCD function GENERATE_PCFICH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_GENERATE_DCI0 + DESC = VCD function GENERATE_DCI0 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_GENERATE_DLSCH + DESC = VCD function GENERATE_DLSCH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_GENERATE_PHICH + DESC = VCD function GENERATE_PHICH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PDCCH_SCRAMBLING + DESC = VCD function PDCCH_SCRAMBLING + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PDCCH_MODULATION + DESC = VCD function PDCCH_MODULATION + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PDCCH_INTERLEAVING + DESC = VCD function PDCCH_INTERLEAVING + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PDCCH_TX + DESC = VCD function PDCCH_TX + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 387d37d61d..d3f62ae0f4 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -31,10 +31,6 @@ #include #include -#ifdef RTAI -# include -#endif - #if !defined(TRUE) #define TRUE 1 #endif @@ -45,11 +41,6 @@ #include "intertask_interface.h" #include "intertask_interface_dump.h" -#if defined(OAI_EMU) || defined(RTAI) -# include "memory_pools.h" -# include "vcd_signal_dumper.h" -#endif - #if T_TRACER #include "T.h" #endif @@ -67,14 +58,6 @@ #include "log.h" #endif -#ifdef RTAI -# include -# include -# define FIFO_PRINTF_MAX_STRING_SIZE 1000 -# define FIFO_PRINTF_NO 62 -# define FIFO_PRINTF_SIZE 65536 -#endif - /* ITTI DEBUG groups */ #define ITTI_DEBUG_POLL (1<<0) #define ITTI_DEBUG_SEND (1<<1) @@ -86,22 +69,12 @@ const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS); -/* Don't flush if using RTAI */ -#ifdef RTAI -# define ITTI_DEBUG(m, x, args...) do { if ((m) & itti_debug) rt_log_debug (x, ##args); } while(0); -#else # define ITTI_DEBUG(m, x, args...) do { if ((m) & itti_debug) {fprintf(stdout, "[ITTI][D]"x, ##args); fflush (stdout);} } while(0); -#endif #define ITTI_ERROR(x, args...) do { fprintf(stdout, "[ITTI][E]"x, ##args); fflush (stdout); } while(0); /* Global message size */ #define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size) -#ifdef RTAI -# define ITTI_MEM_PAGE_SIZE (1024) -# define ITTI_MEM_SIZE (16 * 1024 * 1024) -#endif - typedef enum task_state_s { TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX, } task_state_t; @@ -140,13 +113,11 @@ typedef struct thread_desc_s { int epoll_nb_events; - //#ifdef RTAI /* Flag to mark real time thread */ unsigned real_time; - /* Counter to indicate from RTAI threads that messages are pending for the thread */ + /* Counter to indicate that messages are pending for the thread */ unsigned messages_pending; - //#endif } thread_desc_t; typedef struct task_desc_s { @@ -178,17 +149,6 @@ typedef struct itti_desc_s { volatile uint32_t created_tasks; volatile uint32_t ready_tasks; volatile int wait_tasks; -#ifdef RTAI - pthread_t rt_relay_thread; -#endif - -#if defined(OAI_EMU) || defined(RTAI) - memory_pools_handle_t memory_pools_handle; - - uint64_t vcd_poll_msg; - uint64_t vcd_receive_msg; - uint64_t vcd_send_msg; -#endif } itti_desc_t; static itti_desc_t itti_desc; @@ -197,20 +157,8 @@ void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize { void *ptr = NULL; -#if defined(OAI_EMU) || defined(RTAI) - ptr = memory_pools_allocate (itti_desc.memory_pools_handle, size, origin_task_id, destination_task_id); - - if (ptr == NULL) { - char *statistics = memory_pools_statistics (itti_desc.memory_pools_handle); - - ITTI_ERROR (" Memory pools statistics:\n%s", statistics); - free (statistics); - } - -#else ptr = malloc (size); if (ptr) memset(ptr,0,size); -#endif AssertFatal (ptr != NULL, "Memory allocation of %d bytes failed (%d -> %d)!\n", (int) size, origin_task_id, destination_task_id); @@ -222,13 +170,7 @@ int itti_free(task_id_t task_id, void *ptr) int result = EXIT_SUCCESS; AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id); -#if defined(OAI_EMU) || defined(RTAI) - result = memory_pools_free (itti_desc.memory_pools_handle, ptr, task_id); - - AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory at %p (%d)!\n", ptr, task_id); -#else free (ptr); -#endif return (result); } @@ -284,27 +226,6 @@ static task_id_t itti_get_current_task_id(void) return TASK_UNKNOWN; } -#ifdef RTAI -static void rt_log_debug(char *format, ...) -{ - task_id_t task_id; - va_list args; - char log_buffer[FIFO_PRINTF_MAX_STRING_SIZE]; - int len; - - task_id = itti_get_current_task_id (); - len = snprintf(log_buffer, FIFO_PRINTF_MAX_STRING_SIZE-1, "[ITTI][D][%s]", itti_get_task_name(task_id)); - va_start(args, format); - len += vsnprintf(&log_buffer[len], FIFO_PRINTF_MAX_STRING_SIZE-1-len, format, args); - va_end (args); - - if (task_id != TASK_UNKNOWN) - fwrite(log_buffer, len, 1, stdout); - else - rtf_put (FIFO_PRINTF_NO, log_buffer, len); -} -#endif - void itti_update_lte_time(uint32_t frame, uint8_t slot) { itti_desc.lte_time.frame = frame; @@ -361,10 +282,6 @@ MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds m AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG, size); -#endif - if (origin_task_id == TASK_UNKNOWN) { /* Try to identify real origin task ID */ origin_task_id = itti_get_current_task_id(); @@ -376,10 +293,6 @@ MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds m temp->ittiMsgHeader.originTaskId = origin_task_id; temp->ittiMsgHeader.ittiMsgSize = size; -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG, 0); -#endif - return temp; } @@ -397,11 +310,6 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me message_number_t message_number; uint32_t message_id; -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG, - __sync_or_and_fetch (&itti_desc.vcd_send_msg, 1L << destination_task_id)); -#endif - AssertFatal (message != NULL, "Message is NULL!\n"); AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); @@ -424,11 +332,6 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); if (destination_task_id != TASK_UNKNOWN) { -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_ENQUEUE_MESSAGE, VCD_FUNCTION_IN); - - memory_pools_set_info (itti_desc.memory_pools_handle, message, 1, destination_task_id); -#endif if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) { ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n", @@ -476,17 +379,6 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me #endif } -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_ENQUEUE_MESSAGE, VCD_FUNCTION_OUT); -#endif - -#ifdef RTAI - - if (itti_desc.threads[TASK_GET_THREAD_ID(origin_task_id)].real_time) { - /* This is a RT task, increase destination task messages pending counter */ - __sync_fetch_and_add (&itti_desc.threads[destination_thread_id].messages_pending, 1); - } else -#endif { /* Only use event fd for tasks, subtasks will pool the queue */ if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { @@ -514,11 +406,6 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG, - __sync_and_and_fetch (&itti_desc.vcd_send_msg, ~(1L << destination_task_id))); -#endif - return 0; } @@ -670,17 +557,9 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) { -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, - __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); -#endif itti_receive_msg_internal_event_fd(task_id, 0, received_msg); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, - __sync_or_and_fetch (&itti_desc.vcd_receive_msg, 1L << task_id)); -#endif } void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) @@ -689,11 +568,6 @@ void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) *received_msg = NULL; -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG, - __sync_or_and_fetch (&itti_desc.vcd_poll_msg, 1L << task_id)); -#endif - { struct message_list_s *message; @@ -710,10 +584,6 @@ void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) ITTI_DEBUG(ITTI_DEBUG_POLL, " No message in queue[(%u:%s)]\n", task_id, itti_get_task_name(task_id)); } -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG, - __sync_and_and_fetch (&itti_desc.vcd_poll_msg, ~(1L << task_id))); -#endif } int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) @@ -745,7 +615,6 @@ int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *ar return 0; } -//#ifdef RTAI void itti_set_task_real_time(task_id_t task_id) { thread_id_t thread_id = TASK_GET_THREAD_ID(task_id); @@ -754,7 +623,6 @@ void itti_set_task_real_time(task_id_t task_id) itti_desc.threads[thread_id].real_time = TRUE; } -//#endif void itti_wait_ready(int wait_tasks) { @@ -782,15 +650,6 @@ void itti_mark_task_ready(task_id_t task_id) /* Mark the thread as using LFDS queue */ lfds611_queue_use(itti_desc.tasks[task_id].message_queue); -#ifdef RTAI - /* Assign low priority to created threads */ - { - struct sched_param sched_param; - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; - sched_setscheduler(0, SCHED_FIFO, &sched_param); - } -#endif - itti_desc.threads[thread_id].task_state = TASK_STATE_READY; itti_desc.ready_tasks ++; @@ -803,15 +662,6 @@ void itti_mark_task_ready(task_id_t task_id) void itti_exit_task(void) { -#if defined(OAI_EMU) || defined(RTAI) - task_id_t task_id = itti_get_current_task_id(); - - if (task_id > TASK_UNKNOWN) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG, - __sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id))); - } - -#endif pthread_exit (NULL); } @@ -827,45 +677,6 @@ void itti_terminate_tasks(task_id_t task_id) pthread_exit (NULL); } -#ifdef RTAI -static void *itti_rt_relay_thread(void *arg) -{ - thread_id_t thread_id; - unsigned pending_messages; - - while (itti_desc.running) { - usleep (200); // Poll for messages a little more than 2 time by slot to get a small latency between RT and other tasks - -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_RELAY_THREAD, VCD_FUNCTION_IN); -#endif - - /* Checks for all non real time tasks if they have pending messages */ - for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) { - if ((itti_desc.threads[thread_id].task_state == TASK_STATE_READY) - && (itti_desc.threads[thread_id].real_time == FALSE)) { - pending_messages = __sync_fetch_and_and (&itti_desc.threads[thread_id].messages_pending, 0); - - if (pending_messages > 0) { - ssize_t write_ret; - eventfd_t sem_counter = pending_messages; - - /* Call to write for an event fd must be of 8 bytes */ - write_ret = write (itti_desc.threads[thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); - DevCheck(write_ret == sizeof(sem_counter), write_ret, sem_counter, thread_id); - } - } - } - -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_RELAY_THREAD, VCD_FUNCTION_OUT); -#endif - } - - return NULL; -} -#endif - int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, const message_info_t *messages_info, const char * const messages_definition_xml, const char * const dump_file_name) { @@ -946,45 +757,12 @@ int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_i ITTI_DEBUG(ITTI_DEBUG_EVEN_FD, " Successfully subscribed fd %d for thread %d\n", itti_desc.threads[thread_id].task_event_fd, thread_id); -#ifdef RTAI - itti_desc.threads[thread_id].real_time = FALSE; - itti_desc.threads[thread_id].messages_pending = 0; -#endif } itti_desc.running = 1; itti_desc.wait_tasks = 0; itti_desc.created_tasks = 0; itti_desc.ready_tasks = 0; -#ifdef RTAI - /* Start RT relay thread */ - DevAssert(pthread_create (&itti_desc.rt_relay_thread, NULL, itti_rt_relay_thread, NULL) >= 0); - - rt_global_heap_open(); -#endif - -#if defined(OAI_EMU) || defined(RTAI) - itti_desc.memory_pools_handle = memory_pools_create (5); - memory_pools_add_pool (itti_desc.memory_pools_handle, 1000 + ITTI_QUEUE_MAX_ELEMENTS, 50); - memory_pools_add_pool (itti_desc.memory_pools_handle, 1000 + (2 * ITTI_QUEUE_MAX_ELEMENTS), 100); - memory_pools_add_pool (itti_desc.memory_pools_handle, 10000, 1000); - memory_pools_add_pool (itti_desc.memory_pools_handle, 400, 20050); - memory_pools_add_pool (itti_desc.memory_pools_handle, 100, 30050); - - { - char *statistics = memory_pools_statistics (itti_desc.memory_pools_handle); - - ITTI_DEBUG(ITTI_DEBUG_MP_STATISTICS, " Memory pools statistics:\n%s", statistics); - free (statistics); - } -#endif - -#if defined(OAI_EMU) || defined(RTAI) - itti_desc.vcd_poll_msg = 0; - itti_desc.vcd_receive_msg = 0; - itti_desc.vcd_send_msg = 0; -#endif - itti_dump_init (messages_definition_xml, dump_file_name); CHECK_INIT_RETURN(timer_init ()); @@ -1047,15 +825,6 @@ void itti_wait_tasks_end(void) itti_desc.running = 0; -#if defined(OAI_EMU) || defined(RTAI) - { - char *statistics = memory_pools_statistics (itti_desc.memory_pools_handle); - - ITTI_DEBUG(ITTI_DEBUG_MP_STATISTICS, " Memory pools statistics:\n%s", statistics); - free (statistics); - } -#endif - if (ready_tasks > 0) { ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Some threads are still running, force exit\n"); exit (0); diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h index 191d9199c3..606c851d1d 100644 --- a/common/utils/itti/intertask_interface.h +++ b/common/utils/itti/intertask_interface.h @@ -27,10 +27,6 @@ #include -#ifdef RTAI -# include -#endif - #ifndef INTERTASK_INTERFACE_H_ #define INTERTASK_INTERFACE_H_ @@ -155,12 +151,10 @@ int itti_create_task(task_id_t task_id, void *(*start_routine) (void *), void *args_p); -//#ifdef RTAI /** \brief Mark the task as a real time task * \param task_id task to mark as real time **/ void itti_set_task_real_time(task_id_t task_id); -//#endif /** \brief Indicates to ITTI if newly created tasks should wait for all tasks to be ready * \param wait_tasks non 0 to make new created tasks to wait, 0 to let created tasks to run diff --git a/common/utils/itti/intertask_interface_dump.c b/common/utils/itti/intertask_interface_dump.c index a06b97c63b..bb77509726 100644 --- a/common/utils/itti/intertask_interface_dump.c +++ b/common/utils/itti/intertask_interface_dump.c @@ -51,23 +51,14 @@ #include "intertask_interface.h" #include "intertask_interface_dump.h" -#if defined(OAI_EMU) || defined(RTAI) -#include "vcd_signal_dumper.h" -#endif - #if T_TRACER #include "T.h" #endif static const int itti_dump_debug = 0; // 0x8 | 0x4 | 0x2; -#ifdef RTAI -# define ITTI_DUMP_DEBUG(m, x, args...) do { if ((m) & itti_dump_debug) rt_printk("[ITTI_DUMP][D]"x, ##args); } \ - while(0) -#else # define ITTI_DUMP_DEBUG(m, x, args...) do { if ((m) & itti_dump_debug) fprintf(stdout, "[ITTI_DUMP][D]"x, ##args); } \ while(0) -#endif #define ITTI_DUMP_ERROR(x, args...) do { fprintf(stdout, "[ITTI_DUMP][E]"x, ##args); } \ while(0) @@ -99,13 +90,8 @@ typedef struct itti_desc_s { int nb_connected; -#ifndef RTAI /* Event fd used to notify new messages (semaphore) */ int event_fd; -#else - unsigned long messages_in_queue __attribute__((aligned(8))); -#endif - int itti_listen_socket; itti_client_desc_t itti_clients[ITTI_DUMP_MAX_CON]; @@ -194,9 +180,7 @@ static int itti_dump_fwrite_message(itti_dump_queue_item_t *message) fwrite (&new_message_header, sizeof(itti_dump_message_t), 1, dump_file); fwrite (message->data, message->data_size, 1, dump_file); fwrite (&itti_dump_message_type_end, sizeof(itti_message_types_t), 1, dump_file); - // #if !defined(RTAI) fflush (dump_file); - // #endif return (1); } @@ -280,10 +264,6 @@ static int itti_dump_enqueue_message(itti_dump_queue_item_t *new, uint32_t messa int overwrite_flag; AssertFatal (new != NULL, "Message to queue is NULL!\n"); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE, VCD_FUNCTION_IN); -#endif - new->message_type = message_type; new->message_size = message_size; @@ -303,9 +283,6 @@ static int itti_dump_enqueue_message(itti_dump_queue_item_t *new, uint32_t messa lfds611_ringbuffer_put_write_element(itti_dump_queue.itti_message_queue, new_queue_element); if (overwrite_flag == 0) { -#ifdef RTAI - __sync_fetch_and_add (&itti_dump_queue.messages_in_queue, 1); -#else { ssize_t write_ret; eventfd_t sem_counter = 1; @@ -314,25 +291,18 @@ static int itti_dump_enqueue_message(itti_dump_queue_item_t *new, uint32_t messa write_ret = write(itti_dump_queue.event_fd, &sem_counter, sizeof(sem_counter)); AssertFatal (write_ret == sizeof(sem_counter), "Write to dump event failed (%d/%d)!\n", (int) write_ret, (int) sizeof(sem_counter)); } -#endif // add one to pending_messages, atomically __sync_fetch_and_add (&pending_messages, 1); } ITTI_DUMP_DEBUG (0x2, " Added element to queue %p %p, pending %u, type %u\n", new_queue_element, new, pending_messages, message_type); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE, VCD_FUNCTION_OUT); -#endif - return 0; } static void itti_dump_socket_exit(void) { -#ifndef RTAI close(itti_dump_queue.event_fd); -#endif close(itti_dump_queue.itti_listen_socket); /* Leave the thread as we detected end signal */ @@ -346,10 +316,6 @@ static int itti_dump_flush_ring_buffer(int flush_all) int j; int consumer; -#ifdef RTAI - unsigned long number_of_messages; -#endif - /* Check if there is a least one consumer */ consumer = 0; @@ -365,18 +331,6 @@ static int itti_dump_flush_ring_buffer(int flush_all) } if (consumer > 0) { -#ifdef RTAI - number_of_messages = itti_dump_queue.messages_in_queue; - - ITTI_DUMP_DEBUG(0x4, "%lu elements in queue\n", number_of_messages); - - if (number_of_messages == 0) { - return (consumer); - } - - __sync_sub_and_fetch(&itti_dump_queue.messages_in_queue, number_of_messages); -#endif - do { /* Acquire the ring element */ lfds611_ringbuffer_get_read_element(itti_dump_queue.itti_message_queue, &element); @@ -419,9 +373,6 @@ static int itti_dump_flush_ring_buffer(int flush_all) lfds611_ringbuffer_put_read_element(itti_dump_queue.itti_message_queue, element); } } while(flush_all -#ifdef RTAI - && --number_of_messages -#endif ); } @@ -478,9 +429,6 @@ static void *itti_dump_socket(void *arg_p) struct sockaddr_in servaddr; /* socket address structure */ struct timeval *timeout_p = NULL; -#ifdef RTAI - struct timeval timeout; -#endif ITTI_DUMP_DEBUG(0x2, " Creating TCP dump socket on port %u\n", ITTI_PORT); @@ -536,15 +484,11 @@ static void *itti_dump_socket(void *arg_p) /* Add the listener */ FD_SET(itti_listen_socket, &read_set); -#ifndef RTAI /* Add the event fd */ FD_SET(itti_dump_queue.event_fd, &read_set); /* Max of both sd */ max_sd = itti_listen_socket > itti_dump_queue.event_fd ? itti_listen_socket : itti_dump_queue.event_fd; -#else - max_sd = itti_listen_socket; -#endif itti_dump_queue.itti_listen_socket = itti_listen_socket; @@ -557,14 +501,7 @@ static void *itti_dump_socket(void *arg_p) int i; memcpy(&working_set, &read_set, sizeof(read_set)); -#ifdef RTAI - timeout.tv_sec = 0; - timeout.tv_usec = 100000; - - timeout_p = &timeout; -#else timeout_p = NULL; -#endif /* No timeout: select blocks till a new event has to be handled * on sd's. @@ -592,8 +529,6 @@ static void *itti_dump_socket(void *arg_p) if (FD_ISSET(i, &working_set)) { desc_ready -= 1; -#ifndef RTAI - if (i == itti_dump_queue.event_fd) { /* Notification of new element to dump from other tasks */ eventfd_t sem_counter; @@ -613,7 +548,6 @@ static void *itti_dump_socket(void *arg_p) if (itti_dump_running) { ITTI_DUMP_DEBUG (0x4, " No messages consumers, waiting ...\n"); usleep(100 * 1000); -#ifndef RTAI { ssize_t write_ret; @@ -622,7 +556,6 @@ static void *itti_dump_socket(void *arg_p) write_ret = write(itti_dump_queue.event_fd, &sem_counter, sizeof(sem_counter)); AssertFatal (write_ret == sizeof(sem_counter), "Failed to write to dump event FD (%d/%d)!\n", (int) write_ret, (int) sem_counter); } -#endif } else { itti_dump_socket_exit(); } @@ -630,7 +563,6 @@ static void *itti_dump_socket(void *arg_p) ITTI_DUMP_DEBUG(0x1, " Write element to file\n"); } } else -#endif if (i == itti_listen_socket) { do { client_socket = accept(itti_listen_socket, NULL, NULL); @@ -719,21 +651,9 @@ int itti_dump_queue_message(task_id_t sender_task, AssertFatal (message_name != NULL, "Message name is NULL!\n"); AssertFatal (message_p != NULL, "Message is NULL!\n"); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC, VCD_FUNCTION_IN); -#endif new = itti_malloc(sender_task, TASK_MAX, sizeof(itti_dump_queue_item_t)); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC, VCD_FUNCTION_OUT); -#endif -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC, VCD_FUNCTION_IN); -#endif new->data = itti_malloc(sender_task, TASK_MAX, message_size); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC, VCD_FUNCTION_OUT); -#endif memcpy(new->data, message_p, message_size); new->data_size = message_size; @@ -791,9 +711,6 @@ int itti_dump_init(const char * const messages_definition_xml, const char * cons AssertFatal (0, " Failed to create ring buffer!\n"); } -#ifdef RTAI - itti_dump_queue.messages_in_queue = 0; -#else itti_dump_queue.event_fd = eventfd(0, EFD_SEMAPHORE); if (itti_dump_queue.event_fd == -1) { @@ -801,8 +718,6 @@ int itti_dump_init(const char * const messages_definition_xml, const char * cons AssertFatal (0, "eventfd failed: %s!\n", strerror(errno)); } -#endif - itti_dump_queue.nb_connected = 0; for(i = 0; i < ITTI_DUMP_MAX_CON; i++) { diff --git a/common/utils/itti/itti_types.h b/common/utils/itti/itti_types.h index 7f01901712..d07853133b 100644 --- a/common/utils/itti/itti_types.h +++ b/common/utils/itti/itti_types.h @@ -27,11 +27,7 @@ #ifndef _ITTI_TYPES_H_ #define _ITTI_TYPES_H_ -#ifdef USER_MODE #include -#else -#include -#endif #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) diff --git a/common/utils/itti/memory_pools.c b/common/utils/itti/memory_pools.c index 23c53b71ae..78b6923dc8 100644 --- a/common/utils/itti/memory_pools.c +++ b/common/utils/itti/memory_pools.c @@ -19,15 +19,8 @@ * contact@openairinterface.org */ -#ifdef RTAI -# include -#endif - #include "assertions.h" #include "memory_pools.h" -#if defined(OAI_EMU) || defined(RTAI) -# include "vcd_signal_dumper.h" -#endif #if T_TRACER #include @@ -37,18 +30,8 @@ /*------------------------------------------------------------------------------*/ const static int mp_debug = 0; -#ifdef RTAI -# define MP_DEBUG(x, args...) do { if (mp_debug) rt_printk("[MP][D]"x, ##args); } \ - while(0) -#else # define MP_DEBUG(x, args...) do { if (mp_debug) fprintf(stdout, "[MP][D]"x, ##args); fflush (stdout); } \ while(0) -#endif - -#if defined(OAI_EMU) || defined(RTAI) -uint64_t vcd_mp_alloc; -uint64_t vcd_mp_free; -#endif /*------------------------------------------------------------------------------*/ #ifndef CHARS_TO_UINT32 @@ -414,11 +397,6 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po pool_id_t pool; items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID; -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC, - __sync_or_and_fetch (&vcd_mp_alloc, 1L << info_0)); -#endif - /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); @@ -464,11 +442,6 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po MP_DEBUG(" Alloc [--][------]{------}, %3u %3u, %6u, failed!\n", info_0, info_1, item_size); } -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC, - __sync_and_and_fetch (&vcd_mp_alloc, ~(1L << info_0))); -#endif - return memory_pool_item_handle; } @@ -493,11 +466,6 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it info_1 = memory_pool_item->start.info[1]; -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE, - __sync_or_and_fetch (&vcd_mp_free, 1L << info_1)); -#endif - /* Recover pool index */ pool = memory_pool_item->start.pool_id; AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); @@ -531,11 +499,6 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index); -#if defined(OAI_EMU) || defined(RTAI) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE, - __sync_and_and_fetch (&vcd_mp_free, ~(1L << info_1))); -#endif - return (result); } diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt index 51284ad2e8..bc4a550742 100644 --- a/common/utils/telnetsrv/CMakeLists.txt +++ b/common/utils/telnetsrv/CMakeLists.txt @@ -24,7 +24,7 @@ set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} ) set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS}) -add_definitions (-DRel14 -DCMAKER -DENABLE_FXP -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNB_ANTENNAS_TXRX=2 -DNEW_FFT -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR1 -DOPENAIR2 -DOPENAIR_LTE -DPC_DSP -DPC_TARGET -DPHYSIM -DPHY_CONTEXT -DPUCCH -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DUSER_MODE -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3) +add_definitions (-DRel14 -DCMAKER -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR2 -DOPENAIR_LTE -DPHYSIM -DPHY_CONTEXT -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3) add_compile_options( -fPIC -march=native -Ofast) include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG diff --git a/nfapi/README b/nfapi/README new file mode 100644 index 0000000000..b2e1321532 --- /dev/null +++ b/nfapi/README @@ -0,0 +1,15 @@ +This directory contains the NFAPI code. + +It comes in two parts: + +1 - open-nFAPI + + This is a clone of the github repository + (https://github.com/cisco/open-nFAPI, + commit b3bc579b1697eab829d5d8a2de59c93a61b88fa4). + The patch open-nfapi.oai.patch has then been applied. + +2 - oai_integration + + This is code written by David Price from Cisco to integrate + open-nFAPI into OpenAirInterface. diff --git a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.h b/nfapi/oai_integration/nfapi.c similarity index 59% rename from openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.h rename to nfapi/oai_integration/nfapi.c index 128503094f..5a3bc804c1 100644 --- a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.h +++ b/nfapi/oai_integration/nfapi.c @@ -19,31 +19,33 @@ * contact@openairinterface.org */ -#ifndef _IOCTL_H -#define _IOCTL_H - -#include -#include #include -#include -#include -#include -#include -#include -//#include +#include -//#include -//#define GRAAL_STATE_IDLE 0 -//#define GRAAL_STATE_CONNECTED 1 -//#define GRAAL_STATE_ESTABLISHMENT_REQUEST 2 -//#define GRAAL_STATE_ESTABLISHMENT_FAILURE 3 -//#define GRAAL_STATE_RELEASE_FAILURE 4 +void set_thread_priority(int priority) +{ + //printf("%s(priority:%d)\n", __FUNCTION__, priority); -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; + pthread_attr_t ptAttr; -extern int inet_pton(int af, const char *src, void *dst); -extern char *inet_ntop(int af, const void *src, char *dst, size_t sise); + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) + { + printf("Failed to set scheduler to SCHED_RR\n"); + } -#endif //_IOCTL_H + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) + { + printf("Failed to set pthread sched policy SCHED_RR\n"); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) + { + printf("failed to set sched param\n"); + } +} diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c new file mode 100644 index 0000000000..c63d504e43 --- /dev/null +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -0,0 +1,1625 @@ +/* + * 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 +#include +#include +#include +#include + +#include "debug.h" +#include "nfapi_pnf_interface.h" +#include "nfapi.h" +#include "nfapi_pnf.h" +#include "common/ran_context.h" +//#include "openair1/PHY/vars.h" +extern RAN_CONTEXT_t RC; + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "fapi_stub.h" +//#include "fapi_l1.h" +#include "UTIL/LOG/log.h" +#include "openair2/LAYER2/MAC/proto.h" + +#define NUM_P5_PHY 2 + +#define _GNU_SOURCE + +extern void phy_init_RU(RU_t*); +extern int config_sync_var; + +extern pthread_cond_t nfapi_sync_cond; +extern pthread_mutex_t nfapi_sync_mutex; +extern int nfapi_sync_var; + +extern int sync_var; + +extern void init_eNB_afterRU(void); +extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu); +extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); +extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); +extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); +extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); +extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu); + +extern uint8_t nfapi_mode; + +nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus] + +uint8_t tx_pdus[32][8][4096]; + + +uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; + +nfapi_pnf_param_response_t g_pnf_param_resp; + + +nfapi_pnf_p7_config_t *p7_config_g = NULL; + +void* pnf_allocate(size_t size) { + return malloc(size); +} + +void pnf_deallocate(void* ptr) { + free(ptr); +} + + +typedef struct { + //public: + uint8_t enabled; + uint32_t rx_port; + uint32_t tx_port; + //std::string tx_addr; + char tx_addr[80]; +} udp_data; + +typedef struct { + uint16_t index; + uint16_t id; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; + + udp_data udp; + + char local_addr[80]; + int local_port; + + char* remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + +} phy_info; + +typedef struct { + //public: + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +} rf_info; + + +typedef struct { + + int release; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +} pnf_info; + +typedef struct { + uint16_t phy_id; + nfapi_pnf_config_t* config; + phy_info* phy; + nfapi_pnf_p7_config_t* p7_config; +} pnf_phy_user_data_t; + +static pnf_info pnf; +static pthread_t pnf_start_pthread; + +extern void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args); + +void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char* message, ...) { + va_list args; + int oai_level; + + if (nfapi_level==NFAPI_TRACE_ERROR) { + oai_level = LOG_ERR; + } else if (nfapi_level==NFAPI_TRACE_WARN) { + oai_level = LOG_WARNING; + } else if (nfapi_level==NFAPI_TRACE_NOTE) { + oai_level = LOG_INFO; + } else if (nfapi_level==NFAPI_TRACE_INFO) { + oai_level = LOG_DEBUG; + } else { + oai_level = LOG_ERR; + } + + va_start(args, message); + nfapi_log("FILE>", "FUNC", 999, PHY, oai_level, message, args); + va_end(args); +} + +void pnf_set_thread_priority(int priority) { + + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = priority; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { + printf("failed to set SCHED_RR\n"); + } + + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { + printf("failed to set pthread SCHED_RR %d\n", errno); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { + printf("failed to set sched param\n"); + } +} + +void* pnf_p7_thread_start(void* ptr) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__); + + pnf_set_thread_priority(79); + + nfapi_pnf_p7_config_t* config = (nfapi_pnf_p7_config_t*)ptr; + nfapi_pnf_p7_start(config); + + return 0; +} + +int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req) { + + printf("[PNF] pnf param request\n"); + + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + + pnf_info* pnf = (pnf_info*)(config->user_data); + + resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode; + resp.pnf_param_general.location_mode = pnf->location_mode; + resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing; + resp.pnf_param_general.tx_timing = pnf->tx_timing; + resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing; + resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing; + resp.pnf_param_general.maximum_number_phys = pnf->max_phys; + resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw; + resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers; + resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers; + resp.pnf_param_general.shared_bands = pnf->shared_bands; + resp.pnf_param_general.shared_pa = pnf->shared_pa; + resp.pnf_param_general.maximum_total_power = pnf->max_total_power; + + resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + resp.pnf_phy.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support; + resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support; + resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + + resp.pnf_phy.phy[i].number_of_rfs = 2; + for(int j = 0; j < 1; ++j) { + resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + resp.pnf_phy.phy[i].number_of_rf_exclusions = 0; + for(int j = 0; j < 0; ++j) { + resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + } + + resp.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG; + resp.pnf_rf.number_of_rfs = 2; + + for(int i = 0; i < 2; ++i) { + resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; + resp.pnf_rf.rf[i].band = pnf->rfs[i].band; + resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; + resp.pnf_rf.rf[i].minimum_transmit_power = pnf->rfs[i].min_transmit_power; + resp.pnf_rf.rf[i].number_of_antennas_suppported = pnf->rfs[i].num_antennas_supported; + resp.pnf_rf.rf[i].minimum_downlink_frequency = pnf->rfs[i].min_downlink_frequency; + resp.pnf_rf.rf[i].maximum_downlink_frequency = pnf->rfs[i].max_downlink_frequency; + resp.pnf_rf.rf[i].minimum_uplink_frequency = pnf->rfs[i].min_uplink_frequency; + resp.pnf_rf.rf[i].maximum_uplink_frequency = pnf->rfs[i].max_uplink_frequency; + } + + if(pnf->release >= 10) { + resp.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; + resp.pnf_phy_rel10.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) + { + resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel10.phy[i].transmission_mode_7_supported = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_8_supported = 1; + resp.pnf_phy_rel10.phy[i].two_antenna_ports_for_pucch = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_9_supported = 1; + resp.pnf_phy_rel10.phy[i].simultaneous_pucch_pusch = 0; + resp.pnf_phy_rel10.phy[i].four_layer_tx_with_tm3_and_tm4 = 1; + } + } + + if(pnf->release >= 11) { + resp.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG; + resp.pnf_phy_rel11.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel11.phy[i].edpcch_supported = 0; + resp.pnf_phy_rel11.phy[i].multi_ack_csi_reporting = 1; + resp.pnf_phy_rel11.phy[i].pucch_tx_diversity = 0; + resp.pnf_phy_rel11.phy[i].ul_comp_supported = 1; + resp.pnf_phy_rel11.phy[i].transmission_mode_5_supported = 0; + } + } + + if(pnf->release >= 12) { + resp.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG; + resp.pnf_phy_rel12.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel12.phy[i].csi_subframe_set = 0; + resp.pnf_phy_rel12.phy[i].enhanced_4tx_codebook = 2; + resp.pnf_phy_rel12.phy[i].drs_supported = 0; + resp.pnf_phy_rel12.phy[i].ul_64qam_supported = 1; + resp.pnf_phy_rel12.phy[i].transmission_mode_10_supported = 0; + resp.pnf_phy_rel12.phy[i].alternative_bts_indices = 1; + } + } + + if(pnf->release >= 13) { + resp.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG; + resp.pnf_phy_rel13.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel13.phy[i].pucch_format4_supported = 0; + resp.pnf_phy_rel13.phy[i].pucch_format5_supported = 1; + resp.pnf_phy_rel13.phy[i].more_than_5_ca_support = 0; + resp.pnf_phy_rel13.phy[i].laa_supported = 1; + resp.pnf_phy_rel13.phy[i].laa_ending_in_dwpts_supported = 0; + resp.pnf_phy_rel13.phy[i].laa_starting_in_second_slot_supported = 1; + resp.pnf_phy_rel13.phy[i].beamforming_supported = 0; + resp.pnf_phy_rel13.phy[i].csi_rs_enhancement_supported = 1; + resp.pnf_phy_rel13.phy[i].drms_enhancement_supported = 0; + resp.pnf_phy_rel13.phy[i].srs_enhancement_supported = 1; + } + + resp.pnf_phy_rel13_nb_iot.tl.tag = NFAPI_PNF_PHY_REL13_NB_IOT_TAG; + resp.pnf_phy_rel13_nb_iot.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = 1; + for(int j = 0; j < 1; ++j) { + resp.pnf_phy_rel13_nb_iot.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = 1; + for(int j = 0; j < 1; ++j) { + resp.pnf_phy_rel13_nb_iot.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + } + } + + nfapi_pnf_pnf_param_resp(config, &resp); + + return 0; +} + +int pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req) { + + printf("[PNF] pnf config request\n"); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + phy_info *phy = pnf->phys; + phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id; + printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index); + + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_config_resp(config, &resp); + printf("[PNF] Sent pnf_config_resp\n"); + + return 0; +} + +void nfapi_send_pnf_start_resp(nfapi_pnf_config_t* config, uint16_t phy_id) { + + printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id); + + nfapi_start_response_t start_resp; + memset(&start_resp, 0, sizeof(start_resp)); + start_resp.header.message_id = NFAPI_START_RESPONSE; + start_resp.header.phy_id = phy_id; + start_resp.error_code = NFAPI_MSG_OK; + + nfapi_pnf_start_resp(config, &start_resp); +} + +int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req) { + + printf("Received NFAPI_PNF_START_REQUEST\n"); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + // start all phys that have been configured + phy_info* phy = pnf->phys; + + if(phy->id != 0) { + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_start_resp(config, &resp); + printf("[PNF] Sent NFAPI_PNF_START_RESP\n"); + } + return 0; +} + +int pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req) { + + printf("[PNF] Received NFAPI_PNF_STOP_REQ\n"); + + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_stop_resp(config, &resp); + printf("[PNF] Sent NFAPI_PNF_STOP_REQ\n"); + + return 0; +} + +int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req) { + + printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id); + + //pnf_info* pnf = (pnf_info*)(config->user_data); + + nfapi_param_response_t nfapi_resp; + + pnf_info* pnf = (pnf_info*)(config->user_data); + + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE; + nfapi_resp.header.phy_id = req->header.phy_id; + nfapi_resp.error_code = 0; // DJP - what value??? + + struct sockaddr_in pnf_p7_sockaddr; + + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(pnf->phys[0].local_addr); + nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4); + nfapi_resp.num_tlv++; + + // P7 PNF Port + nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // DJP - hard code alert!!!! FIXME TODO + nfapi_resp.num_tlv++; + + nfapi_pnf_param_resp(config, &nfapi_resp); + + printf("[PNF] Sent NFAPI_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv); + + printf("[PNF] param request .. exit\n"); + + return 0; +} + +int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req) { + + printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + uint8_t num_tlv = 0; + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + + phy_info* phy_info = pnf->phys; + + if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG) { + phy_info->timing_window = req->nfapi_config.timing_window.value; + printf("Phy_info:Timing window:%u NFAPI_CONFIG:timing_window:%u\n", phy_info->timing_window, req->nfapi_config.timing_window.value); + num_tlv++; + } + + if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NFAPI_TIMING_INFO_MODE_TAG) { + printf("timing info mode:%d\n", req->nfapi_config.timing_info_mode.value); + phy_info->timing_info_mode = req->nfapi_config.timing_info_mode.value; + num_tlv++; + } else { + phy_info->timing_info_mode = 0; + printf("NO timing info mode provided\n"); + } + + if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG) { + printf("timing info period provided value:%d\n", req->nfapi_config.timing_info_period.value); + phy_info->timing_info_period = req->nfapi_config.timing_info_period.value; + num_tlv++; + } else { + phy_info->timing_info_period = 0; + } + + if(req->rf_config.dl_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG) { + phy_info->dl_channel_bw_support = req->rf_config.dl_channel_bandwidth.value; + fp->N_RB_DL = req->rf_config.dl_channel_bandwidth.value; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG N_RB_DL:%u\n", __FUNCTION__, fp->N_RB_DL); + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() Missing NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG\n", __FUNCTION__); + } + + if(req->rf_config.ul_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG) { + phy_info->ul_channel_bw_support = req->rf_config.ul_channel_bandwidth.value; + fp->N_RB_UL = req->rf_config.ul_channel_bandwidth.value; + num_tlv++; + } + + if(req->nfapi_config.rf_bands.tl.tag == NFAPI_NFAPI_RF_BANDS_TAG) { + pnf->rfs[0].band = req->nfapi_config.rf_bands.rf_band[0]; + fp->eutra_band = req->nfapi_config.rf_bands.rf_band[0]; + num_tlv++; + } + + if(req->nfapi_config.earfcn.tl.tag == NFAPI_NFAPI_EARFCN_TAG) { + fp->dl_CarrierFreq = from_earfcn(fp->eutra_band, req->nfapi_config.earfcn.value); + fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(fp->eutra_band) * 1e5); + num_tlv++; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() earfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", + __FUNCTION__, req->nfapi_config.earfcn.value, fp->dl_CarrierFreq, fp->ul_CarrierFreq, pnf->rfs[0].band, fp->N_RB_DL); + } + + if (req->subframe_config.duplex_mode.tl.tag == NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG) { + fp->frame_type = req->subframe_config.duplex_mode.value==0 ? TDD : FDD; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() frame_type:%d\n", __FUNCTION__, fp->frame_type); + } + + if (req->subframe_config.dl_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG) { + fp->Ncp = req->subframe_config.dl_cyclic_prefix_type.value; + num_tlv++; + } + + if (req->subframe_config.ul_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG) { + fp->Ncp_UL = req->subframe_config.ul_cyclic_prefix_type.value; + num_tlv++; + } + + fp->num_MBSFN_config = 0; // DJP - hard code alert + + if (req->sch_config.physical_cell_id.tl.tag == NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG) { + fp->Nid_cell = req->sch_config.physical_cell_id.value; + fp->nushift = fp->Nid_cell%6; + num_tlv++; + } + + if (req->rf_config.tx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG) { + fp->nb_antennas_tx = req->rf_config.tx_antenna_ports.value; + fp->nb_antenna_ports_eNB = 1; + num_tlv++; + } + + if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG) { + fp->nb_antennas_rx = req->rf_config.rx_antenna_ports.value; + num_tlv++; + } + + if (req->phich_config.phich_resource.tl.tag == NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG) { + fp->phich_config_common.phich_resource = req->phich_config.phich_resource.value; + num_tlv++; + } + + if (req->phich_config.phich_duration.tl.tag == NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG) { + fp->phich_config_common.phich_duration = req->phich_config.phich_duration.value; + num_tlv++; + } + + if (req->phich_config.phich_power_offset.tl.tag == NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG) { + LOG_E(PHY, "%s() NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG tag:%d not supported\n", __FUNCTION__, req->phich_config.phich_power_offset.tl.tag); + //fp->phich_config_common.phich_power_offset = req->phich_config. + num_tlv++; + } + + // UL RS Config + if (req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = req->uplink_reference_signal_config.uplink_rs_hopping.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.group_assignment.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = req->uplink_reference_signal_config.group_assignment.value; + num_tlv++; + } + + if (req->pusch_config.hopping_mode.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG) { + } // DJP - not being handled? + + if (req->pusch_config.hopping_offset.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG) { + } // DJP - not being handled? + + if (req->pusch_config.number_of_subbands.tl.tag == NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG) { + } // DJP - not being handled? + + if (req->prach_config.configuration_index.tl.tag == NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG) { + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=req->prach_config.configuration_index.value; + num_tlv++; + } + + if (req->prach_config.root_sequence_index.tl.tag == NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG) { + fp->prach_config_common.rootSequenceIndex=req->prach_config.root_sequence_index.value; + num_tlv++; + } + + if (req->prach_config.zero_correlation_zone_configuration.tl.tag == NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG) { + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=req->prach_config.zero_correlation_zone_configuration.value; + num_tlv++; + } + + if (req->prach_config.high_speed_flag.tl.tag == NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG) { + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag=req->prach_config.high_speed_flag.value; + num_tlv++; + } + + if (req->prach_config.frequency_offset.tl.tag == NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG) { + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset=req->prach_config.frequency_offset.value; + num_tlv++; + } + + printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); + + printf("[PNF] Simulating PHY CONFIG - DJP\n"); + PHY_Config_t phy_config; + phy_config.Mod_id = 0; + phy_config.CC_id=0; + phy_config.cfg = req; + + phy_config_request(&phy_config); + + dump_frame_parms(fp); + + phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; + + struct sockaddr_in vnf_p7_sockaddr; + memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); + phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); + + printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, + phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period); + + nfapi_config_response_t nfapi_resp; + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_CONFIG_RESPONSE; + nfapi_resp.header.phy_id = phy_info->id; + nfapi_resp.error_code = 0; // DJP - some value resp->error_code; + nfapi_pnf_config_resp(config, &nfapi_resp); + printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); + + return 0; +} + +nfapi_p7_message_header_t* pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) { + + if(message_id == P7_VENDOR_EXT_REQ) { + (*msg_size) = sizeof(vendor_ext_p7_req); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_req)); + } + + return 0; +} + +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) { + + 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]; + eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0]; + + for (int i=0; ihi_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); + + if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { + + //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + + nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + + handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf),proc,hi_dci0_req_pdu); + + eNB->pdcch_vars[NFAPI_SFNSF2SF(req->sfn_sf)&1].num_dci++; + + } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) { + + LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + + nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + + handle_nfapi_hi_dci0_hi_pdu(eNB, NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf), proc, hi_dci0_req_pdu); + + } else { + + LOG_E(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); + + } + } + + return 0; +} + +int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) { + + if (RC.ru == 0) { + return -1; + } + + if (RC.eNB == 0) { + return -2; + } + + if (RC.eNB[0][0] == 0) { + return -3; + } + + if (sync_var != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__); + return -4; + } + + int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + int sf = NFAPI_SFNSF2SF(req->sfn_sf); + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0]; + nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; + LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1]; + + pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; + pdcch_vars->num_dci = 0; + + if (req->dl_config_request_body.number_dci || + req->dl_config_request_body.number_pdu || + req->dl_config_request_body.number_pdsch_rnti) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d pdcch:%u dl_cfg[dci:%u pdus:%d pdsch_rnti:%d] pcfich:%u\n", + __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->dl_config_request_body.number_pdcch_ofdm_symbols, + req->dl_config_request_body.number_dci, + req->dl_config_request_body.number_pdu, + req->dl_config_request_body.number_pdsch_rnti, + req->dl_config_request_body.transmission_power_pcfich); + + for (int i=0;idl_config_request_body.number_pdu;i++) { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci); + + if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) { + + handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf),proc,&dl_config_pdu_list[i]); + + pdcch_vars->num_dci++; // Is actually number of DCI PDUs + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci); + + } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { + + nfapi_dl_config_bch_pdu *bch_pdu = &dl_config_pdu_list[i].bch_pdu; + uint16_t pdu_index = bch_pdu->bch_pdu_rel8.pdu_index; + + if (tx_request_pdu[sfn][sf][pdu_index] != NULL) { + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]); + + handle_nfapi_bch_pdu(eNB, proc, &dl_config_pdu_list[i], tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_data); + + eNB->pbch_configured=1; + + } else { + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index); + } + } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { + + nfapi_dl_config_dlsch_pdu *dlsch_pdu = &dl_config_pdu_list[i].dlsch_pdu; + nfapi_dl_config_dlsch_pdu_rel8_t *rel8_pdu = &dlsch_pdu->dlsch_pdu_rel8; + nfapi_tx_request_pdu_t *tx_pdu = tx_request_pdu[sfn][sf][rel8_pdu->pdu_index]; + + if (tx_pdu != NULL) { + int UE_id = find_dlsch(rel8_pdu->rnti,eNB,SEARCH_EXIST_OR_FREE); + AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); + AssertFatal(UE_id= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); + LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0]; + //LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[UE_id][1]; + int harq_pid = dlsch0->harq_ids[sf]; + 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.proc_rxtx[0], &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); + } + + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_config_pdu_list[i].pdu_type); + } + } + + if(req->vendor_extension) + free(req->vendor_extension); + + return 0; +} + +int pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) { + + uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); + uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); + + if (req->tx_request_body.number_of_pdus==0) + LOG_D(PHY,"%s() SFN/SF:%d%d PDUs:%d\n", __FUNCTION__, sfn, sf, req->tx_request_body.number_of_pdus); + + if (req->tx_request_body.tl.tag==NFAPI_TX_REQUEST_BODY_TAG) { + for (int i=0; itx_request_body.number_of_pdus; i++) { + LOG_D(PHY,"%s() SFN/SF:%d%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n", + __FUNCTION__, + sfn, sf, + req->tx_request_body.number_of_pdus, + i, + req->tx_request_body.tx_pdu_list[i].pdu_length, + req->tx_request_body.tx_pdu_list[i].pdu_index, + req->tx_request_body.tx_pdu_list[i].num_segments + ); + + tx_request_pdu[sfn][sf][i] = &req->tx_request_body.tx_pdu_list[i]; + } + } + + return 0; +} + +int pnf_phy_ul_config_req(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), + req->ul_config_request_body.number_of_pdus, + req->ul_config_request_body.rach_prach_frequency_resources, + req->ul_config_request_body.srs_present + ); + + if (RC.ru == 0) { + return -1; + } + + if (RC.eNB == 0) { + return -2; + } + + if (RC.eNB[0][0] == 0) { + return -3; + } + + if (sync_var != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__); + return -4; + } + + 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]; + eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0]; + nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list; + + for (int i=0;iul_config_request_body.number_of_pdus;i++) { + //LOG_D(PHY, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size); + + if ( + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ) { + //LOG_D(PHY, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i); + + handle_nfapi_ul_pdu(eNB,proc,&ul_config_pdu_list[i],curr_sfn,curr_sf,req->ul_config_request_body.srs_present); + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); + } + } + + return 0; +} + +int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req) { + //printf("[PNF] lbt dl config request\n"); + return 0; +} + +int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg) { + if(msg->message_id == P7_VENDOR_EXT_REQ) { + //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; + //printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2); + } else { + printf("[PNF] unknown vendor ext\n"); + } + return 0; +} + +int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codex) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) { + vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)(header); + if(!push16(ind->error_code, ppWritePackedMsg, end)) + return 0; + + return 1; + } + return -1; +} + +int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* codec) { + if(header->message_id == P7_VENDOR_EXT_REQ) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))) + return 0; + return 1; + } + return -1; +} + +int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t* end, void** ve, nfapi_p7_codec_config_t* config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_phy_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_1_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_1)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int pnf_phy_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config) { + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} + +int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_2_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_2)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int pnf_sim_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} + +nfapi_dl_config_request_t dummy_dl_config_req; +nfapi_tx_request_t dummy_tx_req; + +nfapi_pnf_p7_subframe_buffer_t dummy_subframe; + +int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req) { + + printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); + + nfapi_set_trace_level(NFAPI_TRACE_INFO); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + phy_info* phy_info = pnf->phys; + + nfapi_pnf_p7_config_t* p7_config = nfapi_pnf_p7_config_create(); + + p7_config->phy_id = phy->phy_id; + + p7_config->remote_p7_port = phy_info->remote_port; + p7_config->remote_p7_addr = phy_info->remote_addr; + p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; + //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); + p7_config->local_p7_addr = phy_info->local_addr; + + printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port); + + p7_config->user_data = phy_info; + + p7_config->malloc = &pnf_allocate; + p7_config->free = &pnf_deallocate; + p7_config->codec_config.allocate = &pnf_allocate; + p7_config->codec_config.deallocate = &pnf_deallocate; + + p7_config->trace = &pnf_nfapi_trace; + + phy->user_data = p7_config; + + p7_config->subframe_buffer_size = phy_info->timing_window; + printf("subframe_buffer_size configured using phy_info->timing_window:%d\n", phy_info->timing_window); + if(phy_info->timing_info_mode & 0x1) { + p7_config->timing_info_mode_periodic = 1; + p7_config->timing_info_period = phy_info->timing_info_period; + } + + if(phy_info->timing_info_mode & 0x2) { + p7_config->timing_info_mode_aperiodic = 1; + } + + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; + + memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); + dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; + dummy_dl_config_req.dl_config_request_body.number_dci=0; + dummy_dl_config_req.dl_config_request_body.number_pdu=0; + dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; + dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; + dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; + + memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); + dummy_tx_req.tx_request_body.number_of_pdus=0; + dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; + + dummy_subframe.dl_config_req = &dummy_dl_config_req; + dummy_subframe.tx_req = 0;//&dummy_tx_req; + + dummy_subframe.ul_config_req=0; + dummy_subframe.hi_dci0_req=0; + dummy_subframe.lbt_dl_config_req=0; + + p7_config->dummy_subframe = dummy_subframe; + + p7_config->vendor_ext = &pnf_phy_vendor_ext; + + p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; + + p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); + + //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); + l1_north_init_eNB(); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); + p7_config_g = p7_config; + + // Need to wait for main thread to create RU structures + while(config_sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); + } + printf("[PNF] OAI eNB/RU configured\n"); + + printf("[PNF] About to call init_eNB_afterRU()\n"); + init_eNB_afterRU(); + + // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + + while(sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be started\n"); + } + + printf("[PNF] Sending PNF_START_RESP\n"); + nfapi_send_pnf_start_resp(config, p7_config->phy_id); + + printf("[PNF] Sending first P7 subframe ind\n"); + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + printf("[PNF] Sent first P7 subframe ind\n"); + + return 0; +} + +int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req) { + + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_measurement_resp(config, &resp); + return 0; +} + +int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req) { + + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_rssi_resp(config, &resp); + + nfapi_rssi_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RSSI_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + ind.rssi_indication_body.tl.tag = NFAPI_RSSI_INDICATION_TAG; + ind.rssi_indication_body.number_of_rssi = 1; + ind.rssi_indication_body.rssi[0] = -42; + nfapi_pnf_rssi_ind(config, &ind); + + return 0; +} + +int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req) { + + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_cell_search_resp(config, &resp); + + nfapi_cell_search_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) { + case NFAPI_RAT_TYPE_LTE: + ind.lte_cell_search_indication.tl.tag = NFAPI_LTE_CELL_SEARCH_INDICATION_TAG; + ind.lte_cell_search_indication.number_of_lte_cells_found = 1; + ind.lte_cell_search_indication.lte_found_cells[0].pci = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrp = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrq = 123; + ind.lte_cell_search_indication.lte_found_cells[0].frequency_offset = 123; + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; + ind.utran_cell_search_indication.number_of_utran_cells_found = 1; + ind.utran_cell_search_indication.utran_found_cells[0].psc = 89; + ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89; + ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89; + ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89; + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; + ind.geran_cell_search_indication.number_of_gsm_cells_found = 1; + ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23; + ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230; + + } + break; + } + + ind.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + ind.pnf_cell_search_state.length = 3; + + nfapi_pnf_cell_search_ind(config, &ind); + + return 0; +} + +int broadcast_detect_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req) +{ + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_broadcast_detect_resp(config, &resp); + + nfapi_broadcast_detect_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; + ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1; + ind.lte_broadcast_detect_indication.mib_length = 4; + //ind.lte_broadcast_detect_indication.mib... + ind.lte_broadcast_detect_indication.sfn_offset = 77; + + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; + ind.utran_broadcast_detect_indication.mib_length = 4; + //ind.utran_broadcast_detect_indication.mib... + // ind.utran_broadcast_detect_indication.sfn_offset; DJP - nonsense line + + } + break; + } + + ind.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + ind.pnf_cell_broadcast_state.length = 3; + + nfapi_pnf_broadcast_detect_ind(config, &ind); + + return 0; +} + +int system_information_schedule_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req) +{ + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_schedule_resp(config, &resp); + + nfapi_system_information_schedule_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 3; + ind.lte_system_information_indication.sib_length = 5; + //ind.lte_system_information_indication.sib... + + nfapi_pnf_system_information_schedule_ind(config, &ind); + + return 0; +} + +int system_information_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req) +{ + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_resp(config, &resp); + + nfapi_system_information_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 1; + ind.lte_system_information_indication.sib_length = 3; + //ind.lte_system_information_indication.sib... + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.utran_system_information_indication.sib_length = 3; + //ind.utran_system_information_indication.sib... + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.geran_system_information_indication.si_length = 3; + //ind.geran_system_information_indication.si... + + } + break; + } + + nfapi_pnf_system_information_ind(config, &ind); + + return 0; +} + +int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req) +{ + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_nmm_stop_resp(config, &resp); + return 0; +} + +int vendor_ext(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg); + + switch(msg->message_id) + { + case P5_VENDOR_EXT_REQ: + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)msg; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2); + // send back the P5_VENDOR_EXT_RSP + vendor_ext_p5_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); + rsp.header.message_id = P5_VENDOR_EXT_RSP; + rsp.error_code = NFAPI_MSG_OK; + nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp)); + } + break; + } + + return 0; +} + +nfapi_p4_p5_message_header_t* pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) { + + if(message_id == P5_VENDOR_EXT_REQ) { + (*msg_size) = sizeof(vendor_ext_p5_req); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_req)); + } + + return 0; +} + +void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) { + free(header); +} + +int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)(header); + return (!push16(rsp->error_code, ppWritePackedMsg, end)); + } + return 0; +} + +int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2); + } + return 0; +} + +/*------------------------------------------------------------------------------*/ + +void* pnf_start_thread(void* ptr) { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__); + + nfapi_pnf_config_t *config = (nfapi_pnf_config_t*)ptr; + + struct sched_param sp; + sp.sched_priority = 20; + pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); + + nfapi_pnf_start(config); + + return (void*)0; +} + +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { + + printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); + + nfapi_mode = 1; // PNF! + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + + config->vnf_ip_addr = vnf_ip_addr; + config->vnf_p5_port = vnf_p5_port; + + pnf.phys[0].udp.enabled = 1; + pnf.phys[0].udp.rx_port = pnf_p7_port; + pnf.phys[0].udp.tx_port = vnf_p7_port; + strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); + + strcpy(pnf.phys[0].local_addr, pnf_ip_addr); + + printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", + __FUNCTION__, + config->vnf_ip_addr, config->vnf_p5_port, + pnf.phys[0].local_addr, + pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, + pnf.phys[0].udp.rx_port); + + config->pnf_param_req = &pnf_param_request; + config->pnf_config_req = &pnf_config_request; + config->pnf_start_req = &pnf_start_request; + config->pnf_stop_req = &pnf_stop_request; + config->param_req = ¶m_request; + config->config_req = &config_request; + config->start_req = &start_request; + + config->measurement_req = &measurement_request; + config->rssi_req = &rssi_request; + config->cell_search_req = &cell_search_request; + config->broadcast_detect_req = &broadcast_detect_request; + config->system_information_schedule_req = &system_information_schedule_request; + config->system_information_req = &system_information_request; + config->nmm_stop_req = &nmm_stop_request; + + config->vendor_ext = &vendor_ext; + + config->trace = &pnf_nfapi_trace; + + config->user_data = &pnf; + + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv; + + config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext; + + config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&pnf_start_pthread, NULL, &pnf_start_thread, config); + + pthread_setname_np(pnf_start_pthread, "NFAPI_PNF"); +} + +void oai_subframe_ind(uint16_t sfn, uint16_t sf) { + + //LOG_D(PHY,"%s(sfn:%d, sf:%d)\n", __FUNCTION__, sfn, sf); + + //TODO FIXME - HACK - DJP - using a global to bodge it in + + if (p7_config_g != NULL && sync_var==0) { + + uint16_t sfn_sf_tx = sfn<<4 | sf; + + if ((sfn % 100 == 0) && sf==0) + { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u sf:%u) SFN/SF(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, sf, NFAPI_SFNSF2DEC(sfn_sf_tx)); + } + + int subframe_ret = nfapi_pnf_p7_subframe_ind(p7_config_g, p7_config_g->phy_id, sfn_sf_tx); + + if (subframe_ret) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u subframe:%u) SFN/SF(TX):%u - PROBLEM with pnf_p7_subframe_ind()\n", __FUNCTION__, sfn, sf, sfn_sf_tx, NFAPI_SFNSF2DEC(sfn_sf_tx)); + } else { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n"); + } + } else { + } +} + +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) { + + rach_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + LOG_D(PHY, "%s() sfn_sf:%d preambles:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(rach_ind->sfn_sf), rach_ind->rach_indication_body.number_of_preambles); + + return nfapi_pnf_p7_rach_ind(p7_config_g, rach_ind); +} + +int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind) { + + harq_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + harq_ind->header.message_id = NFAPI_HARQ_INDICATION; + + LOG_D(PHY, "%s() sfn_sf:%d number_of_harqs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(harq_ind->sfn_sf), harq_ind->harq_indication_body.number_of_harqs); + + int retval = nfapi_pnf_p7_harq_ind(p7_config_g, harq_ind); + + if (retval != 0) + LOG_E(PHY, "%s() sfn_sf:%d number_of_harqs:%d nfapi_pnf_p7_harq_ind()=%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(harq_ind->sfn_sf), harq_ind->harq_indication_body.number_of_harqs, retval); + + return retval; +} + +int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind) { + + crc_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + crc_ind->header.message_id = NFAPI_CRC_INDICATION; + + //LOG_D(PHY, "%s() sfn_sf:%d number_of_crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(crc_ind->sfn_sf), crc_ind->crc_indication_body.number_of_crcs); + + return nfapi_pnf_p7_crc_ind(p7_config_g, crc_ind); +} + +int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *ind) { + + ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ind->header.message_id = NFAPI_RX_CQI_INDICATION; + + //LOG_D(PHY, "%s() sfn_sf:%d number_of_cqis:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); + + return nfapi_pnf_p7_cqi_ind(p7_config_g, ind); +} + +int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind) { + + ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ind->header.message_id = NFAPI_RX_ULSCH_INDICATION; + + int retval = nfapi_pnf_p7_rx_ind(p7_config_g, ind); + + //LOG_D(PHY,"%s() SFN/SF:%d pdus:%d retval:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, retval); + + //free(ind.rx_indication_body.rx_pdu_list); + + return retval; +} + +int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind) { + + ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + int retval = nfapi_pnf_p7_sr_ind(p7_config_g, ind); + + //LOG_D(PHY,"%s() SFN/SF:%d srs:%d retval:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs, retval); + + //free(ind.rx_indication_body.rx_pdu_list); + + return retval; +} diff --git a/openair1/SIMULATION/ETH_TRANSPORT/pgm_link.h b/nfapi/oai_integration/nfapi_pnf.h similarity index 71% rename from openair1/SIMULATION/ETH_TRANSPORT/pgm_link.h rename to nfapi/oai_integration/nfapi_pnf.h index 03fa6d4b48..592d4877af 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/pgm_link.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -19,20 +19,9 @@ * contact@openairinterface.org */ -#ifndef PGM_LINK_H_ -#define PGM_LINK_H_ +#if !defined(NFAPI_PNF_H__) +#define NFAPI_PNF_H__ -/* Define prototypes only if enabled */ -#if defined(ENABLE_PGM_TRANSPORT) -void bypass_tx_nack(unsigned int frame, unsigned int next_slot); - -int pgm_oai_init(char *if_name); - -int pgm_recv_msg(int group, uint8_t *buffer, uint32_t length, - unsigned int frame, unsigned int next_slot); - -int pgm_link_send_msg(int group, uint8_t *data, uint32_t len); +void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); #endif - -#endif /* PGM_LINK_H_ */ diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c new file mode 100644 index 0000000000..07c3f1aa91 --- /dev/null +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -0,0 +1,1221 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nfapi_interface.h" +#include "nfapi_vnf_interface.h" +#include "nfapi.h" +#include "vendor_ext.h" + +#include "nfapi_vnf.h" + + +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + +typedef struct { + uint8_t enabled; + uint32_t rx_port; + uint32_t tx_port; + char tx_addr[80]; +} udp_data; + +typedef struct { + uint16_t index; + uint16_t id; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; + + udp_data udp; + + char local_addr[80]; + int local_port; + + char* remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + +} phy_info; + +typedef struct { + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +} rf_info; + +typedef struct { + + int release; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +} pnf_info; + +typedef struct mac mac_t; + +typedef struct mac { + + void* user_data; + + void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req); + void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req); + void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req); + void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req); +} mac_t; + +typedef struct { + + int local_port; + char local_addr[80]; + + unsigned timing_window; + unsigned periodic_timing_enabled; + unsigned aperiodic_timing_enabled; + unsigned periodic_timing_period; + + // This is not really the right place if we have multiple PHY, + // should be part of the phy struct + udp_data udp; + + uint8_t thread_started; + + nfapi_vnf_p7_config_t* config; + + mac_t* mac; + +} vnf_p7_info; + +typedef struct { + + uint8_t wireshark_test_mode; + pnf_info pnfs[2]; + vnf_p7_info p7_vnfs[2]; + +} vnf_info; + +int vnf_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n"); + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) { + case VENDOR_EXT_TLV_2_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); + vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + } + return -1; +} + +int vnf_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec) { + return -1; +} + +void install_schedule_handlers(IF_Module_t *if_inst); +extern int single_thread_flag; +extern void init_eNB_afterRU(void); +extern uint16_t sf_ahead; + +void oai_create_enb(void) { + + int bodge_counter=0; + PHY_VARS_eNB *eNB = RC.eNB[0][0]; + + printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d td:%p te:%p if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, eNB->single_thread_flag, eNB->td, eNB->te, eNB->if_inst); + + eNB->Mod_id = bodge_counter; + eNB->CC_id = bodge_counter; + eNB->abstraction_flag = 0; + eNB->single_thread_flag = 0;//single_thread_flag; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + + RC.nb_CC[bodge_counter] = 1; + + if (eNB->if_inst==0) { + eNB->if_inst = IF_Module_init(bodge_counter); + } + + // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY + // that will result in eNB->configured being set to TRUE. + // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values + if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) { + + printf("RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); + install_schedule_handlers(RC.eNB[0][0]->if_inst); + } + + do { + printf("%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); + usleep(50000); + } while(eNB->configured != 1); + + printf("%s() eNB is now configured\n", __FUNCTION__); +} + +void oai_enb_init(void) { + + printf("%s() About to call init_eNB_afterRU()\n", __FUNCTION__); + init_eNB_afterRU(); +} + +int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) { + + printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + + oai_create_enb(); + + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + nfapi_vnf_pnf_param_req(config, p5_idx, &req); + return 0; +} + +int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) { + printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + + vnf_p7_info* p7_vnf = vnf->p7_vnfs; + nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id); + + return 0; +} + +int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp) { + + printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + pnf_info *pnf = vnf->pnfs; + + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) + { + phy_info phy; + phy.index = resp->pnf_phy.phy[i].phy_config_index; + + printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) + { + printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; + } + + pnf->phys[0] = phy; + } + + for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) { + rf_info rf; + rf.index = resp->pnf_rf.rf[i].rf_config_index; + + printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); + + pnf->rfs[0] = rf; + } + + nfapi_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); + printf("DJP:Hard coded num phy rf to 2\n"); + + for(unsigned i = 0; i < 2; ++i) { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0]; + } + + nfapi_vnf_pnf_config_req(config, p5_idx, &req); + + return 0; +} + +int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp) { + + printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); + + if(1) { + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.phy_id = resp->header.phy_id; + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } else { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + + //vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + return 0; +} + +int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { + + eNB_proc_t *proc=&eNB->proc; + + eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[sf&1]; + + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + + //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + + //int i; + struct timespec wait; + + wait.tv_sec=0; + wait.tv_nsec=5000000L; + +#if 0 + /* accept some delay in processing - up to 5ms */ + for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { + LOG_W( PHY,"[eNB] sfn/sf:%d:%d proc_rxtx[%d]:TXsfn:%d/%d eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", sfn, sf, sf&1, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); + usleep(500); + } + if (proc_rxtx->instance_cnt_rxtx == 0) { + exit_fun( "TX thread busy" ); + return(-1); + } +#endif + + // wake up TX for subframe n+sf_ahead + // lock the TX mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); + exit_fun( "error locking mutex_rxtx" ); + return(-1); + } + + { + static uint16_t old_sf = 0; + static uint16_t old_sfn = 0; + + proc->subframe_rx = old_sf; + proc->frame_rx = old_sfn; + + // Try to be 1 frame back + old_sf = sf; + old_sfn = sfn; + + if (old_sf == 0 && old_sfn % 100==0) LOG_W( PHY,"[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx); + } + + ++proc_rxtx->instance_cnt_rxtx; + + //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] proc_rxtx->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx); + + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // transmitted timestamp of the next TX slot (first). + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+sf_ahead + proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); + proc_rxtx->frame_rx = proc->frame_rx; + proc_rxtx->subframe_rx = proc->subframe_rx; + proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; + proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; + + //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] proc_rxtx[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx, proc_rxtx->frame_rx, proc_rxtx->subframe_rx); + + // the thread can now be woken up + if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } + + //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__); + pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); + //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__); + + return(0); +} + +extern pthread_cond_t nfapi_sync_cond; +extern pthread_mutex_t nfapi_sync_mutex; +extern int nfapi_sync_var; + +int phy_sync_indication(struct nfapi_vnf_p7_config* config, uint8_t sync) { + + printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); + + if (sync==1 && nfapi_sync_var!=0) { + + printf("[VNF] Signal to OAI main code that it can go\n"); + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } + + return(0); +} + +int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf) { + + static uint8_t first_time = 1; + if (first_time) { + printf("[VNF] subframe indication %d\n", NFAPI_SFNSF2DEC(sfn_sf)); + first_time = 0; + } + + if (RC.eNB && RC.eNB[0][0]->configured) { + uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); + uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); + + //LOG_D(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf); + + wake_eNB_rxtx(RC.eNB[0][0], sfn, sf); + } else { + printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB); + if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured); + } + + return 0; +} + +int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind) { + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_preambles:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + printf("[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.rach_ind = *ind; + eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = eNB->preamble_list; + + for (int i=0;irach_indication_body.number_of_preambles;i++) { + if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) { + + printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", + i, + ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, + ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, + ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance + ); + } + + if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) { + printf("RACH PREAMBLE REL13 present\n"); + } + + eNB->preamble_list[i] = ind->rach_indication_body.preamble_list[i]; + } + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_rach_ind(p7_vnf->mac, ind); + return 1; +} + +int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind) { + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->harq_indication_body.number_of_harqs); + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.harq_ind = *ind; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + + for (int i=0; iharq_indication_body.number_of_harqs; i++) { + memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i])); + } + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_harq_ind(p7_vnf->mac, ind); + + return 1; +} + +int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind) { + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.crc_ind = *ind; + + nfapi_crc_indication_t *dest_ind = &eNB->UL_INFO.crc_ind; + nfapi_crc_indication_pdu_t *dest_pdu_list = eNB->crc_pdu_list; + + *dest_ind = *ind; + dest_ind->crc_indication_body.crc_pdu_list = dest_pdu_list; + + if (ind->crc_indication_body.number_of_crcs==0) + LOG_D(MAC, "%s() NFAPI SFN/SF:%d IND:number_of_crcs:%u UL_INFO:crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs); + + for (int i=0; icrc_indication_body.number_of_crcs; i++) { + memcpy(&dest_ind->crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0])); + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + i, + ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti, + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); + } + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_crc_ind(p7_vnf->mac, ind); + + return 1; +} + +int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind) { + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + if (ind->rx_indication_body.number_of_pdus==0) { + LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_pdus:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus); + } + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + nfapi_rx_indication_t *dest_ind = &eNB->UL_INFO.rx_ind; + nfapi_rx_indication_pdu_t *dest_pdu_list = eNB->rx_pdu_list; + + *dest_ind = *ind; + dest_ind->rx_indication_body.rx_pdu_list = dest_pdu_list; + + for(int i=0; irx_indication_body.number_of_pdus; i++) { + nfapi_rx_indication_pdu_t *dest_pdu = &dest_ind->rx_indication_body.rx_pdu_list[i]; + nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i]; + + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + + // DJP - TODO FIXME - intentional memory leak + dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length); + + memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length); + + LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, + dest_pdu->rx_ue_information.handle, + dest_pdu->rx_ue_information.rnti, + dest_pdu->rx_indication_rel8.length, + dest_pdu->rx_indication_rel8.offset, + dest_pdu->rx_indication_rel8.ul_cqi, + dest_pdu->rx_indication_rel8.timing_advance, + dest_pdu->data + ); + } + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_rx_ind(p7_vnf->mac, ind); + return 1; +} +int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind) { + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_srs_ind(p7_vnf->mac, ind); + return 1; +} + +int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind) { + + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs); + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind; + nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list; + + *dest_ind = *ind; + dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list; + + LOG_D(MAC,"%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); + + for (int i=0;iUL_INFO.sr_ind.sr_indication_body.number_of_srs;i++) { + nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i]; + nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; + + LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); + + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + } + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_sr_ind(p7_vnf->mac, ind); + + return 1; +} + +int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind) { + + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_cqi_ind(p7_vnf->mac, ind); + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.cqi_ind = ind->cqi_indication_body; + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + return 1; +} + +int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind) { + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_lbt_dl_ind(p7_vnf->mac, ind); + return 1; +} + +int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind) { + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_nb_harq_ind(p7_vnf->mac, ind); + return 1; +} + +int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind) { + // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + //mac_nrach_ind(p7_vnf->mac, ind); + return 1; +} + +void* vnf_allocate(size_t size) { + //return (void*)memory_pool::allocate(size); + return (void*)malloc(size); +} + +void vnf_deallocate(void* ptr) { + //memory_pool::deallocate((uint8_t*)ptr); + free(ptr); +} + +extern void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args); + +void vnf_trace(nfapi_trace_level_t nfapi_level, const char* message, ...) { + + va_list args; + int oai_level; + + if (nfapi_level==NFAPI_TRACE_ERROR) + { + oai_level = LOG_ERR; + } + else if (nfapi_level==NFAPI_TRACE_WARN) + { + oai_level = LOG_WARNING; + } + else if (nfapi_level==NFAPI_TRACE_NOTE) + { + oai_level = LOG_INFO; + } + else if (nfapi_level==NFAPI_TRACE_INFO) + { + oai_level = LOG_INFO; + } + else + { + oai_level = LOG_INFO; + } + + va_start(args, message); + nfapi_log("FILE>", "FUNC", 999, PHY, oai_level, message, args); + va_end(args); +} + +int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg) { + + if(msg->message_id == P7_VENDOR_EXT_IND) + { + //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; + //printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code); + } + else + { + printf("[VNF] unknown %02x\n", msg->message_id); + } + return 0; +} + +nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) { + if(message_id == P7_VENDOR_EXT_IND) + { + *msg_size = sizeof(vendor_ext_p7_ind); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind)); + } + return 0; +} + +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) { + free(header); +} + +int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec) { + + (void)tl; + (void)ppReadPackedMessage; + (void)ve; + return -1; +} + +int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec) { + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) { + case VENDOR_EXT_TLV_1_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + default: + return -1; + break; + } +} + +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config) { + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) { + vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header); + if(!pull16(ppReadPackedMessage, &req->error_code, end)) + return 0; + } + + return 1; +} + +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_REQ) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))) + return 0; + } + return 1; +} + +int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); + return (!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))); + } + return 0; +} + +static pthread_t vnf_start_pthread; +static pthread_t vnf_p7_start_pthread; + +void* vnf_p7_start_thread(void *ptr) { + + printf("%s()\n", __FUNCTION__); + + pthread_setname_np(pthread_self(), "VNF_P7"); + + nfapi_vnf_p7_config_t* config = (nfapi_vnf_p7_config_t*)ptr; + + nfapi_vnf_p7_start(config); + + return config; +} + +void set_thread_priority(int priority); + +void* vnf_p7_thread_start(void* ptr) { + + set_thread_priority(79); + + vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; + + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->sync_indication = &phy_sync_indication; + p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->harq_indication = &phy_harq_indication; + p7_vnf->config->crc_indication = &phy_crc_indication; + p7_vnf->config->rx_indication = &phy_rx_indication; + p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->srs_indication = &phy_srs_indication; + p7_vnf->config->sr_indication = &phy_sr_indication; + p7_vnf->config->cqi_indication = &phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &phy_nrach_indication; + p7_vnf->config->malloc = &vnf_allocate; + p7_vnf->config->free = &vnf_deallocate; + + p7_vnf->config->trace = &vnf_trace; + + p7_vnf->config->vendor_ext = &phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + + p7_vnf->mac->user_data = p7_vnf; + + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &vnf_allocate; + p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config); + + return 0; +} + +int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp) { + + vnf_info* vnf = (vnf_info*)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + nfapi_param_request_t req; + + printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); + + if(p7_vnf->thread_started == 0) { + + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, p7_vnf); + p7_vnf->thread_started = 1; + } + else + { + // P7 thread already running. + } + + // start all the phys in the pnf. + printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = pnf->phys[0].id; + + nfapi_vnf_param_req(config, p5_idx, &req); + + return 0; +} + +extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw); + +int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp) { + + printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + struct sockaddr_in pnf_p7_sockaddr; + nfapi_config_request_t *req = &RC.mac[0]->config[0]; + + phy->remote_port = resp->nfapi_config.p7_pnf_port.value; + + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + + phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + + // for now just 1 + + printf("[VNF] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period); + + req->header.message_id = NFAPI_CONFIG_REQUEST; + req->header.phy_id = phy->id; + + printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); + + req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; + req->num_tlv++; + + printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); + + req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); + memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req->num_tlv++; + printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + + req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = p7_vnf->timing_window; + printf("[VNF] Timing window:%d\n", p7_vnf->timing_window); + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { + + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled); + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled) { + + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period; + req->num_tlv++; + } + } + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req->vendor_extension = &ve2.tl; + + nfapi_vnf_config_req(config, p5_idx, req); + printf("[VNF] Sent NFAPI_CONFIG_REQ num_tlv:%u\n",req->num_tlv); + + return 0; +} + +int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp) { + + nfapi_start_request_t req; + + printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + printf("[VNF] Calling oai_enb_init()\n"); + oai_enb_init(); + + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_vnf_start_req(config, p5_idx, &req); + + printf("[VNF] Send NFAPI_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + return 0; +} + +int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp) { + + printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); + + return 0; +} + +int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) { + + printf("[VNF] %s\n", __FUNCTION__); + + switch(msg->message_id) { + case P5_VENDOR_EXT_RSP: + { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg; + printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + + // send the start request + + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + break; + } + + return 0; +} + +int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) + { + vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header); + return(!pull16(ppReadPackedMessage, &req->error_code, end)); + } + return 0; +} + +nfapi_p4_p5_message_header_t* vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) { + + if(message_id == P5_VENDOR_EXT_RSP) { + *msg_size = sizeof(vendor_ext_p5_rsp); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp)); + } + return 0; +} + +void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) { + free(header); +} + +nfapi_vnf_config_t *config = 0; + +void vnf_start_thread(void* ptr) { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__); + + pthread_setname_np(pthread_self(), "VNF"); + + config = (nfapi_vnf_config_t*)ptr; + + nfapi_vnf_start(config); +} + +static vnf_info vnf; +extern uint8_t nfapi_mode; +/*------------------------------------------------------------------------------*/ +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) +{ + nfapi_mode = 2; + + memset(&vnf, 0, sizeof(vnf)); + + memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs)); + + vnf.p7_vnfs[0].timing_window = 32; + vnf.p7_vnfs[0].periodic_timing_enabled = 1; + vnf.p7_vnfs[0].aperiodic_timing_enabled = 0; + vnf.p7_vnfs[0].periodic_timing_period = 10; + + vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); + + strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); + vnf.p7_vnfs[0].local_port = 50001; + vnf.p7_vnfs[0].mac = (mac_t*)malloc(sizeof(mac_t)); + + nfapi_vnf_config_t* config = nfapi_vnf_config_create(); + + config->malloc = malloc; + config->free = free; + config->trace = &vnf_trace; + + config->vnf_p5_port = vnf_p5_port; + config->vnf_ipv4 = 1; + config->vnf_ipv6 = 0; + + config->pnf_list = 0; + config->phy_list = 0; + + config->pnf_connection_indication = &pnf_connection_indication_cb; + config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + config->pnf_param_resp = &pnf_param_resp_cb; + config->pnf_config_resp = &pnf_config_resp_cb; + config->pnf_start_resp = &pnf_start_resp_cb; + config->param_resp = ¶m_resp_cb; + config->config_resp = &config_resp_cb; + config->start_resp = &start_resp_cb; + config->vendor_ext = &vendor_ext_cb; + + config->user_data = &vnf; + + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv; + + config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &vnf_allocate; + config->codec_config.deallocate = &vnf_deallocate; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_start_pthread, NULL, (void*)&vnf_start_thread, config); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); +} + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) +{ + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req); + + dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1; + dl_config_req->dl_config_request_body.number_dci = 0; + dl_config_req->dl_config_request_body.number_pdu = 0; + dl_config_req->dl_config_request_body.number_pdsch_rnti = 0; + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } + return retval; +} + +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) +{ + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + //LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus); + + int retval = nfapi_vnf_p7_tx_req(p7_config, tx_req); + + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + tx_req->tx_request_body.number_of_pdus = 0; + } + return retval; +} + +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + //LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi); + + int retval = nfapi_vnf_p7_hi_dci0_req(p7_config, hi_dci0_req); + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + hi_dci0_req->hi_dci0_request_body.number_of_hi = 0; + hi_dci0_req->hi_dci0_request_body.number_of_dci = 0; + } + return retval; +} + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { + + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + + //LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id); + + //LOG_D(PHY, "[VNF] %s() UL_CONFIG sfn_sf:%d PDUs:%d rach_prach_frequency_resources:%d srs_present:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ul_config_req->sfn_sf), ul_config_req->ul_config_request_body.number_of_pdus, ul_config_req->ul_config_request_body.rach_prach_frequency_resources, ul_config_req->ul_config_request_body.srs_present); + + int retval = nfapi_vnf_p7_ul_config_req(p7_config, ul_config_req); + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + // Reset number of PDUs so that it is not resent + ul_config_req->ul_config_request_body.number_of_pdus = 0; + ul_config_req->ul_config_request_body.rach_prach_frequency_resources = 0; + ul_config_req->ul_config_request_body.srs_present = 0; + } + return retval; +} diff --git a/openair2/RRC/LITE/MESSAGES/rtai_mem.h b/nfapi/oai_integration/nfapi_vnf.h similarity index 70% rename from openair2/RRC/LITE/MESSAGES/rtai_mem.h rename to nfapi/oai_integration/nfapi_vnf.h index 9efc24851f..4ea26eda12 100644 --- a/openair2/RRC/LITE/MESSAGES/rtai_mem.h +++ b/nfapi/oai_integration/nfapi_vnf.h @@ -19,26 +19,9 @@ * contact@openairinterface.org */ -/*! \file rtai_mem.h -* \brief a wrapper for Unified RTAI real-time memory management. -* \author Florian Kaltenberger -* \date 2011-04-06 -* \version 0.1 -* \company Eurecom -* \email: florian.kaltenberger@eurecom.fr -* \note -* \bug -* \warning -*/ +#if !defined(NFAPI_VNF_H__) +#define NFAPI_VNF_H__ -/* -void* rt_alloc_wrapper(int size); +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port); -int rt_free_wrapper(void* ptr); - -void* rt_realloc_wrapper(void* oldptr, int size); -*/ - -void* rt_realloc(void* oldptr, int size); - -void* rt_calloc(int nmemb, int size); +#endif diff --git a/nfapi/oai_integration/vendor_ext.h b/nfapi/oai_integration/vendor_ext.h new file mode 100644 index 0000000000..0622432260 --- /dev/null +++ b/nfapi/oai_integration/vendor_ext.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _VENDOR_EXT_H_ +#define _VENDOR_EXT_H_ + +#include "nfapi_interface.h" + +typedef enum { + P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN, + P5_VENDOR_EXT_RSP, + + P7_VENDOR_EXT_REQ, + P7_VENDOR_EXT_IND + +} vendor_ext_message_id_e; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p5_req; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t error_code; +} vendor_ext_p5_rsp; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p7_req; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t error_code; +} vendor_ext_p7_ind; + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_1; + +#define VENDOR_EXT_TLV_1_TAG 0xF001 + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_2; + +#define VENDOR_EXT_TLV_2_TAG 0xF002 + +#endif // _VENDOR_EXT_ diff --git a/nfapi/open-nFAPI/.travis.yml b/nfapi/open-nFAPI/.travis.yml new file mode 100644 index 0000000000..ce2faea923 --- /dev/null +++ b/nfapi/open-nFAPI/.travis.yml @@ -0,0 +1,36 @@ + +env: + global: + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "oNj8JhGBN/zjzrAU7y2Nn/wxSxA/MDp2Y8fVLLp6fhx+y2mWdlMZhgCjeKSpdbGtroUnxErX1P8t+8EPz2+mMoq+G809Q9t7eJjd1+6nkVhEEfDXN83BmJkvIylC0/IKJiT2wCa8LzbdhpQUFyZ1Gk1WKZozAW5HotfFjm6/NFi/GX4uA7S0tU5E4yC3r4yqH9cLZ+arWMOEY/X0lrx0n6tLjDe921kFwkZQGFzAzrbXN2fZXKQ3xFcpREWEgEWsY7H2n4T7oJI3nEPY4P/4kvCjeQMjnlATEwtcciBiUbHRew4WWSTndF54crRlqFlzFcEf/Ouz27U/d2xYHJWcWNi88l+/qsb+V0uobwhiGUJGbVhf9IkgEO3tr/zbwkPDFrXpa/1xuSoc6jDm8i61gKQkcBhQsRFXlciPvwLhiL07gzeAfZD1Yke3tE+0geHPbEA0czzwtHe35jorAKYWsFXOXmcoK9t9SpnvBRFz6JuEsHPooafze43sTJg3qkgBszkU+U38CneeAVwo/uTA3Zw1ZrtOQv56v0UvAHze/VAF5z3rFJPl1oJl60OI8V5UBg4yIa2bySKhO//zwd4MGmsBpcWwDuu2BHUVasfk0vaetVxVVtdXG/2BuBP+IXinpJtI48NSFs6PT82dHz4cDF/iLDs0hPC6sbV258PY8F0=" + +language: cpp + +dist: trusty +sudo: required + +compiler: + - g++ + +before_install: + - sudo apt-get install doxygen + - sudo apt-get install libcunit1-dev + - sudo apt-get install libz-dev + - sudo apt-get install libsctp-dev + - sudo apt-get install libboost-all-dev + - autoreconf -i + +addons: + coverity_scan: + project: + name: cisco-open-nFAPI + version: 1.0 + description: Build submitted via Travis CI + notification_email: xxx@cisco.com + build_command_prepend: ./configure + build_command: make + branch_pattern: coverity_scan + +script: + - ./configure && make && make check diff --git a/nfapi/open-nFAPI/CHANGELOG.md b/nfapi/open-nFAPI/CHANGELOG.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/nfapi/open-nFAPI/LICENSE.md b/nfapi/open-nFAPI/LICENSE.md new file mode 100644 index 0000000000..5e0fd33cbb --- /dev/null +++ b/nfapi/open-nFAPI/LICENSE.md @@ -0,0 +1,201 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all +other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or +Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work +(an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the purposes +of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, +the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including +the original version of the Work and any modifications or additions +to that Work or Derivative Works thereof, that is intentionally +submitted to Licensor for inclusion in the Work by the copyright owner +or by an individual or Legal Entity authorized to submit on behalf of +the copyright owner. For the purposes of this definition, "submitted" +means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work, +where such license applies only to those patent claims licensable +by such Contributor that are necessarily infringed by their +Contribution(s) alone or by combination of their Contribution(s) +with the Work to which such Contribution(s) was submitted. If You +institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work +or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate +as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You +meet the following conditions: + +(a) You must give any other recipients of the Work or +Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices +stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and +attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of +the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained +within such NOTICE file, excluding those notices that do not +pertain to any part of the Derivative Works, in at least one +of the following places: within a NOTICE text file distributed +as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, +within a display generated by the Derivative Works, if and +wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and +do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside +or as an addendum to the NOTICE text from the Work, provided +that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and +may provide additional or different license terms and conditions +for use, reproduction, or distribution of Your modifications, or +for any such Derivative Works as a whole, provided Your use, +reproduction, and distribution of the Work otherwise complies with +the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "{}" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + +Copyright {yyyy} {name of copyright owner} + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +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. diff --git a/nfapi/open-nFAPI/Makefile.am b/nfapi/open-nFAPI/Makefile.am new file mode 100644 index 0000000000..900cf2bbcf --- /dev/null +++ b/nfapi/open-nFAPI/Makefile.am @@ -0,0 +1,15 @@ +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS =common/ \ + sim_common/ \ + nfapi/ \ + pnf/ \ + vnf/ \ + nfapi/tests \ + pnf/tests \ + vnf/tests \ + pnf_sim/ \ + vnf_sim/ \ + integration_tests/ \ + docs/ \ + $(NULL) diff --git a/nfapi/open-nFAPI/README.md b/nfapi/open-nFAPI/README.md new file mode 100644 index 0000000000..f3132c78d6 --- /dev/null +++ b/nfapi/open-nFAPI/README.md @@ -0,0 +1,138 @@ +[![Build Status](https://travis-ci.org/cisco/open-nFAPI.svg?branch=master)](https://travis-ci.org/cisco/open-nFAPI) +[![Coverity Status](https://scan.coverity.com/projects/11791/badge.svg)](https://scan.coverity.com/projects/cisco-open-nfapi) + +# open-nFAPI + +Open-nFAPI is implementation of the Small Cell Forum's network functional API or nFAPI for short. +nFAPI defines a network protocol that is used to connect a Physical Network Function (PNF) +running LTE Layer 1 to a Virtual Network Function (VNF) running LTE layer 2 and above. The specification +can be found at http://scf.io/documents/082. + +The aim of open-nFAPI is to provide an open interface between LTE layer 1 and layer 2 to allow for +interoperability between the PNF and VNF & also to facilitate the sharing of PNF's between +different VNF's + +Open-nFAPI implements the P4, P5 and P7 interfaces as defined by the nFAPI specification. +* The P5 interface allows the VNF to query and configure the 'resources' of the PNF; i.e slice it into + 1 or more PHY instances. +* The P7 interface is used to send the subframe information between the PNF and VNF for a PHY instance +* The P4 interface allows the VNF to request the PNF PHY instance to perform measurements of the surrounding network + +The remaining interfaces are currently outside of the scope of this project. + +Supports release 082.09.05 of the nFAPI specification + +**The Small Cell Forum cordially requests that any derivative work that looks to +extend the nFAPI libraries use the specified vendor extension techniques, +so ensuring the widest interoperability of the baseline nFAPI specification +in those derivative works.** + +## Awards + +The Open-nFAPI project has won the Small Cell Forum Judges Choice award 2017. (http://www.smallcellforum.org/awards-2/winners-2017/) + +## Licensing + +The open-nFAPI libraries are release by CISCO under an Apache 2 license. See `LICENSE.md` file for details + +## Downloading + +The open-nFAPI project can be pulled from git hub + +``` +git clone https://github.com/cisco/open-nFAPI.git nfapi +``` + +The following dependencies are required. These are based on a fresh ubuntu installation. + +``` +sudo apt-get install autoconf +sudo apt-get install gcc +sudo apt-get install g++ +sudo apt-get install libtool +sudo apt-get install make +sudo apt-get install doxygen +sudo apt-get install libcunit1-dev +sudo apt-get install libz-dev +sudo apt-get install libsctp-dev +sudo apt-get install libboost-all-dev +``` + + + +## Building + +To build the open-nFAPI project + +``` +autoreconf -i +./configure +make +``` + +To run the unit and integration tests + +``` +make check +``` + +You may notice in the console output of the final integration tests the following + +``` +*** Missing subframe 123 125 +``` + +Out of the box the machine on which you are running has not be configured for real time operation as a result +the vnf may not be scheduled at the correct times and hence it may risk 'missing' subframe opportunities. This +warning indicates this has happened. + +## Running the simulator + +The vnf and pnf simulator can be run using the following commands. The pnf and vnf simulator support sourcing and sinking +data over udp. Review the xml configuration files for the details of the port and address to configure. Console logging will show +which address:port is being used + +Note : Pinning the simulators to unused cores will produce more consistent behaviour. + +Note : You may have to run the processes with sudo to be able to set the real time scheduling and priority + +### vnf simulator + +To run the vnf simulator you need to specify the port the vnf will listen for p5 connection request upon and also the xml configuration file + +``` +vnfsim +``` + +### pnf simulator + +To run the vnf simulator you need to specify the addrss & port the pnf will connect to the vnf on and also the xml configuration file + +``` +pnfsim
+``` + + +## Directory structure + +``` +docs doxgen documentation +common common code used by the nfapi libraries +nfapi the nfapi library including message definitions & encode/decode functions +pnf the pnf library for p4, p5, & p7 interfaces +vnf the vnf library for p4, p5, & p7 interfaces +sim_common common simulation for used by the vnf and pnf sim +vnf_sim a vnf simulator including a stub mac implementation +pnf_sim a pnf simualtor including a fapi interface defintion and stub implementation +xml xml configuration files for the vnf and pnf simulator +wireshark code for a wireshark dissector for the nFAPI protocol +``` + +## Coverity + +Coverity runs on the coverity-scan branch. Changes must be merged to the coverity-scan branch to be checked. + + +## eNB Integration - Open Air Interface + +The open-nFAPI implementation has been integrated with the Open Air Interface solution here (https://gitlab.eurecom.fr/oai/openairinterface5g) and is (at the time of writing) here (https://gitlab.eurecom.fr/daveprice/openairinterface5g/tree/nfapi-ru-rau-split). The open-nFAPI implementation is integrated with the source eNB implementation with any changes required applied as a patch on top of the baseline open-nFAPI library. Any extensions required must be implemented through the vendor extensions as specified by the Small Cell Forum documentation. Any integration wrapping of functionality must be done within the target environment as shown in the Open Air Interface implementation nfapi directory which is defined by the $NFAPI_DIR location at the top level. diff --git a/nfapi/open-nFAPI/common/Makefile.am b/nfapi/open-nFAPI/common/Makefile.am new file mode 100644 index 0000000000..3e3326ea2c --- /dev/null +++ b/nfapi/open-nFAPI/common/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AM_CPPFLAGS = -I$(top_srcdir)/common/public_inc -g -Wall -Werror + +noinst_LIBRARIES =libnfapi_common.a + +libnfapi_common_a_SOURCES = src/debug.c + +libnfapi_common_a_CFLAGS =$(AM_CFLAGS) + +lib_LTLIBRARIES =libnfapi_common.la + +libnfapi_common_la_SOURCES = src/debug.c + + + + diff --git a/nfapi/open-nFAPI/common/public_inc/debug.h b/nfapi/open-nFAPI/common/public_inc/debug.h new file mode 100644 index 0000000000..14f97a17f6 --- /dev/null +++ b/nfapi/open-nFAPI/common/public_inc/debug.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +/*! The trace levels used by the nfapi libraries */ +typedef enum nfapi_trace_level +{ + NFAPI_TRACE_ERROR = 1, + NFAPI_TRACE_WARN, + NFAPI_TRACE_NOTE, + NFAPI_TRACE_INFO, + + NFAPI_TRACE_LEVEL_MAX +} nfapi_trace_level_t; + +/*! The trace function pointer */ +typedef void (*nfapi_trace_fn_t)(nfapi_trace_level_t level, const char* format, ...); + +/*! Global trace function */ +extern nfapi_trace_fn_t nfapi_trace_g; + +/*! Global trace level */ +extern nfapi_trace_level_t nfapi_trace_level_g; + +/*! NFAPI trace macro */ +//#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } +#define NFAPI_TRACE(level, format, ...) { if (nfapi_trace_g) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } + +/*! Function to change the trace level + * \param new_level The modified trace level + */ + +void nfapi_set_trace_level(nfapi_trace_level_t new_level); + +#endif /* _DEBUG_H_ */ diff --git a/nfapi/open-nFAPI/common/src/debug.c b/nfapi/open-nFAPI/common/src/debug.c new file mode 100644 index 0000000000..a45d41d7d7 --- /dev/null +++ b/nfapi/open-nFAPI/common/src/debug.c @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_MSG_LENGTH 2096 +#define TRACE_HEADER_LENGTH 44 + +void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...); + +// initialize the trace function to 0 +void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg; + +nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO; +//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN; + +void nfapi_set_trace_level(nfapi_trace_level_t new_level) +{ + nfapi_trace_level_g = new_level; +} + +void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...) +{ + char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH]; + uint32_t num_chars; + va_list p_args; + struct timeval tv; + pthread_t tid = pthread_self(); + + (void)gettimeofday(&tv, NULL); + + num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid); + + if (num_chars > TRACE_HEADER_LENGTH) + { + printf("trace_dbg: Error, num_chars is too large: %d", num_chars); + return; + } + + va_start(p_args, format); + if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args))) + { + if (level <= NFAPI_TRACE_WARN) + { + printf("%s", trace_buff); + } + printf("%s", trace_buff); + } + va_end(p_args); +} diff --git a/nfapi/open-nFAPI/configure.ac b/nfapi/open-nFAPI/configure.ac new file mode 100644 index 0000000000..fd3b387ee5 --- /dev/null +++ b/nfapi/open-nFAPI/configure.ac @@ -0,0 +1,45 @@ +AC_INIT([open-nFAPI], [1.0]) + +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign serial-tests]) +AM_PROG_AR + +LT_INIT([shared static]) + +# Dependencies +AC_PROG_CC +AC_PROG_CXX +AC_PROG_AWK +AC_CONFIG_HEADERS([config.h]) + +AC_PROG_LIBTOOL + +AC_CHECK_FILE([/usr/include/CUnit/CUnit.h], + [CFLAGS_CUNIT=-I/usr/include/CUnit AC_SUBST(CFLAGS_CUNIT)], + [AC_MSG_NOTICE([Have cunit *************])]) + +# Need doxygen +AC_CHECK_PROGS([DOXYGEN], [doxygen]) +if test -z "$DOXYGEN"; + then AC_MSG_WARN([Doxygen not found - continuing without Doxygen support]) +fi +AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([docs/Doxyfile])]) + +AC_REQUIRE_AUX_FILE([tap-driver.sh]) + +AC_CONFIG_FILES([Makefile + sim_common/Makefile + common/Makefile + nfapi/Makefile + pnf/Makefile + vnf/Makefile + nfapi/tests/Makefile + pnf/tests/Makefile + vnf/tests/Makefile + pnf_sim/Makefile + vnf_sim/Makefile + integration_tests/Makefile + docs/Makefile +]) +AC_OUTPUT diff --git a/nfapi/open-nFAPI/docs/Doxyfile b/nfapi/open-nFAPI/docs/Doxyfile new file mode 100644 index 0000000000..9491727d2b --- /dev/null +++ b/nfapi/open-nFAPI/docs/Doxyfile @@ -0,0 +1,1720 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = open-nFAPI + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../nfapi/public_inc ../pnf/public_inc ../vnf/public_inc ../docs/doxygen.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp. + +HTML_TIMESTAMP = NO + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/nfapi/open-nFAPI/docs/Doxyfile.in b/nfapi/open-nFAPI/docs/Doxyfile.in new file mode 100644 index 0000000000..74d405ad00 --- /dev/null +++ b/nfapi/open-nFAPI/docs/Doxyfile.in @@ -0,0 +1,1720 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = @PACKAGE_NAME@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @PACKAGE_VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @top_srcdir@/nfapi/public_inc @top_srcdir@/pnf/public_inc @top_srcdir@/vnf/public_inc @top_srcdir@/docs/doxygen.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp. + +HTML_TIMESTAMP = NO + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/nfapi/open-nFAPI/docs/Makefile.am b/nfapi/open-nFAPI/docs/Makefile.am new file mode 100644 index 0000000000..9530fa844d --- /dev/null +++ b/nfapi/open-nFAPI/docs/Makefile.am @@ -0,0 +1,35 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +if HAVE_DOXYGEN +directory = $(top_srcdir)/docs/man/man3/ + +dist_man_MANS = $(directory)/man_page_1.3 $(directory)/man_page_2.3 +$(directory)/man_page_1.3: doxyfile.stamp +$(directory)/man_page_2.3: doxyfile.stamp + +doxyfile.stamp: + $(DOXYGEN) Doxyfile + echo Timestamp > doxyfile.stamp + +CLEANFILES = doxyfile.stamp + +all-local: doxyfile.stamp +clean-local: + rm -rf $(top_srcdir)/docs/man + rm -rf $(top_srcdir)/docs/html + rm -rf $(top_srcdir)/docs/latex +endif diff --git a/nfapi/open-nFAPI/docs/doxygen.h b/nfapi/open-nFAPI/docs/doxygen.h new file mode 100644 index 0000000000..ae815e68d6 --- /dev/null +++ b/nfapi/open-nFAPI/docs/doxygen.h @@ -0,0 +1,327 @@ +/*! \mainpage Open Network Function Application Platform Interface (Open-nFAPI) + * + * \section intro_sec Introduction + * + * Open-nFAPI is implementation of the Small Cell Forum's network femto API or nFAPI for short. + * nFAPI defines a network protocol that is used to connect a Physical Network Function (PNF) + * running LTE Layer 1 to a Virtual Network Function (VNF) running LTE Layer 2 and above. The specification + * can be found at http://scf.io/documents/082. + * + * The aim of Open-nFAPI is to provide an open interface between LTE Layer 1 and Layer 2 to allow for + * interoperability between the PNF and VNF & also to facilitate the sharing of PNF's between + * different VNF's + * + * Open-nFAPI implements the P4, P5 and P7 interfaces as defined by the nFAPI specification. + * - The P5 interface allows the VNF to query and configure the 'resources' of the PNF; slicing it into + * 1 or more phy instances. + * - The P7 interface is used to send the subframe information between the PNF and VNF for 1 or more phy instances + * - The P4 interface allows the VNF to request the PNF phy instances to perform measurements of the surrounding network + * + * The remaining interfaces are currently outside of the scope of this project. + * + * The best place to start is by reviewing the detailed nFAPI call flow which can be \ref nfapi_call_flow "here" + * + * \section contrib Contibuting + * + * The Small Cell Forum cordially requests that any derivative work that looks to extend + * the nFAPI libraries use the specified vendor extension techniques, so ensuring + *the widest interoperability of the baseline nFAPI specification in those derivative works. + * + * \section install_sec Installation + * + * \subsection step1 Step 1: Opening the box + * + * etc... + * + * \section dir_struct Directory Structure + * \code + + * nfapi + * |- common Common functions for the nfapi project + * | |- src + * | |- public-inc + * |- nfapi The NFAPI lib + * | |- inc + * | |- src + * | |- public-inc Public interface for the nfapi library + * | |- tests Unit test for the nfapi lib + * |- pnf The PNF lib + * | |- inc + * | |- src + * | |- public-inc Public interface for the pnf library + * | |- tests Unit test for the pnf lib + * |- vnf The VNF lib + * | |- inc + * | |- src + * | |- public-inc Public interface for the vnf library + * | |- tests Unit test for the vnf lib + * |- sim_common Common functions for the nfapi simulators + * | |- inc + * | |- src + * |- pnf_sim The PNF simulator + * | |- inc + * | |- src + * |- vnf_sim The VNF simulator + * | |- inc + * | |- src + * |- integration_tests Integration tests that run both VNF & PNF simulators + * | |- inc + * | |- src + * |- docs Documentation + * |- xml Xml configuration for the simulator + + * \endcode + * \section building Building + * To build the nfapi project and run the unit test you will need to + * \code + * autoreconf -i + * ./configure + * make + * make check + * \endcode + * The following dependencies will be required + * - Boost. Need to build the simulators + * - STCP. Need to run the simulators + * - + * \section simulators Running the simulators + * Once you have build the nfapi project you can run the PNF/VNF simulators on either the same + * of seperate linux machines. + * + * To run the VNF from the vnf_sim directory. + * \code + * ./vnfsim 4242 ../xml/vnf_A.xml + * [MAC] Rx Data from 8891 + * [MAC] Tx Data to 10.231.16.80.8892 + * Calling nfapi_vnf_start + * 2035.854438: 0x04: 773068608: nfapi_vnf_start() + * 2035.854450: 0x04: 773068608: Starting P5 VNF connection on port 4242 + * 2035.854472: 0x04: 773068608: P5 socket created... 3 + * 2035.854478: 0x03: 773068608: VNF Setting the SCTP_INITMSG + * 2035.854481: 0x04: 773068608: IPV4 binding to port 4242 + * 2035.854485: 0x04: 773068608: bind succeeded..3. + * 2035.854497: 0x04: 773068608: listen succeeded... + * \endcode + * + * + * To run the PNF from the pnf_sim directory + * \code + * ./pnfsim 127.0.01 4242 ../xml/pnf_phy_1_A.xml + * nfapi_pnf_start + * Starting P5 PNF connection to VNF at 127.0.0.1:4242 + * Host address info 0 Family:IPV4 Address:127.0.0.1 + * PNF Setting the SCTP_INITMSG + * P5 socket created... + * Socket CONNECTED + * PNF_PARAM.request received + * [PNF_SIM] pnf param request + * PNF_CONFIG.request received + * [PNF_SIM] pnf config request + * .... and so on + * \endcode + * + * You can Ctrl-C to exit the simulators. + * + + */ + +/*! \page nfapi_call_flow NFAPI Call Flow + * + * \section seq_diag Sequence diagram + * + * The follow sequence digram show how the nFAPI api will be used to bring up + * the PNF and then the PNF PHY and initiate subframe message exchange + * The names of the CLIENT callbacks are placeholders for the functions that + * the CLIENT will provide. + * + * \msc + * + * width="1750"; + * FAPI, PNF_P7_CLIENT, PNF_P7_LIB, PNF_P5_CLIENT, PNF_P5_LIB, VNF_P5_LIB, VNF_P5_CLIENT, VNF_P7_LIB, VNF_P7_CLIENT, MAC; + * VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_config_create", URL="\ref nfapi_vnf_config_create"]; + * VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_start", URL="\ref nfapi_vnf_start"]; + * VNF_P5_LIB note VNF_P5_LIB [label="Listening for PNF connection"]; + * PNF_P5_CLIENT note PNF_P5_CLIENT [label="P9 has provided the address of the VNF"]; + * PNF_P5_CLIENT=>PNF_P5_LIB [label="nfapi_pnf_config_create", URL="\ref nfapi_pnf_config_create"]; + * PNF_P5_CLIENT=>PNF_P5_LIB [label="nfapi_pnf_start", URL="\ref nfapi_pnf_start"]; + * PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF IDLE"]; + * PNF_P5_LIB->VNF_P5_LIB [label=""]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_connection_indication", URL="\ref nfapi_vnf_config::pnf_connection_indication"]; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_param_req", URL="\ref nfapi_vnf_pnf_param_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="PNF_PARAM.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_param_request", URL="\ref nfapi_pnf_config::pnf_param_req"]; + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_param_response", URL="\ref nfapi_pnf_pnf_param_resp"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="PNF_PARAM.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_param_response", URL="\ref nfapi_vnf_config::pnf_param_resp"]; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_config_req", URL="\ref nfapi_vnf_pnf_config_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="PNF_CONFIG.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_config_request", URL="\ref nfapi_pnf_config::pnf_config_req"]; + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_config_response", URL="\ref nfapi_pnf_pnf_config_resp"]; + * PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF CONFIGURED"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="PNF_CONFIG.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_config_response", URL="\ref nfapi_vnf_config::pnf_config_resp"]; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_start_req", URL="\ref nfapi_vnf_pnf_start_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="PNF_START.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_start_request", URL="\ref nfapi_pnf_config::pnf_start_req"]; + * PNF_P5_CLIENT=>FAPI [label=""]; + * FAPI note FAPI [label="FAPI STATE : IDLE"]; + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_start_response", URL="\ref nfapi_pnf_pnf_start_resp"]; + * PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF RUNNING"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="PNF_START.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_start_response", URL="\ref nfapi_vnf_config::pnf_param_resp"]; + * + * --- [ label="If vnf p7 instance not already running"]; + * VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_allocate_phy", URL="\ref nfapi_vnf_allocate_phy"]; + * VNF_P5_CLIENT=>VNF_P7_CLIENT [label=""]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_config_create", URL="\ref nfapi_vnf_p7_config_create"]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_start", URL="\ref nfapi_vnf_p7_start"]; + * ---; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_param_request", URL="\ref nfapi_vnf_param_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="PARAM.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="param_request", URL="\ref nfapi_pnf_config::param_req"]; + * PNF_P5_CLIENT=>FAPI [label="fapi_param_request"]; + * PNF_P5_CLIENT<=FAPI [label="fapi_param_response"]; + * PNF_P5_CLIENT=>PNF_P7_CLIENT [label=""]; + * PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_create", URL="\ref nfapi_pnf_p7_config_create"]; + * PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_start", URL="\ref nfapi_pnf_p7_start"]; + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_param_response", URL="\ref nfapi_pnf_param_resp"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="PARAM.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="param_response", URL="\ref nfapi_vnf_config::param_resp"]; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_config_request", URL="\ref nfapi_vnf_config_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="CONFIG.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="config_request", URL="\ref nfapi_pnf_config::config_req"]; + * PNF_P5_CLIENT=>FAPI [label="fapi_config_request"]; + * FAPI note FAPI [label="FAPI STATE : CONFIGURED"]; + * PNF_P5_CLIENT<=FAPI [label="fapi_config_response"]; + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_config_response", URL="\ref nfapi_pnf_param_resp"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="CONFIG.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="config_response", URL="\ref nfapi_vnf_config::config_resp"]; + * + * VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_start_request", URL="\ref nfapi_vnf_start_req"]; + * VNF_P5_LIB->PNF_P5_LIB [label="START.request"]; + * PNF_P5_LIB=>PNF_P5_CLIENT [label="start_request", URL="\ref nfapi_pnf_config::start_req"]; + * PNF_P5_CLIENT=>FAPI [label="fapi_start_request"]; + * FAPI note FAPI [label="FAPI STATE : RUNNING"]; + * FAPI note FAPI [label="FAPI will start sending subframe indications"]; + * + * --- [ label="For each 'phy' subframe"]; + * FAPI=>PNF_P7_CLIENT [label="fapi_subframe_indication"]; + * PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_subframe_ind", URL="\ref nfapi_pnf_p7_subframe_ind"]; + * ---; + * PNF_P7_CLIENT=>PNF_P5_CLIENT [label=""]; + * + * PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_start_response", URL="\ref nfapi_pnf_start_resp"]; + * VNF_P5_LIB<-PNF_P5_LIB [label="START.response"]; + * VNF_P5_LIB=>VNF_P5_CLIENT [label="start_response", URL="\ref nfapi_vnf_config::start_resp"]; + * VNF_P5_CLIENT=>VNF_P7_CLIENT [label=""]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_add_pnf", URL="\ref nfapi_vnf_p7_add_pnf"]; + * + * VNF_P7_LIB->PNF_P7_LIB [label="DL_NODE_SYNC"]; + * VNF_P7_LIB<-PNF_P7_LIB [label="UL_NODE_SYNC"]; + * VNF_P7_LIB<-PNF_P7_LIB [label="TIMING_INFO"]; + * VNF_P7_LIB note VNF_P7_LIB [label="When sync is achieved"]; + * + * VNF_P7_LIB=>VNF_P7_CLIENT [label="sync_indication", URL="\ref nfapi_vnf_p7_config::sync_indication"]; + * + * --- [ label="For each 'vnf phy' subframe"]; + * VNF_P7_LIB=>VNF_P7_CLIENT [label="subframe_indication(tti=x)", URL="\ref nfapi_vnf_p7_config::subframe_indication"]; + * VNF_P7_CLIENT=>MAC [label="subframe_indication"]; + * VNF_P7_CLIENT<=MAC [label="dl_config_req"]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_dl_config_req", URL="\ref nfapi_vnf_p7_dl_config_req"]; + * VNF_P7_LIB->PNF_P7_LIB [label="DL_CONFIG.request"]; + * PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"]; + * VNF_P7_CLIENT<=MAC [label="ul_config_req"]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_ul_config_req", URL="\ref nfapi_vnf_p7_ul_config_req"]; + * VNF_P7_LIB->PNF_P7_LIB [label="UL_CONFIG.request"]; + * PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"]; + * VNF_P7_CLIENT<=MAC [label="hi_dci0_req"]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_hi_dci0_req", URL="\ref nfapi_vnf_p7_hi_dci0_req"]; + * VNF_P7_LIB->PNF_P7_LIB [label="HI_DCI0.request"]; + * PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"]; + * VNF_P7_CLIENT<=MAC [label="tx_req"]; + * VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_tx_req", URL="\ref nfapi_vnf_p7_tx_req"]; + * VNF_P7_LIB->PNF_P7_LIB [label="TX.request"]; + * PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"]; + * ---; + * + * + * --- [ label="For each 'phy' subframe"]; + * + * FAPI=>PNF_P7_CLIENT [label="harq_indication"]; + * PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_harq_ind", URL="\ref nfapi_pnf_p7_harq_ind"]; + * PNF_P7_LIB->VNF_P7_LIB [label="HARQ.ind"]; + * VNF_P7_LIB=>VNF_P7_CLIENT [label="harq_ind", URL="\ref nfapi_vnf_p7_config::harq_indication"]; + * VNF_P7_CLIENT=>MAC [label="harq_ind"]; + * + * FAPI=>PNF_P7_CLIENT [label="subframe_indication(tti=x)"]; + * PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_subframe_ind", URL="\ref nfapi_pnf_p7_subframe_ind"]; + * PNF_P7_LIB note PNF_P7_LIB [label="Send data from subframe buffer for tti x"]; + * PNF_P7_LIB=>PNF_P7_CLIENT [label="dl_config_req", URL="\ref nfapi_pnf_p7_config::dl_config_req"]; + * PNF_P7_CLIENT=>FAPI [label="dl_config_req"]; + * PNF_P7_LIB=>PNF_P7_CLIENT [label="ul_config_req", URL="\ref nfapi_pnf_p7_config::ul_config_req"]; + * PNF_P7_CLIENT=>FAPI [label="ul_config_req"]; + * PNF_P7_LIB=>PNF_P7_CLIENT [label="hi_dci0_req", URL="\ref nfapi_pnf_p7_config::hi_dci0_req"]; + * PNF_P7_CLIENT=>FAPI [label="hi_dci0_req"]; + * PNF_P7_LIB=>PNF_P7_CLIENT [label="tx_req", URL="\ref nfapi_pnf_p7_config::tx_req"]; + * PNF_P7_CLIENT=>FAPI [label="tx_req"]; + * ---; + * + * \endmsc + * + * \section seq_diag_bca BCA + * + * -# The VNF_P5_CLIENT is created. If it left to the VRAN partner to define how that is done. The client is responsiable to creation of the thread with the correct priorities within the wider system. + * -# The VNF_P5_CLIENT creates and initializes the VNF_P5_LIB (nfapi_vnf_config_create & nfapi_vnf_start) providing the address that it should listen on for incoming SCTP connections. It is expected that this would be provided by some VNF management system. The VNF_P5_CLIENT also provides information on the callbacks that the VNF_P5_LIB will use to inform the VNF_P5_CLIENT of the received messages + * \code + * nfapi_vnf_config_t* vnf_config = nfapi_vnf_config_create(); + * vnf_config->pnf_connection_indication = &pnf_connection_indication; + * vnf_config->pnf_param_resp = &pnf_param_resp; + * nfapi_vnf_start(vnf_config); + * \endcode + * -# It is FFS how the address information of the VNF P5 is passed to the PNF over P9, but assuming that has been done + * -# The PNF_P5_CLIENT is created and then creates the PNF_P5_LIB (nfapi_pnf_init & nfapi_pnf_start) passing the address of the VNF to connect to. The PNF_P5_CLIENT also provides information on the callbacks that the PNF_P5_LIB will use to inform the PNF_P5_CLIENT of the received messages + * \code + * nfapi_pnf_config_t* pnf_config = nfapi_pnf_config_create(); + * pnf_config->pnf_param_req = &pnf_param_req; + * nfapi_pnf_start(pnf_config); + * \endcode + * -# The PNF_P5_LIB attempts to establish connection to the VNF_P5 endpoint + * -# The VNF_P5_LIB receives the STCP connection request and indicates this to the VNF_P5_CLIENT (pnf_connection_indication). The VNF_P5_CLIENT can decide to accept or reject the connection. + * \code + * int pnf_connection_indication(nfapi_vnf_config_t* config, int p5_idx) { + * // send the PNF_PARAM.request + * nfapi_pnf_param_request_t req; + * memset(&req, 0, sizeof(req)); + * req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + * nfapi_vnf_pnf_param_req(config, p5_idx, req); + * return 0; + * } + * \endcode + + * -# The VNF and PNF then proceed to exchange the NFAPI PNF messages (PNF_PARAM, PNF_CONFIG and PNF_START). At each stage the LIB’s invoke callbacks on the CLIENT’s for them to handle message the return the appropriate response. + * -# Finally the VNF will send the PNF_START.req which will invoke the PNF_P5_CLIENT nfapi_pnf_start_request callback. This is the point at which it is expect that the PNF_CLIENT will create the FAPI module. The PNF_P5_CLIENT will need to perform the translation between NFAPI structures and vendor specific FAPI structures for messages sent between the PNF_P5_LIB and the FAPI interface. + * -# The PNF_START.response will sent back to the VNF and at this point the VNF_P5_CLIENT will need to decide which VNF_P7 instance will handle the P7 connection. i.e. it needs to determine the IP address and port number of the P7 VNF instance. + * -# A new VNF_P7_CLIENT & VNF_P7_LIB should be configured and started if necessary. + * -# The VNF_P5 will then send the PARAM.request to the PNF_P5 which will forward it onto the FAPI interface. This PARAM.request includes the VNF_P7 address. The PNF_P7_CLIENT must decide on the PNF P7 address. This information is used to create and initialize the PNF_P7_LIB. The PNF_P7 address is then returned by the PNF_P5 to the VNF_P5 in the PARAM.response. + * -# The VNF_P5 will then exchange with the PNF_P5 the CONFIG.request/response which will be used to configure the PNF FAPI instance. + * -# The VNF_P5 will then decide to start the PNF_P7 by sending the START.request. + * -# The PNF_P5_CLIENT need to send the start request to the FAPI instance. The response which is the start of subframe indications from the FAPI. In receipt of the first subframe indication the PNF_P5_CLIENT will send the START.response to the VNF_P5 via the PNF_P5_LIB + * -# The FAPI subframe indications should be forwarded to the PNF_P7_LIB by the PNF_P7_CLIENT. Until the VNF_P7 instance has sent the subframe configuration messages (dl_config, ul_config, etc) the PNF_P7_LIB will send ‘dummy’ subframe configuration messages. The contents of which are configurable by the PNF_P7_CLIENT. + * -# When the VNF_P5_CLIENT receives the START.response it will need to ‘communicate’ with the VNF_P7_CLIENT to inform it that the PNF_P7 instance has started. The VNF_P7_CLIENT will call the nfapi_vnf_P7_add_pnf function passing the address details of the PNF_P7 instance. + * -# The VNF_P7_LIB will then start the sync procedure to establish sub frame synchronization between the PNF_P7 and VNF_P7 instances. This involves sending the DL_NODE_SYNC and UL_NODE_SYNC to determine network latency and PNF processing latency to be able to request MAC generate sub frames in advance on when they are required by the FAPI interface. + * -# When sync is achieved the VNF_P7_LIB will send the nfapi_sync_indication to the VNF_P7_CLIENT. + * -# The VNF_P7_LIB will then start issuing sub frame indications to the VNF_P7_CLIENT. The logical intent is that they indications are sent every millisecond. However due to the scheduling jitter that may be seen by the VNF these subframe indications may be less than or more than 1ms apart. How this is handled is one of the critical functions of the VNF_P7_LIB and may require specialization or requirements on the VNF environment i.e. CPU pinning. + * -# The VNF_P7_LIB will send the subframe_indication to the VNF_P7_CLIENT for ‘x’ subframe’s inadvance of the current TTI at the PNF. The delta ‘x’ will be determined by the sync procedure and how far in advance the FAPI needs to receive messages before RF transmission. + * -# The VNF_P7_CLIENT is then responsible for communicating to the MAC layer to prepare the dl_config_request, ul_config_request, hi_dci0_request, tx_req in a timely manner and sending them to the VNF_P7_LIB + * -# The VNF_P7_LIB will send them to the VNF_P7_LIB. + * -# The PNF_P7_LIB will store these messages in a subframe buffer or playout buffer in advance of when they are required by FAPI. + * -# The PNF_P7_LIB will monitor to see if these messages arrive too late and if they do trigger a TIMING_INFO response to the VNF_P7_LIB to reassess if the sync is still valid. + * -# As some time in the future the FAPI will send a subframe indication for the TTI that the VNF_P7_LIB had previously requested. + * -# The PNF_P7_LIB will then use the messages in the subframe buffer and send them too the FAPI interface for transmission. The PNF_P7_CLIENT will need to perform the translation between NFAPI structure and vendor specific FAPI structures + * -# This subframe exchange will continue and allow high layer MAC and RRC function to bringup the cell and connect UE’s + + */ diff --git a/nfapi/open-nFAPI/integration_tests/Makefile.am b/nfapi/open-nFAPI/integration_tests/Makefile.am new file mode 100644 index 0000000000..2413590182 --- /dev/null +++ b/nfapi/open-nFAPI/integration_tests/Makefile.am @@ -0,0 +1,29 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +#vnf unit test +AM_CPPFLAGS = -I../nfapi/inc -I../nfapi/public_inc -I../common/public_inc -I../vnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror + +export LD_LIBRARY_PATH=/opt/gcc-4.7.3/lib +check_PROGRAMS= nfapi_integration_tests +nfapi_integration_tests_SOURCES = main.cpp ../common/src/debug.c +nfapi_integration_tests_LDADD= -L$(libdir) -lpthread -lrt -lcunit + + + +LOG_DRIVER = $(top_srcdir)/tap-driver.sh +TESTS=nfapi_integration_tests +EXTRA_DIST=$(TESTS) diff --git a/nfapi/open-nFAPI/integration_tests/main.cpp b/nfapi/open-nFAPI/integration_tests/main.cpp new file mode 100644 index 0000000000..83c48afec3 --- /dev/null +++ b/nfapi/open-nFAPI/integration_tests/main.cpp @@ -0,0 +1,269 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "CUnit.h" +#include "Basic.h" +#include "Automated.h" + +#include +#include +#include +#include + +int start_vnf_proc(int port) +{ + char port_str[10]; + sprintf(port_str, "%d", port); + + const char *argv[] = {"vnfsim", port_str, "../xml/vnf_A.xml", NULL}; + int pid = fork(); + + if(pid == 0) + { + int result = execv("../vnf_sim/vnfsim", (char* const*)argv); //, env_args); + if(result == -1) + { + printf("Failed to exec vnf process %d\n", errno); + } + exit(0); + } + else + { + return pid; + } +} + +int start_pnf_proc(const char* addr, int port, const char* file) +{ + char port_str[10]; + sprintf(port_str, "%d", port); + + char filename[256]; + sprintf(filename, "../xml/%s", file); + + const char * argv[] = {"pnfsim", addr, port_str, filename, NULL}; + int pid = fork(); + + if(pid == 0) + { + int result = execv("../pnf_sim/pnfsim", (char* const*)argv); //, env_args); + if(result == -1) + { + printf("Failed to exec pnf process %d\n", errno); + } + exit(0); + } + else + { + return pid; + } +} + +int kill_proc(int pid) +{ + kill(pid, SIGKILL); + + int status; + int waitpid_result = waitpid(pid, &status, 0); + + return waitpid_result; +} + + +void test_1() +{ + + int pnf_port = 5655; + const char* pnf_addr = "localhost"; + + printf("**** starting vnf *****\n"); + int vnf_pid = start_vnf_proc(pnf_port); + + printf("**** starting pnf *****\n"); + int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml"); + + + sleep(10); + + printf ("*** Terminating ****\n"); + kill_proc(vnf_pid); + kill_proc(pnf1_pid); +} +void test_1a() +{ + + int pnf_port = 5655; + const char* pnf_addr = "localhost"; + + printf("**** starting vnf *****\n"); + int vnf_pid = start_vnf_proc(pnf_port); + + printf("**** starting pnf *****\n"); + int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_2_A.xml"); + + + sleep(10); + + printf ("*** Terminating ****\n"); + kill_proc(vnf_pid); + kill_proc(pnf1_pid); +} + + +void test_2() +{ + int pnf_port = 5655; + const char* pnf_addr = "127.0.0.1"; + + int vnf_pid = start_vnf_proc(pnf_port); + sleep(2); + + int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml"); + int pnf2_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml"); + + sleep(2); + + kill_proc(pnf2_pid); + kill_proc(pnf1_pid); + kill_proc(vnf_pid); +} + +void test_32() +{ + int pnf_count = 32; + int pnf_pid[pnf_count]; + + int pnf_port = 5655; + const char* pnf_addr = "127.0.0.1"; + + int vnf_pid = start_vnf_proc(pnf_port); + sleep(2); + + for(int i = 0; i < pnf_count; ++i) + { + pnf_pid[i] = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml"); + } + + sleep(5); + + printf ("*** Terminating pnfs\n"); + + for(int i = 0; i < pnf_count; ++i) + { + kill_proc(pnf_pid[i]); + } + printf ("*** Terminating vnf\n"); + kill_proc(vnf_pid); +} + + +int init_suite() +{ + return 0; +} + +int clean_suite() +{ + return 0; +} + +int main ( void ) +{ + CU_pSuite pSuite = NULL; + + /* initialize the CUnit test registry */ + if ( CUE_SUCCESS != CU_initialize_registry() ) + return CU_get_error(); + + /* add a suite to the registry */ + pSuite = CU_add_suite( "integration_test_suite", init_suite, clean_suite ); + if ( NULL == pSuite ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + //(NULL == CU_add_test(pSuite, "vnf_test_start_connect_2", vnf_test_start_connect_2)) + /* add the tests to the suite */ + if ( (NULL == CU_add_test(pSuite, "test_1a", test_1a)) +// (NULL == CU_add_test(pSuite, "test_2", test_2)) || +// (NULL == CU_add_test(pSuite, "test_32", test_32)) + ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + // Run all tests using the basic interface + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_set_output_filename("vnf_unit_test_results.xml"); + CU_basic_run_tests(); + + CU_pSuite s = CU_get_registry()->pSuite; + int count = 0; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + count++; + t = t->pNext; + } + s = s->pNext; + } + + printf("%d..%d\n", 1, count); + + + + s = CU_get_registry()->pSuite; + count = 1; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + int pass = 1; + CU_FailureRecord* failures = CU_get_failure_list(); + while(failures) + { + if(strcmp(failures->pSuite->pName, s->pName) == 0 && + strcmp(failures->pTest->pName, t->pName) == 0) + { + pass = 0; + failures = 0; + } + else + { + failures = failures->pNext; + } + } + + if(pass) + printf("ok %d - %s:%s\n", count, s->pName, t->pName); + else + printf("not ok %d - %s:%s\n", count, s->pName, t->pName); + + count++; + t = t->pNext; + } + s = s->pNext; + } + + CU_cleanup_registry(); + return CU_get_error(); + +} diff --git a/nfapi/open-nFAPI/nfapi/Makefile.am b/nfapi/open-nFAPI/nfapi/Makefile.am new file mode 100644 index 0000000000..853ee9ff80 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/Makefile.am @@ -0,0 +1,30 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AUTOMAKE_OPTIONS=subdir-objects +AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(BOOST_CPPFLAGS) -Wall -Werror -g + +noinst_LIBRARIES = libnfapi.a + +libnfapi_a_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c +libnfapi_a_CFLAGS =$(AM_CFLAGS) + +lib_LTLIBRARIES = libnfapi.la +libnfapi_la_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c + + +LDADD= ../pnf/src/libnfapi_pnf.a ../vnf/src/libnfapi_vnf.a ../common/bin/libnfapi_common.a + diff --git a/nfapi/open-nFAPI/nfapi/inc/nfapi.h b/nfapi/open-nFAPI/nfapi/inc/nfapi.h new file mode 100644 index 0000000000..65ad4dd160 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/inc/nfapi.h @@ -0,0 +1,91 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _NFAPI_H_ +#define _NFAPI_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +// todo : move to public_inc so can be used by vendor extensions + +#define MAX_BAD_TAG 3 + +uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end); +uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end); +uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end); +uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end); +uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end); +uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end); + +uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end); +uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end); +uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end); +uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end); +uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end); +uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end); + + +uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end); +uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end); +uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end); + +uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); +uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); +uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end); + +typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end); +uint8_t packarray(void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t **ppWritePackedMsg, uint8_t *end, pack_array_elem_fn fn); + +typedef uint8_t (*unpack_array_elem_fn)(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end); +uint8_t unpackarray(uint8_t **ppReadPackedMsg, void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn); + +uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end); +uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end); + +typedef uint8_t (*pack_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end); +uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn); + +uint32_t pack_vendor_extension_tlv(nfapi_tl_t* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config); +int unpack_vendor_extension(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve_tlv); + +typedef uint8_t (*unpack_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end); +typedef struct +{ + uint16_t tag; + void* tlv; + unpack_tlv_fn unpack_func; +} unpack_tlv_t; + +int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* packedMsgEnd, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve); + +uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config); +typedef uint8_t (*unpack_p7_tlv_fn)(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t*); +typedef struct +{ + uint16_t tag; + void* tlv; + unpack_p7_tlv_fn unpack_func; +} unpack_p7_tlv_t; +int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* packedMsgEnd, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve); + +#if defined(__cplusplus) +} +#endif + +#endif /* _NFAPI_H_ */ diff --git a/nfapi/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h similarity index 99% rename from nfapi/nfapi_interface.h rename to nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 9bb3dbe424..d5b1ce6af6 100644 --- a/nfapi/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -34,7 +34,7 @@ #define NFAPI_MAX_NUM_ANTENNAS 8 #define NFAPI_MAX_NUM_SUBBANDS 13 #define NFAPI_MAX_BF_VECTORS 8 -#define NFAPI_MAX_CC 2 +#define NFAPI_MAX_CC 1 #define NFAPI_MAX_NUM_PHYSICAL_ANTENNAS 8 #define NFAPI_MAX_RSSI 8 #define NFAPI_MAX_PSC_LIST 32 @@ -1689,7 +1689,7 @@ typedef struct { uint16_t number_pdu; uint8_t number_pdsch_rnti; uint16_t transmission_power_pcfich; - nfapi_dl_config_request_pdu_t* dl_config_pdu_list; + nfapi_dl_config_request_pdu_t* dl_config_pdu_list; } nfapi_dl_config_request_body_t; #define NFAPI_DL_CONFIG_REQUEST_BODY_TAG 0x2000 @@ -1962,7 +1962,7 @@ typedef struct { } nfapi_ul_config_harq_information_rel8_fdd_t; #define NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG 0x2019 -typedef struct { +typedef struct { nfapi_tl_t tl; uint8_t harq_size; uint8_t ack_nack_mode; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c new file mode 100644 index 0000000000..3f017bc9a4 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c @@ -0,0 +1,860 @@ +/* + * Copyright (c) 2001-2016, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the Cisco Systems, Inc. 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 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 HOLDERS 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// Fundamental routines + +uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + + if((end - pOut) >= 1) + { + pOut[0] = in; + + (*out)+=1; + + return 1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } + +} + +uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + + if((end - pOut) >= 1) + { + pOut[0] = in; + + (*out)+=1; + + return 1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + + if((end - pOut) >= 2) + { + pOut[0] = (in & 0xFF00) >> 8; + pOut[1] = (in & 0xFF); + + (*out)+=2; + + return 2; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + + if((end - pOut) >= 2) + { + pOut[0] = (in & 0xFF00) >> 8; + pOut[1] = (in & 0xFF); + + (*out)+=2; + + return 2; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + if((end - pOut) >= 4) + { + pOut[0] = (in & 0xFF000000) >> 24; + pOut[1] = (in & 0xFF0000) >> 16; + pOut[2] = (in & 0xFF00) >> 8; + pOut[3] = (in & 0xFF); + + (*out)+=4; + + return 4; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) +{ + uint8_t *pOut = *out; + + if((end - pOut) >= 4) + { + pOut[0] = (in & 0xFF000000) >> 24; + pOut[1] = (in & 0xFF0000) >> 16; + pOut[2] = (in & 0xFF00) >> 8; + pOut[3] = (in & 0xFF); + + (*out)+=4; + + return 4; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >= 1 ) + { + *out = *pIn; + + (*in)+=1; + + return 1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >= 1 ) + { + *out = *pIn; + + (*in)+=1; + + return 1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >=2 ) + { + *out = ((pIn[0]) << 8) | pIn[1]; + (*in)+=2; + + return 2; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >=2 ) + { + *out = ((pIn[0]) << 8) | pIn[1]; + + (*in)+=2; + + return 2; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >=4 ) + { + *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; + + (*in)+=4; + + return 4; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + + if((end - pIn) >=4 ) + { + *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; + + (*in)+=4; + + return 4; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +/* +inline void pusharray16(uint8_t **, uint16_t, uint32_t len) +{ +} +*/ + +uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint16_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!pull16(in, &out[idx], end)) + return 0; + } + + return sizeof(uint16_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint16_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!pulls16(in, &out[idx], end)) + return 0; + } + + return sizeof(uint16_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint16_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + if(!push16(in[idx], out, end)) + return 0; + } + return sizeof(uint16_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint16_t) * len) + { + uint32_t idx; + for(idx = 0; idx < len; ++idx) + { + pushs16(in[idx], out, end); + } + return sizeof(uint16_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - out) >= sizeof(uint8_t) * len) + { + memcpy(out, (*in), len); + (*in)+=len; + + return sizeof(uint8_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) +{ + if(len == 0) + return 1; + + if(len > max_len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint8_t) * len) + { + memcpy((*out), in, len); + (*out)+=len; + + return sizeof(uint8_t) * len; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t packarray(void* array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) +{ + if(count > max_count) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); + return 0; + } + + uint16_t i = 0; + for(i = 0; i < count; ++i) + { + if((fn)(array, ppwritepackedmsg, end) == 0) + return 0; + + array += array_element_size; + } + + return 1; +} + +uint8_t unpackarray(uint8_t **ppReadPackedMsg, void* array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) +{ + if(count > max_count) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); + return 0; + } + + uint16_t i = 0; + for(i = 0; i < count; ++i) + { + if((fn)(array, ppReadPackedMsg, end) == 0) + return 0; + + array += array_element_size; + } + + return 1; +} + + +uint32_t pack_vendor_extension_tlv(nfapi_tl_t* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + if(ve != 0 && config != 0) + { + if(config->pack_vendor_extension_tlv) + { + + uint8_t* pStartOfTlv = *ppWritePackedMsg; + if(pack_tl(ve, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t* pStartOfValue = *ppWritePackedMsg; + if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) + return 0; + + ve->length = (*ppWritePackedMsg) - pStartOfValue; + + pack_tl(ve, &pStartOfTlv, end); + + return 1; + + } + } + return 1; +} + +uint32_t unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve_tlv) +{ + if(ve_tlv != 0 && config != 0) + { + if(config->unpack_vendor_extension_tlv) + { + return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void**)ve_tlv, config); + } + } + return 1; +} + +uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end ,nfapi_p7_codec_config_t* config) +{ + if(ve != 0 && config != 0) + { + if(config->pack_vendor_extension_tlv) + { + uint8_t* pStartOfTlv = *ppWritePackedMsg; + if(pack_tl(ve, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t* pStartOfValue = *ppWritePackedMsg; + if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) + return 0; + + ve->length = (*ppWritePackedMsg) - pStartOfValue; + + pack_tl(ve, &pStartOfTlv, end); + + return 1; + + } + } + return 1; +} + +int unpack_p7_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve_tlv) +{ + if(ve_tlv != 0 && config != 0) + { + if(config->unpack_vendor_extension_tlv) + { + return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void**)ve_tlv, config); + } + } + return 1; +} + + +uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return (push16(tl->tag, ppWritePackedMsg, end) && + push16(tl->length, ppWritePackedMsg, end)); +} + +uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) +{ + return (pull16(ppReadPackedMsg, &tl->tag, end) && + pull16(ppReadPackedMsg, &tl->length, end)); +} + +int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config, nfapi_tl_t** ve) +{ + nfapi_tl_t generic_tl; + uint8_t numBadTags = 0; + uint16_t idx = 0; + + while ((uint8_t*)(*ppReadPackedMsg) < end) + { + // unpack the tl and process the values accordingly + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + uint8_t tagMatch = 0; + + uint8_t* pStartOfValue = *ppReadPackedMsg; + + for(idx = 0; idx < size; ++idx) + { + if(unpack_fns[idx].tag == generic_tl.tag) + { + tagMatch = 1; + nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv); + tl->tag = generic_tl.tag; + tl->length = generic_tl.length; + + int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end); + + if(result == 0) + { + return 0; + } + + // check if the length was right; + if(tl->length != (*ppReadPackedMsg - pStartOfValue)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); + } + } + } + + if(tagMatch == 0) + { + + if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && + generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) + { + int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); + if(result == 0) + { + // got tot the end. + return 0; + } + else if(result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return 0; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) + { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } + else + { + // go to the end + return 0; + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return 0; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) + { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } + else + { + // go to the end + return 0; + } + } + + } + } + + return 1; +} +int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config, nfapi_tl_t** ve) +{ + nfapi_tl_t generic_tl; + uint8_t numBadTags = 0; + uint16_t idx = 0; + + while ((uint8_t*)(*ppReadPackedMsg) < end) + { + // unpack the tl and process the values accordingly + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + uint8_t tagMatch = 0; + + uint8_t* pStartOfValue = *ppReadPackedMsg; + + for(idx = 0; idx < size; ++idx) + { + if(unpack_fns[idx].tag == generic_tl.tag) + { + tagMatch = 1; + nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv); + tl->tag = generic_tl.tag; + tl->length = generic_tl.length; + + int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end , config); + + if(result == 0) + { + return 0; + } + + // check if the length was right; + if(tl->length != (*ppReadPackedMsg - pStartOfValue)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); + } + } + } + + if(tagMatch == 0) + { + + if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && + generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) + { + int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); + if(result == 0) + { + // got to end + return 0; + } + else if(result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return -1; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) + { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } + else + { + // got ot the dn + return 0; + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return -1; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) + { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } + else + { + // got ot the dn + return 0; + } + + } + + } + } + + return 1; +} + +// This intermediate function deals with calculating the length of the value +// and writing into the tlv header. +uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) +{ + nfapi_tl_t* tl = (nfapi_tl_t*)tlv; + + // If the tag is defined + if(tl->tag == tag) + { + uint8_t* pStartOfTlv = *ppWritePackedMsg; + + // write a dumy tlv header + if(pack_tl(tl, ppWritePackedMsg, end) == 0) + return 0; + + // Record the start of the value + uint8_t* pStartOfValue = *ppWritePackedMsg; + + // pack the tlv value + if(fn(tlv, ppWritePackedMsg, end) == 0) + return 0; + + // calculate the length of the value and rewrite the tl header + tl->length = (*ppWritePackedMsg) - pStartOfValue; + + // rewrite the header with the correct length + pack_tl(tl, &pStartOfTlv, end); + } + else + { + if(tl->tag != 0) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag); + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag); + } + } + + return 1; +} + +const char* nfapi_error_code_to_str(nfapi_error_code_e value) +{ + switch(value) + { + case NFAPI_MSG_OK: + return "NFAPI_MSG_OK"; + case NFAPI_MSG_INVALID_STATE: + return "NFAPI_MSG_INVALID_STATE"; + case NFAPI_MSG_INVALID_CONFIG: + return "NFAPI_MSG_INVALID_CONFIG"; + case NFAPI_SFN_OUT_OF_SYNC: + return "NFAPI_SFN_OUT_OF_SYNC"; + case NFAPI_MSG_SUBFRAME_ERR: + return "NFAPI_MSG_SUBFRAME_ERR"; + case NFAPI_MSG_BCH_MISSING: + return "NFAPI_MSG_BCH_MISSING"; + case NFAPI_MSG_INVALID_SFN: + return "NFAPI_MSG_INVALID_SFN"; + case NFAPI_MSG_HI_ERR: + return "NFAPI_MSG_HI_ERR"; + case NFAPI_MSG_TX_ERR: + return "NFAPI_MSG_TX_ERR"; + default: + return "UNKNOWN"; + } +} diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c new file mode 100644 index 0000000000..b429e0a6ce --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c @@ -0,0 +1,2085 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include // need for uintptr_t? + +#include +#include +#include +#include +#include + +#include +#include +#include + +static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) +{ + if (msgEnd < msgHead) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd); + return 0; + } + + return (msgEnd - msgHead); +} + +static uint8_t pack_opaque_data_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_opaqaue_data_t* value = (nfapi_opaqaue_data_t*)tlv; + return pusharray8(value->value, NFAPI_MAX_OPAQUE_DATA, value->length, ppWritePackedMsg, end); +} + +static uint8_t unpack_opaque_data_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_opaqaue_data_t* value = (nfapi_opaqaue_data_t*)tlv; + value->length = value->tl.length; + if(value->length <= NFAPI_MAX_OPAQUE_DATA) + { + if(!pullarray8(ppReadPackedMsg, value->value, NFAPI_MAX_OPAQUE_DATA, value->length, end)) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Opaque date to long %d \n", value->length); + return 0; + } + + return 1; + +} + +static uint8_t pack_lte_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_rssi_request_t* value = (nfapi_lte_rssi_request_t*)tlv; + + return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) && + push16(value->measurement_period, ppWritePackedMsg, end) && + push8(value->bandwidth, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_earfcns, ppWritePackedMsg, end) && + pusharray16(value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, ppWritePackedMsg, end)); +} + +static uint8_t pack_utran_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_rssi_request_t* value = (nfapi_utran_rssi_request_t*)tlv; + + return (push8(value->frequency_band_indicator, ppWritePackedMsg, end) && + push16(value->measurement_period, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_uarfcns, ppWritePackedMsg, end) && + pusharray16(value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, ppWritePackedMsg, end)); +} + +static uint8_t pack_geran_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_geran_rssi_request_t* value = (nfapi_geran_rssi_request_t*)tlv; + uint16_t idx = 0; + + if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) && + push16(value->measurement_period, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_arfcns, ppWritePackedMsg, end))) + return 0; + + for(;idx < value->number_of_arfcns; ++idx) + { + if(!(push16(value->arfcn[idx].arfcn, ppWritePackedMsg, end) && + push8(value->arfcn[idx].direction, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +static uint8_t pack_nb_iot_rssi_request_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_rssi_request_t* value = (nfapi_nb_iot_rssi_request_t*)tlv; + uint16_t idx = 0; + + if(!(push8(value->frequency_band_indicator, ppWritePackedMsg, end) && + push16(value->measurement_period, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_earfcns, ppWritePackedMsg, end))) + return 0; + + for(;idx < value->number_of_earfcns; ++idx) + { + if(!(push16(value->earfcn[idx].earfcn, ppWritePackedMsg, end) && + push8(value->earfcn[idx].number_of_ro_dl, ppWritePackedMsg, end))) + return 0; + + uint8_t ro_dl_idx = 0; + for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx) + { + if(!push8(value->earfcn[idx].ro_dl[ro_dl_idx], ppWritePackedMsg, end)) + return 0; + } + } + + return 1; +} + + + +static uint8_t pack_rssi_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t*)msg; + + if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0) + return 0; + + switch(pNfapiMsg->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + if(pack_tlv(NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, ppWritePackedMsg, end, &pack_lte_rssi_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_UTRAN: + if(pack_tlv(NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, ppWritePackedMsg, end, &pack_utran_rssi_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_GERAN: + if(pack_tlv(NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, ppWritePackedMsg, end, &pack_geran_rssi_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_NB_IOT: + if(pack_tlv(NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, ppWritePackedMsg, end, &pack_nb_iot_rssi_request_value) == 0) + return 0; + break; + } + + return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); +} + +static uint8_t pack_rssi_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_rssi_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rssi_indication_body_t* value = (nfapi_rssi_indication_body_t*)tlv; + + return (push16(value->number_of_rssi, ppWritePackedMsg, end) && + pusharrays16(value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, ppWritePackedMsg, end)); +} + +static uint8_t pack_rssi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, ppWritePackedMsg, end, &pack_rssi_indication_body_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + + +static uint8_t pack_lte_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_cell_search_request_t* value = (nfapi_lte_cell_search_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push8(value->measurement_bandwidth, ppWritePackedMsg, end) && + push8(value->exhaustive_search, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_pci, ppWritePackedMsg, end) && + pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end)); +} + +static uint8_t pack_utran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_cell_search_request_t* value = (nfapi_utran_cell_search_request_t*)msg; + + return (push16(value->uarfcn, ppWritePackedMsg, end) && + push8(value->exhaustive_search, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_psc, ppWritePackedMsg, end) && + pusharray16(value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, ppWritePackedMsg, end)); +} + +static uint8_t pack_geran_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_geran_cell_search_request_t* value = (nfapi_geran_cell_search_request_t*)msg; + + return (push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_arfcn, ppWritePackedMsg, end) && + pusharray16(value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, ppWritePackedMsg, end)); +} + +static uint8_t pack_nb_iot_cell_search_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_cell_search_request_t* value = (nfapi_nb_iot_cell_search_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push8(value->ro_dl, ppWritePackedMsg, end) && + push8(value->exhaustive_search, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end) && + push8(value->number_of_pci, ppWritePackedMsg, end) && + pusharray16(value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, ppWritePackedMsg, end)); +} + + +static uint8_t pack_cell_search_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t*)msg; + + if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0) + return 0; + + switch(pNfapiMsg->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + if(pack_tlv(NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, ppWritePackedMsg, end, &pack_lte_cell_search_request_value) == 0) + return 0; + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + if(pack_tlv(NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, ppWritePackedMsg, end, &pack_utran_cell_search_request_value) == 0) + return 0; + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + if(pack_tlv(NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, ppWritePackedMsg, end, &pack_geran_cell_search_request_value) == 0) + return 0; + } + break; + case NFAPI_RAT_TYPE_NB_IOT: + { + if(pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, ppWritePackedMsg, end, &pack_nb_iot_cell_search_request_value) == 0) + return 0; + } + break; + }; + + return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_cell_search_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lte_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_cell_search_indication_t* value = (nfapi_lte_cell_search_indication_t*)msg; + uint16_t idx = 0; + + if(push16(value->number_of_lte_cells_found, ppWritePackedMsg, end) == 0) + return 0; + + for(idx = 0; idx < value->number_of_lte_cells_found; ++idx) + { + if(!(push16(value->lte_found_cells[idx].pci, ppWritePackedMsg, end) && + push8(value->lte_found_cells[idx].rsrp, ppWritePackedMsg, end) && + push8(value->lte_found_cells[idx].rsrq, ppWritePackedMsg, end) && + pushs16(value->lte_found_cells[idx].frequency_offset, ppWritePackedMsg, end))) + return 0; + } + return 1; +} + +static uint8_t pack_utran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_cell_search_indication_t* value = (nfapi_utran_cell_search_indication_t*)msg; + uint16_t idx = 0; + + if(push16(value->number_of_utran_cells_found, ppWritePackedMsg, end) == 0) + return 0; + + for(idx = 0; idx < value->number_of_utran_cells_found; ++idx) + { + if(!(push16(value->utran_found_cells[idx].psc, ppWritePackedMsg, end) && + push8(value->utran_found_cells[idx].rscp, ppWritePackedMsg, end) && + push8(value->utran_found_cells[idx].ecno, ppWritePackedMsg, end) && + pushs16(value->utran_found_cells[idx].frequency_offset, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +static uint8_t pack_geran_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_geran_cell_search_indication_t* value = (nfapi_geran_cell_search_indication_t*)msg; + uint16_t idx = 0; + + if(push16(value->number_of_gsm_cells_found, ppWritePackedMsg, end) == 0) + return 0; + + for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx) + { + if(!(push16(value->gsm_found_cells[idx].arfcn, ppWritePackedMsg, end) && + push8(value->gsm_found_cells[idx].bsic, ppWritePackedMsg, end) && + push8(value->gsm_found_cells[idx].rxlev, ppWritePackedMsg, end) && + push8(value->gsm_found_cells[idx].rxqual, ppWritePackedMsg, end) && + pushs16(value->gsm_found_cells[idx].frequency_offset, ppWritePackedMsg, end) && + push32(value->gsm_found_cells[idx].sfn_offset, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +static uint8_t pack_nb_iot_cell_search_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_cell_search_indication_t* value = (nfapi_nb_iot_cell_search_indication_t*)msg; + uint16_t idx = 0; + + if(push16(value->number_of_nb_iot_cells_found, ppWritePackedMsg, end) == 0) + return 0; + + for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx) + { + if(!(push16(value->nb_iot_found_cells[idx].pci, ppWritePackedMsg, end) && + push8(value->nb_iot_found_cells[idx].rsrp, ppWritePackedMsg, end) && + push8(value->nb_iot_found_cells[idx].rsrq, ppWritePackedMsg, end) && + pushs16(value->nb_iot_found_cells[idx].frequency_offset, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} +static uint8_t pack_cell_search_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, ppWritePackedMsg, end, &pack_lte_cell_search_indication_value) && + pack_tlv(NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, ppWritePackedMsg, end, &pack_utran_cell_search_indication_value) && + pack_tlv(NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, ppWritePackedMsg, end, &pack_geran_cell_search_indication_value) && + pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) && + pack_tlv(NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, ppWritePackedMsg, end, &pack_nb_iot_cell_search_indication_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_lte_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_broadcast_detect_request_t* value = (nfapi_lte_broadcast_detect_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + +static uint8_t pack_utran_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_broadcast_detect_request_t* value = (nfapi_utran_broadcast_detect_request_t*)msg; + + return (push16(value->uarfcn, ppWritePackedMsg, end) && + push16(value->psc, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + +static uint8_t pack_nb_iot_broadcast_detect_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_broadcast_detect_request_t* value = (nfapi_nb_iot_broadcast_detect_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push8(value->ro_dl, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + +static uint8_t pack_broadcast_detect_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t * end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t*)msg; + + if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0) + return 0; + + switch(pNfapiMsg->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + if(pack_tlv(NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, ppWritePackedMsg, end ,&pack_lte_broadcast_detect_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_UTRAN: + if(pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, ppWritePackedMsg, end, &pack_utran_broadcast_detect_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_NB_IOT: + if(pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_request_value) == 0) + return 0; + break; + + } + + return (pack_tlv(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, ppWritePackedMsg, end, &pack_opaque_data_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_broadcast_detect_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lte_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_broadcast_detect_indication_t* value = (nfapi_lte_broadcast_detect_indication_t*)msg; + + return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) && + push16(value->mib_length, ppWritePackedMsg, end) && + pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) && + push32(value->sfn_offset, ppWritePackedMsg, end)); +} + +static uint8_t pack_utran_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_broadcast_detect_indication_t* value = (nfapi_utran_broadcast_detect_indication_t*)msg; + + return (push16(value->mib_length, ppWritePackedMsg, end) && + pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) && + push32(value->sfn_offset, ppWritePackedMsg, end)); +} + +static uint8_t pack_nb_iot_broadcast_detect_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_broadcast_detect_indication_t* value = (nfapi_nb_iot_broadcast_detect_indication_t*)msg; + + return (push8(value->number_of_tx_antenna, ppWritePackedMsg, end) && + push16(value->mib_length, ppWritePackedMsg, end) && + pusharray8(value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, ppWritePackedMsg, end) && + push32(value->sfn_offset, ppWritePackedMsg, end)); +} + +static uint8_t pack_broadcast_detect_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, ppWritePackedMsg, end, &pack_lte_broadcast_detect_indication_value) && + pack_tlv(NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, ppWritePackedMsg, end, &pack_utran_broadcast_detect_indication_value) && + pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) && + pack_tlv(NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, ppWritePackedMsg, end, &pack_nb_iot_broadcast_detect_indication_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lte_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_schedule_request_t* value = (nfapi_lte_system_information_schedule_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) && + push8(value->phich_configuration, ppWritePackedMsg, end) && + push8(value->number_of_tx_antenna, ppWritePackedMsg, end) && + push8(value->retry_count, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + +static uint8_t pack_nb_iot_system_information_schedule_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_schedule_request_t* value = (nfapi_nb_iot_system_information_schedule_request_t*)msg; + + return (push16(value->earfcn, ppWritePackedMsg, end) && + push8(value->ro_dl, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push8(value->scheduling_info_sib1_nb, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + + +static uint8_t pack_system_information_schedule_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t*)msg; + + if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0) + return 0; + + switch(pNfapiMsg->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, ppWritePackedMsg, end, &pack_lte_system_information_schedule_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_NB_IOT: + if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, ppWritePackedMsg, end, &pack_nb_iot_system_information_schedule_request_value) == 0) + return 0; + break; + } + + return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_system_information_schedule_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lte_system_information_indication_value(void* msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_indication_t* value = (nfapi_lte_system_information_indication_t*)msg; + + return (push8(value->sib_type, ppWritePackedMsg, end) && + push16(value->sib_length, ppWritePackedMsg, end) && + pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end)); +} + +static uint8_t pack_nb_iot_system_information_indication_value(void* msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_indication_t* value = (nfapi_nb_iot_system_information_indication_t*)msg; + + return (push8(value->sib_type, ppWritePackedMsg, end) && + push16(value->sib_length, ppWritePackedMsg, end) && + pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end)); +} + +static uint8_t pack_system_information_schedule_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) && + pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lte_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_request_t* value = (nfapi_lte_system_information_request_t*)msg; + uint16_t idx = 0; + + if(!(push16(value->earfcn, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push16(value->downlink_channel_bandwidth, ppWritePackedMsg, end) && + push8(value->phich_configuration, ppWritePackedMsg, end) && + push8(value->number_of_tx_antenna, ppWritePackedMsg, end) && + push8(value->number_of_si_periodicity, ppWritePackedMsg, end))) + return 0; + + for(idx = 0; idx < value->number_of_si_periodicity; ++idx) + { + if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) && + push8(value->si_periodicity[idx].si_index, ppWritePackedMsg, end))) + return 0; + } + + return (push8(value->si_window_length, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} +static uint8_t pack_utran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_system_information_request_t* value = (nfapi_utran_system_information_request_t*)msg; + + return (push16(value->uarfcn, ppWritePackedMsg, end) && + push16(value->psc, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} +static uint8_t pack_geran_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_geran_system_information_request_t* value = (nfapi_geran_system_information_request_t*)msg; + + return (push16(value->arfcn, ppWritePackedMsg, end) && + push8(value->bsic, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} +static uint8_t pack_nb_iot_system_information_request_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_request_t* value = (nfapi_nb_iot_system_information_request_t*)msg; + uint16_t idx = 0; + + if(!(push16(value->earfcn, ppWritePackedMsg, end) && + push8(value->ro_dl, ppWritePackedMsg, end) && + push16(value->pci, ppWritePackedMsg, end) && + push8(value->number_of_si_periodicity, ppWritePackedMsg, end))) + return 0; + + for(idx = 0; idx < value->number_of_si_periodicity; ++idx) + { + if(!(push8(value->si_periodicity[idx].si_periodicity, ppWritePackedMsg, end) && + push8(value->si_periodicity[idx].si_repetition_pattern, ppWritePackedMsg, end) && + push8(value->si_periodicity[idx].si_tb_size, ppWritePackedMsg, end) && + push8(value->si_periodicity[idx].number_of_si_index, ppWritePackedMsg, end))) + return 0; + + uint8_t si_idx; + for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx) + { + if(!(push8(value->si_periodicity[idx].si_index[si_idx], ppWritePackedMsg, end))) + return 0; + } + } + + return (push8(value->si_window_length, ppWritePackedMsg, end) && + push32(value->timeout, ppWritePackedMsg, end)); +} + + +static uint8_t pack_system_information_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t*)msg; + + if(push8(pNfapiMsg->rat_type, ppWritePackedMsg, end) == 0) + return 0; + + switch(pNfapiMsg->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + if(pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, ppWritePackedMsg, end, &pack_lte_system_information_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_UTRAN: + if(pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, ppWritePackedMsg, end, &pack_utran_system_information_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_GERAN: + if(pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, ppWritePackedMsg, end, &pack_geran_system_information_request_value) == 0) + return 0; + break; + case NFAPI_RAT_TYPE_NB_IOT: + if(pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, ppWritePackedMsg, end, &pack_nb_iot_system_information_request_value) == 0) + return 0; + break; + } + + return (pack_tlv(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, ppWritePackedMsg, end, &pack_opaque_data_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_system_information_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_utran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_utran_system_information_indication_t* value = (nfapi_utran_system_information_indication_t*)msg; + + return (push16(value->sib_length, ppWritePackedMsg, end) && + pusharray8(value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, ppWritePackedMsg, end)); +} + +static uint8_t pack_geran_system_information_indication_value(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_geran_system_information_indication_t* value = (nfapi_geran_system_information_indication_t*)msg; + + return (push16(value->si_length, ppWritePackedMsg, end) && + pusharray8(value->si, NFAPI_MAX_SIB_LENGTH, value->si_length, ppWritePackedMsg, end)); +} + +static uint8_t pack_system_information_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, ppWritePackedMsg, end, &pack_lte_system_information_indication_value) && + pack_tlv(NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, ppWritePackedMsg, end, &pack_utran_system_information_indication_value) && + pack_tlv(NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, ppWritePackedMsg, end, &pack_geran_system_information_indication_value) && + pack_tlv(NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, ppWritePackedMsg, end, &pack_nb_iot_system_information_indication_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nmm_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t*)msg; + + return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nmm_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t unpack_lte_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + //int result = 0; + nfapi_lte_rssi_request_t* value = (nfapi_lte_rssi_request_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) && + pull16(ppReadPackedMsg, &value->measurement_period, end) && + pull8(ppReadPackedMsg, &value->bandwidth, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_earfcns, end))) + return 0; + + if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST) + { + if(pullarray16(ppReadPackedMsg, value->earfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_earfcns, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns); + return 0; + } + + return 1; + +} + +static uint8_t unpack_utran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_rssi_request_t* value = (nfapi_utran_rssi_request_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) && + pull16(ppReadPackedMsg, &value->measurement_period, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_uarfcns, end))) + return 0; + + if(value->number_of_uarfcns <= NFAPI_MAX_CARRIER_LIST) + { + if(pullarray16(ppReadPackedMsg, value->uarfcn, NFAPI_MAX_CARRIER_LIST, value->number_of_uarfcns, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More UARFCN's than we can decode %d \n", value->number_of_uarfcns); + return 0; + } + + return 1; +} + +static uint8_t unpack_geran_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_geran_rssi_request_t* value = (nfapi_geran_rssi_request_t*)tlv; + uint16_t idx = 0; + + if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) && + pull16(ppReadPackedMsg, &value->measurement_period, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_arfcns, end))) + return 0; + + if(value->number_of_arfcns <= NFAPI_MAX_CARRIER_LIST) + { + for(idx = 0; idx < value->number_of_arfcns; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->arfcn[idx].arfcn, end) && + pull8(ppReadPackedMsg, &value->arfcn[idx].direction, end))) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcns); + return 0; + } + + return 1; +} + +static uint8_t unpack_nb_iot_rssi_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_rssi_request_t* value = (nfapi_nb_iot_rssi_request_t*)tlv; + uint16_t idx = 0; + + if(!(pull8(ppReadPackedMsg, &value->frequency_band_indicator, end) && + pull16(ppReadPackedMsg, &value->measurement_period, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_earfcns, end))) + return 0; + + if(value->number_of_earfcns <= NFAPI_MAX_CARRIER_LIST) + { + for(idx = 0; idx < value->number_of_earfcns; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->earfcn[idx].earfcn, end) && + pull8(ppReadPackedMsg, &value->earfcn[idx].number_of_ro_dl, end))) + return 0; + + if(value->earfcn[idx].number_of_ro_dl <= NFAPI_MAX_RO_DL) + { + uint8_t ro_dl_idx = 0; + for(ro_dl_idx = 0; ro_dl_idx < value->earfcn[idx].number_of_ro_dl; ++ro_dl_idx) + { + if(!pull8(ppReadPackedMsg, &value->earfcn[idx].ro_dl[ro_dl_idx], end)) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ROdl's than we can decode %d \n", value->earfcn[idx].number_of_ro_dl); + return 0; + } + + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More EARFCN's than we can decode %d \n", value->number_of_earfcns); + return 0; + } + + return 1; +} + +static uint8_t unpack_rssi_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_request_t *pNfapiMsg = (nfapi_rssi_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_RSSI_REQUEST_TAG, &pNfapiMsg->lte_rssi_request, &unpack_lte_rssi_request_value}, + { NFAPI_UTRAN_RSSI_REQUEST_TAG, &pNfapiMsg->utran_rssi_request, &unpack_utran_rssi_request_value}, + { NFAPI_GERAN_RSSI_REQUEST_TAG, &pNfapiMsg->geran_rssi_request, &unpack_geran_rssi_request_value}, + { NFAPI_NB_IOT_RSSI_REQUEST_TAG, &pNfapiMsg->nb_iot_rssi_request, &unpack_nb_iot_rssi_request_value}, + }; + + int result = 0; + + result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + + + // Verify that the rat type and the tlv match + if(result == 1 && + !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_rssi_request.tl.tag == NFAPI_LTE_RSSI_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_rssi_request.tl.tag == NFAPI_UTRAN_RSSI_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_rssi_request.tl.tag == NFAPI_GERAN_RSSI_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_rssi_request.tl.tag == NFAPI_NB_IOT_RSSI_REQUEST_TAG))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_rssi_request.tl.tag); + result = 0; + } + + return result; +} + +static uint8_t unpack_rssi_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_response_t *pNfapiMsg = (nfapi_rssi_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); +} + +static uint8_t unpack_rssi_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rssi_indication_body_t* value = (nfapi_rssi_indication_body_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->number_of_rssi, end) == 0) + return 0; + + if(value->number_of_rssi <= NFAPI_MAX_RSSI) + { + if(pullarrays16(ppReadPackedMsg, value->rssi, NFAPI_MAX_RSSI, value->number_of_rssi, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More RSSI's than we can decode %d \n", value->number_of_rssi); + return 0; + } + + return 1; +} + +static uint8_t unpack_rssi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_rssi_indication_t *pNfapiMsg = (nfapi_rssi_indication_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RSSI_INDICATION_TAG, &pNfapiMsg->rssi_indication_body, &unpack_rssi_indication_value}, + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_cell_search_request_t* value = (nfapi_lte_cell_search_request_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &value->earfcn, end) && + pull8(ppReadPackedMsg, &value->measurement_bandwidth, end) && + pull8(ppReadPackedMsg, &value->exhaustive_search, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_pci, end))) + return 0; + + if(value->number_of_pci <= NFAPI_MAX_PCI_LIST) + { + if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci); + return 0; + } + return 1; +} + +static uint8_t unpack_utran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_cell_search_request_t* value = (nfapi_utran_cell_search_request_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &value->uarfcn, end) && + pull8(ppReadPackedMsg, &value->exhaustive_search, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_psc, end))) + return 0; + + if(value->number_of_psc <= NFAPI_MAX_PSC_LIST) + { + if(pullarray16(ppReadPackedMsg, value->psc, NFAPI_MAX_PSC_LIST, value->number_of_psc, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PSC's than we can decode %d \n", value->number_of_psc); + return 0; + } + return 1; +} + +static uint8_t unpack_geran_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_geran_cell_search_request_t* value = (nfapi_geran_cell_search_request_t*)tlv; + + if(!(pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_arfcn, end))) + return 0; + + if(value->number_of_arfcn <= NFAPI_MAX_ARFCN_LIST) + { + if(pullarray16(ppReadPackedMsg, value->arfcn, NFAPI_MAX_ARFCN_LIST, value->number_of_arfcn, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More ARFCN's than we can decode %d \n", value->number_of_arfcn); + return 0; + } + return 1; +} + +static uint8_t unpack_nb_iot_cell_search_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_cell_search_request_t* value = (nfapi_nb_iot_cell_search_request_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &value->earfcn, end) && + pull8(ppReadPackedMsg, &value->ro_dl, end) && + pull8(ppReadPackedMsg, &value->exhaustive_search, end) && + pull32(ppReadPackedMsg, &value->timeout, end) && + pull8(ppReadPackedMsg, &value->number_of_pci, end))) + return 0; + + if(value->number_of_pci <= NFAPI_MAX_PCI_LIST) + { + if(pullarray16(ppReadPackedMsg, value->pci, NFAPI_MAX_PCI_LIST, value->number_of_pci, end) == 0) + return 0; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More PCI's than we can decode %d \n", value->number_of_pci); + return 0; + } + return 1; +} + +static uint8_t unpack_cell_search_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_request_t *pNfapiMsg = (nfapi_cell_search_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->lte_cell_search_request, &unpack_lte_cell_search_request_value}, + { NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->utran_cell_search_request, &unpack_utran_cell_search_request_value}, + { NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->geran_cell_search_request, &unpack_geran_cell_search_request_value}, + { NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG, &pNfapiMsg->nb_iot_cell_search_request, &unpack_nb_iot_cell_search_request_value}, + }; + + int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + + // Verify that the rat type and the tlv match + if(result == 1 && + !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_cell_search_request.tl.tag == NFAPI_LTE_CELL_SEARCH_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_cell_search_request.tl.tag == NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_cell_search_request.tl.tag == NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_NB_IOT && pNfapiMsg->nb_iot_cell_search_request.tl.tag == NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_cell_search_request.tl.tag); + result = 0; + } + + return result; +} + +static uint8_t unpack_cell_search_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_response_t *pNfapiMsg = (nfapi_cell_search_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_cell_search_indication_t* value = (nfapi_lte_cell_search_indication_t*)tlv; + + uint16_t idx = 0; + if(pull16(ppReadPackedMsg, &value->number_of_lte_cells_found, end) == 0) + return 0; + + if(value->number_of_lte_cells_found <= NFAPI_MAX_LTE_CELLS_FOUND) + { + for(idx = 0; idx < value->number_of_lte_cells_found; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->lte_found_cells[idx].pci, end) && + pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrp, end) && + pull8(ppReadPackedMsg, &value->lte_found_cells[idx].rsrq, end) && + pulls16(ppReadPackedMsg, &value->lte_found_cells[idx].frequency_offset, end))) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found LTE cells than we can decode %d \n", value->number_of_lte_cells_found); + return 0; + } + return 1; +} + +static uint8_t unpack_utran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_cell_search_indication_t* value = (nfapi_utran_cell_search_indication_t*)tlv; + + uint16_t idx = 0; + if(pull16(ppReadPackedMsg, &value->number_of_utran_cells_found, end) == 0) + return 0; + + if(value->number_of_utran_cells_found <= NFAPI_MAX_UTRAN_CELLS_FOUND) + { + for(idx = 0; idx < value->number_of_utran_cells_found; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->utran_found_cells[idx].psc, end) && + pull8(ppReadPackedMsg, &value->utran_found_cells[idx].rscp, end) && + pull8(ppReadPackedMsg, &value->utran_found_cells[idx].ecno, end) && + pulls16(ppReadPackedMsg, &value->utran_found_cells[idx].frequency_offset, end))) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found UTRAN cells than we can decode %d \n", value->number_of_utran_cells_found); + return 0; + } + return 1; +} + +static uint8_t unpack_geran_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_geran_cell_search_indication_t* value = (nfapi_geran_cell_search_indication_t*)tlv; + + uint16_t idx = 0; + if(pull16(ppReadPackedMsg, &value->number_of_gsm_cells_found, end) == 0) + return 0; + + if(value->number_of_gsm_cells_found <= NFAPI_MAX_GSM_CELLS_FOUND) + { + for(idx = 0; idx < value->number_of_gsm_cells_found; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->gsm_found_cells[idx].arfcn, end) && + pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].bsic, end) && + pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxlev, end) && + pull8(ppReadPackedMsg, &value->gsm_found_cells[idx].rxqual, end) && + pulls16(ppReadPackedMsg, &value->gsm_found_cells[idx].frequency_offset, end) && + pull32(ppReadPackedMsg, &value->gsm_found_cells[idx].sfn_offset, end))) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found GSM cells than we can decode %d \n", value->number_of_gsm_cells_found); + return 0; + } + return 1; +} + +static uint8_t unpack_nb_iot_cell_search_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_cell_search_indication_t* value = (nfapi_nb_iot_cell_search_indication_t*)tlv; + + uint16_t idx = 0; + if(pull16(ppReadPackedMsg, &value->number_of_nb_iot_cells_found, end) == 0) + return 0; + + if(value->number_of_nb_iot_cells_found <= NFAPI_MAX_NB_IOT_CELLS_FOUND) + { + for(idx = 0; idx < value->number_of_nb_iot_cells_found; ++idx) + { + if(!(pull16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].pci, end) && + pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrp, end) && + pull8(ppReadPackedMsg, &value->nb_iot_found_cells[idx].rsrq, end) && + pulls16(ppReadPackedMsg, &value->nb_iot_found_cells[idx].frequency_offset, end))) + return 0; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found NB_IOT cells than we can decode %d \n", value->number_of_nb_iot_cells_found); + return 0; + } + return 1; +} + +static uint8_t unpack_cell_search_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_cell_search_indication_t *pNfapiMsg = (nfapi_cell_search_indication_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->lte_cell_search_indication, &unpack_lte_cell_search_indication_value}, + { NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->utran_cell_search_indication, &unpack_utran_cell_search_indication_value}, + { NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->geran_cell_search_indication, &unpack_geran_cell_search_indication_value}, + { NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value}, + { NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG, &pNfapiMsg->nb_iot_cell_search_indication, &unpack_nb_iot_cell_search_indication_value}, + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_lte_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_broadcast_detect_request_t* value = (nfapi_lte_broadcast_detect_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->earfcn, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_utran_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_broadcast_detect_request_t* value = (nfapi_utran_broadcast_detect_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->uarfcn, end) && + pull16(ppReadPackedMsg, &value->psc, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_nb_iot_broadcast_detect_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_broadcast_detect_request_t* value = (nfapi_nb_iot_broadcast_detect_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->earfcn, end) && + pull8(ppReadPackedMsg, &value->ro_dl, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_broadcast_detect_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_request_t *pNfapiMsg = (nfapi_broadcast_detect_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->lte_broadcast_detect_request, &unpack_lte_broadcast_detect_request_value}, + { NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->utran_broadcast_detect_request, &unpack_utran_broadcast_detect_request_value}, + { NFAPI_PNF_CELL_SEARCH_STATE_TAG, &pNfapiMsg->pnf_cell_search_state, &unpack_opaque_data_value}, + { NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG, &pNfapiMsg->nb_iot_broadcast_detect_request, &unpack_nb_iot_broadcast_detect_request_value} + }; + + return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_broadcast_detect_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_response_t *pNfapiMsg = (nfapi_broadcast_detect_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_broadcast_detect_indication_t* value = (nfapi_lte_broadcast_detect_indication_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) && + pull16(ppReadPackedMsg, &value->mib_length, end))) + return 0; + + if(value->mib_length > NFAPI_MAX_MIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length); + return 0; + } + + return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) && + pull32(ppReadPackedMsg, &value->sfn_offset, end)); +} + +static uint8_t unpack_utran_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_broadcast_detect_indication_t* value = (nfapi_utran_broadcast_detect_indication_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->mib_length, end) == 0) + return 0; + + if(value->mib_length > NFAPI_MAX_MIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length); + return 0; + } + + return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) && + pull32(ppReadPackedMsg, &value->sfn_offset, end)); +} + +static uint8_t unpack_nb_iot_broadcast_detect_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_broadcast_detect_indication_t* value = (nfapi_nb_iot_broadcast_detect_indication_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) && + pull16(ppReadPackedMsg, &value->mib_length, end))) + return 0; + + if(value->mib_length > NFAPI_MAX_MIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "MIB too long %d \n", value->mib_length); + return 0; + } + + return (pullarray8(ppReadPackedMsg, value->mib, NFAPI_MAX_MIB_LENGTH, value->mib_length, end) && + pull32(ppReadPackedMsg, &value->sfn_offset, end)); +} + +static uint8_t unpack_broadcast_detect_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_broadcast_detect_indication_t *pNfapiMsg = (nfapi_broadcast_detect_indication_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->lte_broadcast_detect_indication, &unpack_lte_broadcast_detect_indication_value}, + { NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->utran_broadcast_detect_indication, &unpack_utran_broadcast_detect_indication_value}, + { NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG, &pNfapiMsg->nb_iot_broadcast_detect_indication, &unpack_nb_iot_broadcast_detect_indication_value}, + { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value} + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_schedule_request_t* value = (nfapi_lte_system_information_schedule_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->earfcn, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) && + pull8(ppReadPackedMsg, &value->phich_configuration, end) && + pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) && + pull8(ppReadPackedMsg, &value->retry_count, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_nb_iot_system_information_schedule_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_schedule_request_t* value = (nfapi_nb_iot_system_information_schedule_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->earfcn, end) && + pull8(ppReadPackedMsg, &value->ro_dl, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull8(ppReadPackedMsg, &value->scheduling_info_sib1_nb, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_system_information_schedule_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_request_t *pNfapiMsg = (nfapi_system_information_schedule_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->lte_system_information_schedule_request, &unpack_lte_system_information_schedule_request_value}, + { NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_schedule_request, &unpack_nb_iot_system_information_schedule_request_value}, + { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value} + }; + + return (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_system_information_schedule_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_response_t *pNfapiMsg = (nfapi_system_information_schedule_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_indication_t* value = (nfapi_lte_system_information_indication_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->sib_type, end) && + pull16(ppReadPackedMsg, &value->sib_length, end))) + return 0; + + if(value->sib_length > NFAPI_MAX_SIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length); + return 0; + } + + if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, end) == 0) + return 0; + + return 1; +} + +static uint8_t unpack_nb_iot_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_indication_t* value = (nfapi_nb_iot_system_information_indication_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->sib_type, end) && + pull16(ppReadPackedMsg, &value->sib_length, end))) + return 0; + + if(value->sib_length > NFAPI_MAX_SIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length); + return 0; + } + + if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, end) == 0) + return 0; + + return 1; +} + +static uint8_t unpack_system_information_schedule_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_schedule_indication_t *pNfapiMsg = (nfapi_system_information_schedule_indication_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value}, + { NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value}, + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lte_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lte_system_information_request_t* value = (nfapi_lte_system_information_request_t*)tlv; + uint16_t idx = 0; + + if(!(pull16(ppReadPackedMsg, &value->earfcn, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull16(ppReadPackedMsg, &value->downlink_channel_bandwidth, end) && + pull8(ppReadPackedMsg, &value->phich_configuration, end) && + pull8(ppReadPackedMsg, &value->number_of_tx_antenna, end) && + pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end))) + return 0; + + if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity); + return 0; + } + + for(idx = 0; idx < value->number_of_si_periodicity; ++idx) + { + if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) && + pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index, end))) + return 0; + } + + if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) && + pull32(ppReadPackedMsg, &value->timeout, end))) + return 0; + + return 1; +} + +static uint8_t unpack_utran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_system_information_request_t* value = (nfapi_utran_system_information_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->uarfcn, end) && + pull16(ppReadPackedMsg, &value->psc, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_geran_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_geran_system_information_request_t* value = (nfapi_geran_system_information_request_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->arfcn, end) && + pull8(ppReadPackedMsg, &value->bsic, end) && + pull32(ppReadPackedMsg, &value->timeout, end)); +} + +static uint8_t unpack_nb_iot_system_information_request_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_iot_system_information_request_t* value = (nfapi_nb_iot_system_information_request_t*)tlv; + uint16_t idx = 0; + + if(!(pull16(ppReadPackedMsg, &value->earfcn, end) && + pull8(ppReadPackedMsg, &value->ro_dl, end) && + pull16(ppReadPackedMsg, &value->pci, end) && + pull8(ppReadPackedMsg, &value->number_of_si_periodicity, end))) + return 0; + + if(value->number_of_si_periodicity > NFAPI_MAX_SI_PERIODICITY) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "More found SI periodicity than we can decode %d \n", value->number_of_si_periodicity); + return 0; + } + + for(idx = 0; idx < value->number_of_si_periodicity; ++idx) + { + if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_periodicity, end) && + pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_repetition_pattern, end) && + pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_tb_size, end) && + pull8(ppReadPackedMsg, &value->si_periodicity[idx].number_of_si_index, end))) + return 0; + + uint8_t si_idx; + for(si_idx = 0; si_idx < value->si_periodicity[idx].number_of_si_index; ++si_idx) + { + if(!(pull8(ppReadPackedMsg, &value->si_periodicity[idx].si_index[si_idx], end))) + return 0; + + } + } + + if(!(pull8(ppReadPackedMsg, &value->si_window_length, end) && + pull32(ppReadPackedMsg, &value->timeout, end))) + return 0; + + return 1; +} + +static uint8_t unpack_system_information_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_request_t *pNfapiMsg = (nfapi_system_information_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->lte_system_information_request, &unpack_lte_system_information_request_value}, + { NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->utran_system_information_request, &unpack_utran_system_information_request_value}, + { NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->geran_system_information_request, &unpack_geran_system_information_request_value}, + { NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG, &pNfapiMsg->nb_iot_system_information_request, &unpack_nb_iot_system_information_request_value}, + { NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &pNfapiMsg->pnf_cell_broadcast_state, &unpack_opaque_data_value} + }; + + + int result = (pull8(ppReadPackedMsg, &pNfapiMsg->rat_type, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + + // Verify that the rat type and the tlv match + if(result == 1 && + !((pNfapiMsg->rat_type == NFAPI_RAT_TYPE_LTE && pNfapiMsg->lte_system_information_request.tl.tag == NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_UTRAN && pNfapiMsg->utran_system_information_request.tl.tag == NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG) || + (pNfapiMsg->rat_type == NFAPI_RAT_TYPE_GERAN && pNfapiMsg->geran_system_information_request.tl.tag == NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Mismatch RAT Type: %d and TAG value: 0x%04x \n", pNfapiMsg->rat_type, pNfapiMsg->lte_system_information_request.tl.tag); + result = 0; + } + + return result; +} + +static uint8_t unpack_system_information_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_response_t *pNfapiMsg = (nfapi_system_information_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_utran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_utran_system_information_indication_t* value = (nfapi_utran_system_information_indication_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->sib_length, end) == 0) + return 0; + + if(value->sib_length > NFAPI_MAX_SIB_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->sib_length); + return 0; + } + + if(pullarray8(ppReadPackedMsg, value->sib, NFAPI_MAX_SIB_LENGTH, value->sib_length, end) == 0) + return 0; + + return 1; +} + +static uint8_t unpack_geran_system_information_indication_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_geran_system_information_indication_t* value = (nfapi_geran_system_information_indication_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->si_length, end) == 0) + return 0; + + if(value->si_length > NFAPI_MAX_SI_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "SIB too long %d \n", value->si_length); + return 0; + } + + if(pullarray8(ppReadPackedMsg, value->si, NFAPI_MAX_SI_LENGTH, value->si_length, end) == 0) + return 0; + + return 1; +} + +static uint8_t unpack_system_information_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_system_information_indication_t *pNfapiMsg = (nfapi_system_information_indication_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->lte_system_information_indication, &unpack_lte_system_information_indication_value}, + { NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->utran_system_information_indication, &unpack_utran_system_information_indication_value}, + { NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->geran_system_information_indication, &unpack_geran_system_information_indication_value}, + { NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG, &pNfapiMsg->nb_iot_system_information_indication, &unpack_nb_iot_system_information_indication_value}, + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_nmm_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nmm_stop_request_t *pNfapiMsg = (nfapi_nmm_stop_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension); +} + +static uint8_t unpack_nmm_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nmm_stop_response_t *pNfapiMsg = (nfapi_nmm_stop_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_RSSI_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_rssi_request_t)) + retLen = sizeof(nfapi_rssi_request_t); + break; + + case NFAPI_RSSI_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_rssi_response_t)) + retLen = sizeof(nfapi_rssi_response_t); + break; + + case NFAPI_RSSI_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rssi_indication_t)) + retLen = sizeof(nfapi_rssi_indication_t); + break; + + case NFAPI_CELL_SEARCH_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_cell_search_request_t)) + retLen = sizeof(nfapi_cell_search_request_t); + break; + + case NFAPI_CELL_SEARCH_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_cell_search_response_t)) + retLen = sizeof(nfapi_cell_search_response_t); + break; + + case NFAPI_CELL_SEARCH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_cell_search_indication_t)) + retLen = sizeof(nfapi_cell_search_indication_t); + break; + + case NFAPI_BROADCAST_DETECT_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_request_t)) + retLen = sizeof(nfapi_broadcast_detect_request_t); + break; + + case NFAPI_BROADCAST_DETECT_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_response_t)) + retLen = sizeof(nfapi_broadcast_detect_response_t); + break; + + case NFAPI_BROADCAST_DETECT_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_broadcast_detect_indication_t)) + retLen = sizeof(nfapi_broadcast_detect_indication_t); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_request_t)) + retLen = sizeof(nfapi_system_information_schedule_request_t); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_response_t)) + retLen = sizeof(nfapi_system_information_schedule_response_t); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_system_information_schedule_indication_t)) + retLen = sizeof(nfapi_system_information_schedule_indication_t); + break; + + case NFAPI_SYSTEM_INFORMATION_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_system_information_request_t)) + retLen = sizeof(nfapi_system_information_request_t); + break; + + case NFAPI_SYSTEM_INFORMATION_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_system_information_response_t)) + retLen = sizeof(nfapi_system_information_response_t); + break; + + case NFAPI_SYSTEM_INFORMATION_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_system_information_indication_t)) + retLen = sizeof(nfapi_system_information_indication_t); + break; + + case NFAPI_NMM_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nmm_stop_request_t)) + retLen = sizeof(nfapi_nmm_stop_request_t); + break; + + case NFAPI_NMM_STOP_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nmm_stop_response_t)) + retLen = sizeof(nfapi_nmm_stop_response_t); + break; + + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); + break; + } + + return retLen; +} + +int nfapi_p4_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *end = pPackedBuf + packedBufLen; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint32_t packedMsgLen; + uint16_t packedMsgLen16; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 Pack supplied pointers are null\n"); + return -1; + } + + // process the header + if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && + push16(pMessageHeader->message_id, &pWritePackedMessage, end) && + push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) && + push16(pMessageHeader->spare, &pWritePackedMessage, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header\n"); + return -1; + } + + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) + { + case NFAPI_RSSI_REQUEST: + result = pack_rssi_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RSSI_RESPONSE: + result = pack_rssi_response(pMessageHeader, &pWritePackedMessage, end,config); + break; + + case NFAPI_RSSI_INDICATION: + result = pack_rssi_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CELL_SEARCH_REQUEST: + result = pack_cell_search_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CELL_SEARCH_RESPONSE: + result = pack_cell_search_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CELL_SEARCH_INDICATION: + result = pack_cell_search_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_BROADCAST_DETECT_REQUEST: + result = pack_broadcast_detect_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_BROADCAST_DETECT_RESPONSE: + result = pack_broadcast_detect_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_BROADCAST_DETECT_INDICATION: + result = pack_broadcast_detect_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST: + result = pack_system_information_schedule_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE: + result = pack_system_information_schedule_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION: + result = pack_system_information_schedule_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_REQUEST: + result = pack_system_information_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_RESPONSE: + result = pack_system_information_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SYSTEM_INFORMATION_INDICATION: + result = pack_system_information_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NMM_STOP_REQUEST: + result = pack_nmm_stop_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NMM_STOP_RESPONSE: + result = pack_nmm_stop_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + default: + { + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MIN) + { + if(config && config->pack_p4_p5_vendor_extension) + { + result =(config->pack_p4_p5_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve encoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + } + break; + } + + // return the packed length + if(result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Result is 0\n"); + return -1; + } + + + // check for a valid message length + packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage); + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + if(push16(packedMsgLen16, &pPackedLengthField, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to pack p4 message header lengt\n"); + return -1; + } + + return (packedMsgLen); + +} + +// Main unpack functions - public + +int nfapi_p4_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 header unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // process the headei + if (pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->spare, end)) + return -1; + + return 0; +} + +int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + int result = 0; + nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P4 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) + return -1; + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_RSSI_REQUEST: + if (check_unpack_length(NFAPI_RSSI_REQUEST, unpackedBufLen)) + result = unpack_rssi_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_RSSI_RESPONSE: + if (check_unpack_length(NFAPI_RSSI_RESPONSE, unpackedBufLen)) + result = unpack_rssi_response(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_RSSI_INDICATION: + if (check_unpack_length(NFAPI_RSSI_INDICATION, unpackedBufLen)) + result = unpack_rssi_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_CELL_SEARCH_REQUEST: + if (check_unpack_length(NFAPI_CELL_SEARCH_REQUEST, unpackedBufLen)) + result = unpack_cell_search_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_CELL_SEARCH_RESPONSE: + if (check_unpack_length(NFAPI_CELL_SEARCH_RESPONSE, unpackedBufLen)) + result = unpack_cell_search_response(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_CELL_SEARCH_INDICATION: + if (check_unpack_length(NFAPI_CELL_SEARCH_INDICATION, unpackedBufLen)) + result = unpack_cell_search_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_BROADCAST_DETECT_REQUEST: + if (check_unpack_length(NFAPI_BROADCAST_DETECT_REQUEST, unpackedBufLen)) + result = unpack_broadcast_detect_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_BROADCAST_DETECT_RESPONSE: + if (check_unpack_length(NFAPI_BROADCAST_DETECT_RESPONSE, unpackedBufLen)) + result = unpack_broadcast_detect_response(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_BROADCAST_DETECT_INDICATION: + if (check_unpack_length(NFAPI_BROADCAST_DETECT_INDICATION, unpackedBufLen)) + result = unpack_broadcast_detect_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST, unpackedBufLen)) + result = unpack_system_information_schedule_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE, unpackedBufLen)) + result = unpack_system_information_schedule_response(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION, unpackedBufLen)) + result = unpack_system_information_schedule_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_REQUEST: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_REQUEST, unpackedBufLen)) + result = unpack_system_information_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_RESPONSE: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_RESPONSE, unpackedBufLen)) + result = unpack_system_information_response(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_SYSTEM_INFORMATION_INDICATION: + if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_INDICATION, unpackedBufLen)) + result = unpack_system_information_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_NMM_STOP_REQUEST: + if (check_unpack_length(NFAPI_NMM_STOP_REQUEST, unpackedBufLen)) + result = unpack_nmm_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + else + result = -1; + break; + + case NFAPI_NMM_STOP_RESPONSE: + if (check_unpack_length(NFAPI_NMM_STOP_RESPONSE, unpackedBufLen)) + result = unpack_nmm_stop_response(&pReadPackedMessage, end , pMessageHeader, config); + else + result = -1; + break; + + default: + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p4_p5_vendor_extension) + { + result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P4 message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + if(result == 0) + return -1; + + return result; +} diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c new file mode 100644 index 0000000000..c78b829135 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -0,0 +1,1800 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// Pack routines + +static uint8_t pack_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_param_request_t* request = (nfapi_pnf_param_request_t*)msg; + return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config); +} + +static uint8_t pack_pnf_param_general_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_param_general_t* value = (nfapi_pnf_param_general_t*)tlv; + + return ( push8(value->nfapi_sync_mode, ppWritePackedMsg, end) && + push8(value->location_mode, ppWritePackedMsg, end) && + push16(value->location_coordinates_length, ppWritePackedMsg, end) && + pusharray8(value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, ppWritePackedMsg, end) && + push32(value->dl_config_timing, ppWritePackedMsg, end) && + push32(value->tx_timing, ppWritePackedMsg, end) && + push32(value->ul_config_timing, ppWritePackedMsg, end) && + push32(value->hi_dci0_timing, ppWritePackedMsg, end) && + push16(value->maximum_number_phys, ppWritePackedMsg, end) && + push16(value->maximum_total_bandwidth, ppWritePackedMsg, end) && + push8(value->maximum_total_number_dl_layers, ppWritePackedMsg, end) && + push8(value->maximum_total_number_ul_layers, ppWritePackedMsg, end) && + push8(value->shared_bands, ppWritePackedMsg, end) && + push8(value->shared_pa, ppWritePackedMsg, end) && + pushs16(value->maximum_total_power, ppWritePackedMsg, end) && + pusharray8(value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, ppWritePackedMsg, end)); +} + +static uint8_t pack_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rf_config_info_t* rf = (nfapi_rf_config_info_t*)elem; + + return (push16(rf->rf_config_index, ppWritePackedMsg, end)); +} + + +static uint8_t pack_pnf_phy_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t* end) +{ + nfapi_pnf_phy_info_t* phy = (nfapi_pnf_phy_info_t*)elem; + + return ( push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->number_of_rfs, ppWritePackedMsg, end) && + packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) && + push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) && + packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) && + push16(phy->downlink_channel_bandwidth_supported, ppWritePackedMsg, end) && + push16(phy->uplink_channel_bandwidth_supported, ppWritePackedMsg, end) && + push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) && + push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) && + push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) && + push8(phy->nmm_modes_supported, ppWritePackedMsg, end)); + + +} + +static uint8_t pack_pnf_phy_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_t* value = (nfapi_pnf_phy_t*)tlv; + + return ( push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_info)); +} + +static uint8_t pack_pnf_rf_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_rf_t* value = (nfapi_pnf_rf_t*)tlv; + uint16_t rf_index = 0; + + if(push16(value->number_of_rfs, ppWritePackedMsg, end) == 0) + return 0; + + for(; rf_index < value->number_of_rfs; ++rf_index) + { + if( !(push16(value->rf[rf_index].rf_config_index, ppWritePackedMsg, end) && + push16(value->rf[rf_index].band, ppWritePackedMsg, end) && + pushs16(value->rf[rf_index].maximum_transmit_power, ppWritePackedMsg, end) && + pushs16(value->rf[rf_index].minimum_transmit_power, ppWritePackedMsg, end) && + push8(value->rf[rf_index].number_of_antennas_suppported, ppWritePackedMsg, end) && + push32(value->rf[rf_index].minimum_downlink_frequency, ppWritePackedMsg, end) && + push32(value->rf[rf_index].maximum_downlink_frequency, ppWritePackedMsg, end) && + push32(value->rf[rf_index].minimum_uplink_frequency, ppWritePackedMsg, end) && + push32(value->rf[rf_index].maximum_uplink_frequency, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} +static uint8_t pack_pnf_phy_rel10_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel10_info_t* phy = (nfapi_pnf_phy_rel10_info_t*)elem; + + return(push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->transmission_mode_7_supported, ppWritePackedMsg, end) && + push16(phy->transmission_mode_8_supported, ppWritePackedMsg, end) && + push16(phy->two_antenna_ports_for_pucch, ppWritePackedMsg, end) && + push16(phy->transmission_mode_9_supported, ppWritePackedMsg, end) && + push16(phy->simultaneous_pucch_pusch, ppWritePackedMsg, end) && + push16(phy->four_layer_tx_with_tm3_and_tm4, ppWritePackedMsg, end)); +} + +static uint8_t pack_pnf_phy_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel10_t* value = (nfapi_pnf_phy_rel10_t*)tlv; + + return (push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel10_info)); + +} + +static uint8_t pack_pnf_phy_rel11_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel11_info_t* phy = (nfapi_pnf_phy_rel11_info_t*)elem; + + return (push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->edpcch_supported, ppWritePackedMsg, end) && + push16(phy->multi_ack_csi_reporting, ppWritePackedMsg, end) && + push16(phy->pucch_tx_diversity, ppWritePackedMsg, end) && + push16(phy->ul_comp_supported, ppWritePackedMsg, end) && + push16(phy->transmission_mode_5_supported, ppWritePackedMsg, end )); +} +static uint8_t pack_pnf_phy_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel11_t* value = (nfapi_pnf_phy_rel11_t*)tlv; + + return (push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel11_info)); +} +static uint8_t pack_pnf_phy_rel12_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel12_info_t* phy = (nfapi_pnf_phy_rel12_info_t*)elem; + + return( push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->csi_subframe_set, ppWritePackedMsg, end) && + push16(phy->enhanced_4tx_codebook, ppWritePackedMsg, end) && + push16(phy->drs_supported, ppWritePackedMsg, end) && + push16(phy->ul_64qam_supported, ppWritePackedMsg, end) && + push16(phy->transmission_mode_10_supported, ppWritePackedMsg, end) && + push16(phy->alternative_bts_indices, ppWritePackedMsg, end)); +} +static uint8_t pack_pnf_phy_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel12_t* value = (nfapi_pnf_phy_rel12_t*)tlv; + + return (push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_rel12_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel12_info)); + +} + +static uint8_t pack_pnf_phy_rel13_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_info_t* phy = (nfapi_pnf_phy_rel13_info_t*)elem; + + return( push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->pucch_format4_supported, ppWritePackedMsg, end) && + push16(phy->pucch_format5_supported, ppWritePackedMsg, end) && + push16(phy->more_than_5_ca_support, ppWritePackedMsg, end) && + push16(phy->laa_supported, ppWritePackedMsg, end) && + push16(phy->laa_ending_in_dwpts_supported, ppWritePackedMsg, end) && + push16(phy->laa_starting_in_second_slot_supported, ppWritePackedMsg, end) && + push16(phy->beamforming_supported, ppWritePackedMsg, end) && + push16(phy->csi_rs_enhancement_supported, ppWritePackedMsg, end) && + push16(phy->drms_enhancement_supported, ppWritePackedMsg, end) && + push16(phy->srs_enhancement_supported, ppWritePackedMsg, end) ); +} + +static uint8_t pack_pnf_phy_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_t* value = (nfapi_pnf_phy_rel13_t*)tlv; + + return (push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_info)); +} + +static uint8_t pack_pnf_phy_rel13_nb_iot_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_nb_iot_info_t* phy = (nfapi_pnf_phy_rel13_nb_iot_info_t*)elem; + + return( push16(phy->phy_config_index, ppWritePackedMsg, end) && + push16(phy->number_of_rfs, ppWritePackedMsg, end) && + packarray(phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, ppWritePackedMsg, end, &pack_rf_config_info) && + push16(phy->number_of_rf_exclusions, ppWritePackedMsg, end) && + packarray(phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, ppWritePackedMsg, end, &pack_rf_config_info) && + push8(phy->number_of_dl_layers_supported, ppWritePackedMsg, end) && + push8(phy->number_of_ul_layers_supported, ppWritePackedMsg, end) && + push16(phy->maximum_3gpp_release_supported, ppWritePackedMsg, end) && + push8(phy->nmm_modes_supported, ppWritePackedMsg, end)); +} + +static uint8_t pack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_nb_iot_t* value = (nfapi_pnf_phy_rel13_nb_iot_t*)tlv; + + return (push16(value->number_of_phys, ppWritePackedMsg, end) && + packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_info)); +} + + +static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) && + pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) && + pack_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) && + pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) && + pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) && + pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) && + pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) && + pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_phy_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem; + + return (push16(rf->phy_id, ppWritePackedMsg, end) && + push16(rf->phy_config_index, ppWritePackedMsg, end) && + push16(rf->rf_config_index, ppWritePackedMsg, end)); +} + + +static uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rf_config_t *value = (nfapi_pnf_phy_rf_config_t*)tlv; + + return(push16(value->number_phy_rf_config_info, ppWritePackedMsg, end) && + packarray(value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, ppWritePackedMsg, end, &pack_phy_rf_config_info)); + +} + +static uint8_t pack_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg; + return ( pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config)); +} + + +static uint8_t pack_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg; + return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg; + + return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg; + return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg; + return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_uint16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv; + return push16(value->value, ppWritePackedMsg, end); +} + +static uint8_t unpack_uint16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv; + return pull16(ppReadPackedMsg, &value->value, end); +} +static uint8_t pack_int16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv; + return pushs16(value->value, ppWritePackedMsg, end); +} + +static uint8_t unpack_int16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv; + return pulls16(ppReadPackedMsg, &value->value, end); +} + +static uint8_t pack_uint8_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_uint8_tlv_t* value = (nfapi_uint8_tlv_t*)tlv; + return push8(value->value, ppWritePackedMsg, end); +} +static uint8_t unpack_uint8_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_uint8_tlv_t* value = (nfapi_uint8_tlv_t*)tlv; + return pull8(ppReadPackedMsg, &value->value, end); +} + +static uint8_t pack_ipv4_address_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv; + return pusharray8(value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, ppWritePackedMsg, end); +} +static uint8_t unpack_ipv4_address_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv; + return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV4_ADDRESS_LENGTH, NFAPI_IPV4_ADDRESS_LENGTH, end); +} +static uint8_t pack_ipv6_address_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ipv6_address_t* value = (nfapi_ipv6_address_t*)tlv; + return pusharray8(value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, ppWritePackedMsg, end); +} +static uint8_t unpack_ipv6_address_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ipv4_address_t* value = (nfapi_ipv4_address_t*)tlv; + return pullarray8(ppReadPackedMsg, value->address, NFAPI_IPV6_ADDRESS_LENGTH, NFAPI_IPV6_ADDRESS_LENGTH, end); +} + +static uint8_t pack_rf_bands_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rf_bands_t* value = (nfapi_rf_bands_t*)tlv; + + return ( push16(value->number_rf_bands, ppWritePackedMsg, end) && + pusharray16(value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, ppWritePackedMsg, end)); +} +static uint8_t unpack_rf_bands_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end) +{ + nfapi_rf_bands_t* value = (nfapi_rf_bands_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_rf_bands, end) && + pullarray16(ppReadPackedMsg, value->rf_band, NFAPI_MAX_NUM_RF_BANDS, value->number_rf_bands, end)); +} + +static uint8_t pack_nmm_frequency_bands_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nmm_frequency_bands_t* value = (nfapi_nmm_frequency_bands_t*)tlv; + + return( push16(value->number_of_rf_bands, ppWritePackedMsg, end) && + pusharray16(value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, ppWritePackedMsg, end)); +} +static uint8_t unpack_nmm_frequency_bands_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nmm_frequency_bands_t* value = (nfapi_nmm_frequency_bands_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) && + pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end)); +} + +static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg; + + return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && + push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && + pack_tlv(NFAPI_L1_STATUS_PHY_STATE_TAG, &pNfapiMsg->l1_status.phy_state, ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + // Do we check the phy state and then just fill those sepecified, however + // we do not know the duplex mode, so just attempt to pack all and assumme + // that the callee has set the right tlvs + + pack_tlv(NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_bandwidth_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.dl_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &(pNfapiMsg->phy_capabilities.ul_modulation_support), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.phy_antenna_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &(pNfapiMsg->phy_capabilities.mbsfn_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + // laa capability + + pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value)&& + pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end ,&pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + + pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + + pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) && + + pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + + pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); + +} + +static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg; + + return ( push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && + + // Do we check the phy state and then just fill those sepecified, however + // we do not know the duplex mode, so just attempt to pack all and assumme + // that the callee has set the right tlvs + + pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_pdsch), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &(pNfapiMsg->laa_config.pd_threshold), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &(pNfapiMsg->laa_config.multi_carrier_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &(pNfapiMsg->laa_config.multi_carrier_tx), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &(pNfapiMsg->laa_config.multi_carrier_freeze), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_antenna_ports_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_power_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &(pNfapiMsg->emtc_config.pbch_repetitions_enable_r13), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_catm_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &(pNfapiMsg->emtc_config.prach_catm_high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_PHY_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) && + + pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + + pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg; + return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); +} + +static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg; + return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); +} + +static uint8_t pack_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_measurement_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t*)msg; + + return( pack_tlv(NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &(pNfapiMsg->dl_rs_tx_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &(pNfapiMsg->received_interference_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &(pNfapiMsg->thermal_noise_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_recevied_interference_power_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_received_interference_power_measurement_t* value = (nfapi_received_interference_power_measurement_t*)tlv; + + return ( push16(value->number_of_resource_blocks, ppWritePackedMsg, end) && + pusharrays16(value->received_interference_power, NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, ppWritePackedMsg, end)); +} + +static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t*)msg; + + return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &(pNfapiMsg->dl_rs_tx_power_measurement), ppWritePackedMsg, end, &pack_int16_tlv_value) && + pack_tlv(NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &(pNfapiMsg->received_interference_power_measurement), ppWritePackedMsg, end, &pack_recevied_interference_power_measurement_value) && + pack_tlv(NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &(pNfapiMsg->thermal_noise_power_measurement), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + uint8_t result = 0; + // look for the specific message + switch (header->message_id) + { + case NFAPI_PNF_PARAM_REQUEST: + result = pack_pnf_param_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_PARAM_RESPONSE: + result = pack_pnf_param_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_CONFIG_REQUEST: + result = pack_pnf_config_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_CONFIG_RESPONSE: + result = pack_pnf_config_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_START_REQUEST: + result = pack_pnf_start_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_START_RESPONSE: + result = pack_pnf_start_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_STOP_REQUEST: + result = pack_pnf_stop_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_STOP_RESPONSE: + result = pack_pnf_stop_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PARAM_REQUEST: + result = pack_param_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PARAM_RESPONSE: + result = pack_param_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_CONFIG_REQUEST: + result = pack_config_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_CONFIG_RESPONSE: + result = pack_config_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_START_REQUEST: + result = pack_start_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_START_RESPONSE: + result = pack_start_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_STOP_REQUEST: + result = pack_stop_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_STOP_RESPONSE: + result = pack_stop_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_MEASUREMENT_REQUEST: + result = pack_measurement_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + result = pack_measurement_response(header, ppWritePackedMsg, end, config); + break; + + default: + { + if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->pack_p4_p5_vendor_extension) + { + result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id); + } + } + break; + } + + return result; +} + + +// helper function for message length calculation - +// takes the pointers to the start of message to end of message + +static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) +{ + if (msgEnd < msgHead) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd); + return 0; + } + + return (msgEnd - msgHead); +} + +// Main pack function - public + +int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint32_t packedMsgLen; + uint16_t packedMsgLen16; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n"); + return -1; + } + + // pack the message + if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) && + push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) && + push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, pPackMessageEnd) && + push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) && + pack_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config)) + { + // check for a valid message length + packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage); + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd)) + return -1; + + // return the packed length + return (packedMsgLen); + } + else + { + // Failed to pack the meassage + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n"); + return -1; + } + +} + + + +// Unpack routines +static uint8_t unpack_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_param_request_t *pNfapiMsg = (nfapi_pnf_param_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_pnf_param_general_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_param_general_t* value = (nfapi_pnf_param_general_t*)tlv; + + return( pull8(ppReadPackedMsg, &value->nfapi_sync_mode, end) && + pull8(ppReadPackedMsg, &value->location_mode, end) && + pull16(ppReadPackedMsg, &value->location_coordinates_length, end) && + pullarray8(ppReadPackedMsg, value->location_coordinates, NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH, value->location_coordinates_length, end) && + pull32(ppReadPackedMsg, &value->dl_config_timing, end) && + pull32(ppReadPackedMsg, &value->tx_timing, end) && + pull32(ppReadPackedMsg, &value->ul_config_timing, end) && + pull32(ppReadPackedMsg, &value->hi_dci0_timing, end) && + pull16(ppReadPackedMsg, &value->maximum_number_phys, end) && + pull16(ppReadPackedMsg, &value->maximum_total_bandwidth, end) && + pull8(ppReadPackedMsg, &value->maximum_total_number_dl_layers, end) && + pull8(ppReadPackedMsg, &value->maximum_total_number_ul_layers, end) && + pull8(ppReadPackedMsg, &value->shared_bands, end) && + pull8(ppReadPackedMsg, &value->shared_pa, end) && + pulls16(ppReadPackedMsg, &value->maximum_total_power, end) && + pullarray8(ppReadPackedMsg, value->oui, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH, end)); +} + +static uint8_t unpack_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rf_config_info_t* info = (nfapi_rf_config_info_t*)elem; + return pull16(ppReadPackedMsg, &info->rf_config_index, end); +} + +static uint8_t unpack_pnf_phy_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_info_t* phy = (nfapi_pnf_phy_info_t*)elem; + + return ( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->number_of_rfs, end) && + unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) && + pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) && + unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) && + pull16(ppReadPackedMsg, &phy->downlink_channel_bandwidth_supported, end) && + pull16(ppReadPackedMsg, &phy->uplink_channel_bandwidth_supported, end) && + pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) && + pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) && + pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) && + pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end)); +} + + +static uint8_t unpack_pnf_phy_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_t* value = (nfapi_pnf_phy_t*)tlv; + return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_info)); +} + +static uint8_t unpack_pnf_rf_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_rf_info_t* rf = (nfapi_pnf_rf_info_t*)elem; + + return( pull16(ppReadPackedMsg, &rf->rf_config_index, end) && + pull16(ppReadPackedMsg, &rf->band, end) && + pulls16(ppReadPackedMsg, &rf->maximum_transmit_power, end) && + pulls16(ppReadPackedMsg, &rf->minimum_transmit_power, end) && + pull8(ppReadPackedMsg, &rf->number_of_antennas_suppported, end) && + pull32(ppReadPackedMsg, &rf->minimum_downlink_frequency, end) && + pull32(ppReadPackedMsg, &rf->maximum_downlink_frequency, end) && + pull32(ppReadPackedMsg, &rf->minimum_uplink_frequency, end) && + pull32(ppReadPackedMsg, &rf->maximum_uplink_frequency, end)); + +} +static uint8_t unpack_pnf_rf_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_rf_t* value = (nfapi_pnf_rf_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_rfs, end) && + unpackarray(ppReadPackedMsg, value->rf, sizeof(nfapi_pnf_rf_info_t), NFAPI_MAX_PNF_RF, value->number_of_rfs, end, &unpack_pnf_rf_info)); +} + +static uint8_t unpack_pnf_phy_rel10_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel10_info_t* phy = (nfapi_pnf_phy_rel10_info_t*)elem; + + return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->transmission_mode_7_supported, end) && + pull16(ppReadPackedMsg, &phy->transmission_mode_8_supported, end) && + pull16(ppReadPackedMsg, &phy->two_antenna_ports_for_pucch, end) && + pull16(ppReadPackedMsg, &phy->transmission_mode_9_supported, end) && + pull16(ppReadPackedMsg, &phy->simultaneous_pucch_pusch, end) && + pull16(ppReadPackedMsg, &phy->four_layer_tx_with_tm3_and_tm4, end)); + + +} +static uint8_t unpack_pnf_phy_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel10_t* value = (nfapi_pnf_phy_rel10_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel10_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel10_info)); + +} + + +static uint8_t unpack_pnf_phy_rel11_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel11_info_t* phy = (nfapi_pnf_phy_rel11_info_t*)elem; + + return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->edpcch_supported, end) && + pull16(ppReadPackedMsg, &phy->multi_ack_csi_reporting, end ) && + pull16(ppReadPackedMsg, &phy->pucch_tx_diversity, end) && + pull16(ppReadPackedMsg, &phy->ul_comp_supported, end) && + pull16(ppReadPackedMsg, &phy->transmission_mode_5_supported, end)); +} + +static uint8_t unpack_pnf_phy_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel11_t* value = (nfapi_pnf_phy_rel11_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel11_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel11_info)); + +} + +static uint8_t unpack_phy_phy_rel12_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel12_info_t* phy = (nfapi_pnf_phy_rel12_info_t*)elem; + + return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->csi_subframe_set, end) && + pull16(ppReadPackedMsg, &phy->enhanced_4tx_codebook, end) && + pull16(ppReadPackedMsg, &phy->drs_supported, end) && + pull16(ppReadPackedMsg, &phy->ul_64qam_supported, end) && + pull16(ppReadPackedMsg, &phy->transmission_mode_10_supported, end) && + pull16(ppReadPackedMsg, &phy->alternative_bts_indices, end)); +} + +static uint8_t unpack_pnf_phy_rel12_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel12_t* value = (nfapi_pnf_phy_rel12_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel12_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_phy_phy_rel12_info)); + +} + +static uint8_t unpack_pnf_phy_rel13_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_info_t* phy = (nfapi_pnf_phy_rel13_info_t*)elem; + + return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->pucch_format4_supported, end) && + pull16(ppReadPackedMsg, &phy->pucch_format5_supported, end) && + pull16(ppReadPackedMsg, &phy->more_than_5_ca_support, end) && + pull16(ppReadPackedMsg, &phy->laa_supported, end) && + pull16(ppReadPackedMsg, &phy->laa_ending_in_dwpts_supported, end) && + pull16(ppReadPackedMsg, &phy->laa_starting_in_second_slot_supported, end) && + pull16(ppReadPackedMsg, &phy->beamforming_supported, end) && + pull16(ppReadPackedMsg, &phy->csi_rs_enhancement_supported, end) && + pull16(ppReadPackedMsg, &phy->drms_enhancement_supported, end) && + pull16(ppReadPackedMsg, &phy->srs_enhancement_supported, end)); +} + +static uint8_t unpack_pnf_phy_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_t* value = (nfapi_pnf_phy_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_info)); +} + +static uint8_t unpack_pnf_phy_rel13_nb_info_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_nb_iot_info_t* phy = (nfapi_pnf_phy_rel13_nb_iot_info_t*)elem; + + return( pull16(ppReadPackedMsg, &phy->phy_config_index, end) && + pull16(ppReadPackedMsg, &phy->number_of_rfs, end) && + unpackarray(ppReadPackedMsg, phy->rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rfs, end, &unpack_rf_config_info) && + pull16(ppReadPackedMsg, &phy->number_of_rf_exclusions, end) && + unpackarray(ppReadPackedMsg, phy->excluded_rf_config, sizeof(nfapi_rf_config_info_t), NFAPI_MAX_PNF_PHY_RF_CONFIG, phy->number_of_rf_exclusions, end, &unpack_rf_config_info) && + pull8(ppReadPackedMsg, &phy->number_of_dl_layers_supported, end) && + pull8(ppReadPackedMsg, &phy->number_of_ul_layers_supported, end) && + pull16(ppReadPackedMsg, &phy->maximum_3gpp_release_supported, end) && + pull8(ppReadPackedMsg, &phy->nmm_modes_supported, end)); +} + +static uint8_t unpack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rel13_nb_iot_t* value = (nfapi_pnf_phy_rel13_nb_iot_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_phys, end) && + unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_nb_info_info)); +} + + + +static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_param_response_t *pNfapiMsg = (nfapi_pnf_param_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value}, + { NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value}, + { NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, &unpack_pnf_rf_value}, + { NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, &unpack_pnf_phy_rel10_value}, + { NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, &unpack_pnf_phy_rel11_value}, + { NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, &unpack_pnf_phy_rel12_value}, + { NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, &unpack_pnf_phy_rel13_value}, + { NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, &unpack_pnf_phy_rel13_nb_iot_value}, + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_phy_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem; + + return( pull16(ppReadPackedMsg, &rf->phy_id, end) && + pull16(ppReadPackedMsg, &rf->phy_config_index, end) && + pull16(ppReadPackedMsg, &rf->rf_config_index, end)); + +} + +static uint8_t unpack_pnf_phy_rf_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_pnf_phy_rf_config_t* value = (nfapi_pnf_phy_rf_config_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_phy_rf_config_info, end) && + unpackarray(ppReadPackedMsg, value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, end, &unpack_phy_rf_config_info)); +} + +static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value}, + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension); +} + +static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} + +static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); +} + +static uint8_t unpack_pnf_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_pnf_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} + +static uint8_t unpack_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_L1_STATUS_PHY_STATE_TAG, &pNfapiMsg->l1_status.phy_state, &unpack_uint16_tlv_value}, + + { NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_bandwidth_support, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_bandwidth_support, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.dl_modulation_support, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, &pNfapiMsg->phy_capabilities.ul_modulation_support, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.phy_antenna_capability, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.release_capability, &unpack_uint16_tlv_value}, + { NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, &pNfapiMsg->phy_capabilities.mbsfn_capability, &unpack_uint16_tlv_value}, + + { NFAPI_LAA_CAPABILITY_LAA_SUPPORT_TAG, &pNfapiMsg->laa_capability.laa_support, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CAPABILITY_PD_SENSING_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.pd_sensing_lbt_support, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CAPABILITY_MULTI_CARRIER_LBT_SUPPORT_TAG, &pNfapiMsg->laa_capability.multi_carrier_lbt_support, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CAPABILITY_PARTIAL_SF_SUPPORT_TAG, &pNfapiMsg->laa_capability.partial_sf_support, &unpack_uint16_tlv_value}, + + { NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value}, + + { NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value}, + + { NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value}, + { NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value}, + { NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value}, + + { NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value}, + { NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value}, + { NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value}, + + { NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value}, + + { NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value}, + { NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value}, + + { NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value}, + + { NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value}, + + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value}, + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value}, + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value}, + + { NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value}, + { NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value}, + + { NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value}, + { NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value}, + + { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value}, + { NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value}, + + }; + + return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &pNfapiMsg->subframe_config.duplex_mode, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &pNfapiMsg->subframe_config.pcfich_power_offset, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_PB_TAG, &pNfapiMsg->subframe_config.pb, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.dl_cyclic_prefix_type, &unpack_uint16_tlv_value}, + { NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &pNfapiMsg->subframe_config.ul_cyclic_prefix_type, &unpack_uint16_tlv_value}, + + { NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.dl_channel_bandwidth, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &pNfapiMsg->rf_config.ul_channel_bandwidth, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &pNfapiMsg->rf_config.reference_signal_power, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.tx_antenna_ports, &unpack_uint16_tlv_value}, + { NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &pNfapiMsg->rf_config.rx_antenna_ports, &unpack_uint16_tlv_value}, + + { NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &pNfapiMsg->phich_config.phich_resource, &unpack_uint16_tlv_value}, + { NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &pNfapiMsg->phich_config.phich_duration, &unpack_uint16_tlv_value}, + { NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &pNfapiMsg->phich_config.phich_power_offset, &unpack_uint16_tlv_value}, + + { NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value}, + { NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers, &unpack_uint16_tlv_value}, + { NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &pNfapiMsg->sch_config.physical_cell_id, &unpack_uint16_tlv_value}, + + { NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &pNfapiMsg->prach_config.configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->prach_config.root_sequence_index, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->prach_config.zero_correlation_zone_configuration, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &pNfapiMsg->prach_config.high_speed_flag, &unpack_uint16_tlv_value}, + { NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &pNfapiMsg->prach_config.frequency_offset, &unpack_uint16_tlv_value}, + + { NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &pNfapiMsg->pusch_config.hopping_mode, &unpack_uint16_tlv_value}, + { NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &pNfapiMsg->pusch_config.hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &pNfapiMsg->pusch_config.number_of_subbands, &unpack_uint16_tlv_value}, + + { NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &pNfapiMsg->pucch_config.delta_pucch_shift, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &pNfapiMsg->pucch_config.n_cqi_rb, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &pNfapiMsg->pucch_config.n_an_cs, &unpack_uint16_tlv_value}, + { NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &pNfapiMsg->pucch_config.n1_pucch_an, &unpack_uint16_tlv_value}, + + { NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &pNfapiMsg->srs_config.bandwidth_configuration, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &pNfapiMsg->srs_config.max_up_pts, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &pNfapiMsg->srs_config.srs_subframe_configuration, &unpack_uint16_tlv_value}, + { NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission, &unpack_uint16_tlv_value}, + + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping, &unpack_uint16_tlv_value}, + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &pNfapiMsg->uplink_reference_signal_config.group_assignment, &unpack_uint16_tlv_value}, + { NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms, &unpack_uint16_tlv_value}, + + + { NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_pdsch, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &pNfapiMsg->laa_config.ed_threshold_lbt_drs, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &pNfapiMsg->laa_config.pd_threshold, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &pNfapiMsg->laa_config.multi_carrier_type, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &pNfapiMsg->laa_config.multi_carrier_tx, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &pNfapiMsg->laa_config.multi_carrier_freeze, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_antenna_ports_drs, &unpack_uint16_tlv_value}, + { NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &pNfapiMsg->laa_config.tx_power_drs, &unpack_uint16_tlv_value}, + + { NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &pNfapiMsg->emtc_config.pbch_repetitions_enable_r13, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &pNfapiMsg->emtc_config.prach_catm_root_sequence_index, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &pNfapiMsg->emtc_config.prach_catm_high_speed_flag, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea, &unpack_uint16_tlv_value}, + { NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb, &unpack_uint16_tlv_value}, + + { NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &pNfapiMsg->tdd_frame_structure_config.subframe_assignment, &unpack_uint16_tlv_value}, + { NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns, &unpack_uint16_tlv_value}, + + { NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &pNfapiMsg->l23_config.data_report_mode, &unpack_uint16_tlv_value}, + { NFAPI_L23_CONFIG_SFNSF_TAG, &pNfapiMsg->l23_config.sfnsf, &unpack_uint16_tlv_value}, + + { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.dl_ue_per_sf, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &pNfapiMsg->nfapi_config.ul_ue_per_sf, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_RF_BANDS_TAG, &pNfapiMsg->nfapi_config.rf_bands, &unpack_rf_bands_value}, + { NFAPI_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value}, + { NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &pNfapiMsg->nfapi_config.max_transmit_power, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_EARFCN_TAG, &pNfapiMsg->nfapi_config.earfcn, &unpack_uint16_tlv_value}, + { NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_umts_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &pNfapiMsg->nfapi_config.nmm_lte_frequency_bands, &unpack_nmm_frequency_bands_value}, + { NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported, &unpack_uint8_tlv_value}, + + }; + + return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); +} + +static uint8_t unpack_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} + +static uint8_t unpack_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_stop_response_t *pNfapiMsg = (nfapi_stop_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} +static uint8_t unpack_measurement_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_measurement_request_t *pNfapiMsg = (nfapi_measurement_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, &pNfapiMsg->dl_rs_tx_power, &unpack_uint16_tlv_value}, + { NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, &pNfapiMsg->received_interference_power, &unpack_uint16_tlv_value}, + { NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, &pNfapiMsg->thermal_noise_power, &unpack_uint16_tlv_value}, + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_received_interference_power_measurement_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_received_interference_power_measurement_t* value = (nfapi_received_interference_power_measurement_t*)tlv; + + return ( pull16(ppReadPackedMsg, &value->number_of_resource_blocks, end) && + pullarrays16(ppReadPackedMsg, value->received_interference_power, NFAPI_MAX_RECEIVED_INTERFERENCE_POWER_RESULTS, value->number_of_resource_blocks, end)); +} + + +static uint8_t unpack_measurement_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_measurement_response_t *pNfapiMsg = (nfapi_measurement_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, &pNfapiMsg->dl_rs_tx_power_measurement, &unpack_int16_tlv_value}, + { NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG, &pNfapiMsg->received_interference_power_measurement, &unpack_received_interference_power_measurement_value}, + { NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, &pNfapiMsg->thermal_noise_power_measurement, &unpack_int16_tlv_value}, + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +// unpack length check + +static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_PNF_PARAM_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t)) + retLen = sizeof(nfapi_pnf_param_request_t); + break; + + case NFAPI_PNF_PARAM_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_pnf_param_response_t)) + retLen = sizeof(nfapi_pnf_param_response_t); + break; + + case NFAPI_PNF_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_pnf_config_request_t)) + retLen = sizeof(nfapi_pnf_config_request_t); + break; + + case NFAPI_PNF_CONFIG_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_pnf_config_response_t)) + retLen = sizeof(nfapi_pnf_config_response_t); + break; + + case NFAPI_PNF_START_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_pnf_start_request_t)) + retLen = sizeof(nfapi_pnf_start_request_t); + break; + + case NFAPI_PNF_START_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_pnf_start_response_t)) + retLen = sizeof(nfapi_pnf_start_response_t); + break; + + case NFAPI_PNF_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_pnf_stop_request_t)) + retLen = sizeof(nfapi_pnf_stop_request_t); + break; + + case NFAPI_PNF_STOP_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_pnf_stop_response_t)) + retLen = sizeof(nfapi_pnf_stop_response_t); + break; + + case NFAPI_PARAM_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_param_request_t)) + retLen = sizeof(nfapi_param_request_t); + break; + + case NFAPI_PARAM_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_param_response_t)) + retLen = sizeof(nfapi_param_response_t); + break; + + case NFAPI_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_config_request_t)) + retLen = sizeof(nfapi_config_request_t); + break; + + case NFAPI_CONFIG_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_config_response_t)) + retLen = sizeof(nfapi_config_response_t); + break; + + case NFAPI_START_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_start_request_t)) + retLen = sizeof(nfapi_start_request_t); + break; + + case NFAPI_START_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_start_response_t)) + retLen = sizeof(nfapi_start_response_t); + break; + + case NFAPI_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_stop_request_t)) + retLen = sizeof(nfapi_stop_request_t); + break; + + case NFAPI_STOP_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_stop_response_t)) + retLen = sizeof(nfapi_stop_response_t); + break; + + case NFAPI_MEASUREMENT_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_measurement_request_t)) + retLen = sizeof(nfapi_measurement_request_t); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_measurement_response_t)) + retLen = sizeof(nfapi_measurement_response_t); + break; + + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId); + break; + } + + return retLen; +} + + +// Main unpack functions - public + +int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // process the header + return ( pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->spare, end) ); + +} + +int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) + { + // failed to read the header + return -1; + } + + int result = -1; + + + if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) + { + // the unpack buffer is not big enough for the struct + return -1; + } + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_PNF_PARAM_REQUEST: + result = unpack_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_PARAM_RESPONSE: + result = unpack_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_CONFIG_REQUEST: + result = unpack_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_CONFIG_RESPONSE: + result = unpack_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_START_REQUEST: + result = unpack_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_START_RESPONSE: + result = unpack_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_STOP_REQUEST: + result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PNF_STOP_RESPONSE: + result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PARAM_REQUEST: + result = unpack_param_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_PARAM_RESPONSE: + result = unpack_param_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_CONFIG_REQUEST: + result = unpack_config_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_CONFIG_RESPONSE: + result = unpack_config_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_START_REQUEST: + result = unpack_start_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_START_RESPONSE: + result = unpack_start_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_STOP_REQUEST: + result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_STOP_RESPONSE: + result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_MEASUREMENT_REQUEST: + result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + default: + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p4_p5_vendor_extension) + { + result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + return result; +} + diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c new file mode 100644 index 0000000000..3754fe379f --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -0,0 +1,6185 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, void* user_data); +extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedMsg, void* user_data); + +uint32_t nfapi_calculate_checksum(uint8_t* buffer, uint16_t len) +{ + uint32_t chksum = 0; + // calcaulte upto the checksum + chksum = crc32(chksum, buffer, 8); + + // skip the checksum + uint8_t zeros[4] = {0, 0, 0, 0}; + chksum = crc32(chksum, zeros, 4); + + // continu with the rest of the mesage + chksum = crc32(chksum, &buffer[NFAPI_P7_HEADER_LENGTH], len - NFAPI_P7_HEADER_LENGTH); + + // return the inverse + return ~(chksum); +} + +int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len) +{ + uint32_t checksum = nfapi_calculate_checksum(buffer, len); + + uint8_t* p_write = &buffer[8]; + return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1); +} + +int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp) +{ + uint8_t* p_write = &buffer[12]; + return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1); +} + +uint32_t nfapi_p7_calculate_checksum(uint8_t* buffer, uint32_t len) +{ + return nfapi_calculate_checksum(buffer, len); +} + +void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config) +{ + if(size == 0) + return 0; + + if(config && config->allocate) + { + return (config->allocate)(size); + } + else + { + return calloc(1, size); + } +} + +void nfapi_p7_deallocate(void* ptr, nfapi_p7_codec_config_t* config) +{ + if(ptr == NULL) + return; + + if(config && config->deallocate) + { + return (config->deallocate)(ptr); + } + else + { + return free(ptr); + } +} +// Pack routines + + +static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel8_t* value = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format); + + return ( push8(value->dci_format, ppWritePackedMsg, end) && + push8(value->cce_idx, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs_1, ppWritePackedMsg, end) && + push8(value->redundancy_version_1, ppWritePackedMsg, end) && + push8(value->new_data_indicator_1, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->mcs_2, ppWritePackedMsg, end) && + push8(value->redundancy_version_2, ppWritePackedMsg, end) && + push8(value->new_data_indicator_2, ppWritePackedMsg, end) && + push8(value->harq_process, ppWritePackedMsg, end) && + push8(value->tpmi, ppWritePackedMsg, end) && + push8(value->pmi, ppWritePackedMsg, end) && + push8(value->precoding_information, ppWritePackedMsg, end) && + push8(value->tpc, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end) && + push8(value->transport_block_size_index, ppWritePackedMsg, end) && + push8(value->downlink_power_offset, ppWritePackedMsg, end) && + push8(value->allocate_prach_flag, ppWritePackedMsg, end) && + push8(value->preamble_index, ppWritePackedMsg, end) && + push8(value->prach_mask_index, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel9_t* value = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; + + return( push8(value->mcch_flag, ppWritePackedMsg, end) && + push8(value->mcch_change_notification, ppWritePackedMsg, end) && + push8(value->scrambling_identity, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel10_t* value = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; + + return ( push8(value->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && + push8(value->carrier_indicator, ppWritePackedMsg, end) && + push8(value->srs_flag, ppWritePackedMsg, end) && + push8(value->srs_request, ppWritePackedMsg, end) && + push8(value->antenna_ports_scrambling_and_layers, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(value->n_dl_rb, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel11_t* value = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; + + return ( push8(value->harq_ack_resource_offset, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_quasi_co_location_indicator, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel12_t* value = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; + + return ( push8(value->primary_cell_type, ppWritePackedMsg, end) && + push8(value->ul_dl_configuration_flag, ppWritePackedMsg, end) && + push8(value->number_ul_dl_configurations, ppWritePackedMsg, end) && + pusharray8(value->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, value->number_ul_dl_configurations, ppWritePackedMsg, end)); +} + +static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + if (!( push8(value->num_prb_per_subband, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->num_antennas, ppWritePackedMsg, end))) + return 0; + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); + + if(!(push8(subband_info->subband_index, ppWritePackedMsg, end) && + push8(subband_info->scheduled_ues, ppWritePackedMsg, end))) + return 0; + + + uint8_t antenna_idx = 0; + uint8_t scheduled_ue_idx = 0; + + for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) + { + for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) + { + if(!push16(subband_info->precoding_value[antenna_idx][scheduled_ue_idx], ppWritePackedMsg, end)) + return 0; + } + } + + } + + + return 1; + +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel13_t* value = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; + + return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) && + push8(value->laa_end_partial_sf_configuration, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end) && + push8(value->codebook_size_determination, ppWritePackedMsg, end) && + push8(value->drms_table_flag, ppWritePackedMsg, end) && + push8(value->tpm_struct_flag, ppWritePackedMsg, end) && + (value->tpm_struct_flag == 1 ? pack_tpm_value(&(value->tpm), ppWritePackedMsg, end) : 1)); +} + +static uint8_t pack_dl_config_bch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_bch_pdu_rel8_t* value = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__); + + return( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_mch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_mch_pdu_rel8_t* value = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->mbsfn_area_id, ppWritePackedMsg, end)); +} + +static uint8_t pack_bf_vector_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_bf_vector_t* bf = (nfapi_bf_vector_t*)elem; + + return ( push8(bf->subband_index, ppWritePackedMsg, end) && + push8(bf->num_antennas, ppWritePackedMsg, end) && + pusharray16(bf->bf_value, NFAPI_MAX_NUM_ANTENNAS, bf->num_antennas, ppWritePackedMsg, end)); + + +} +static uint8_t pack_dl_config_dlsch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel8_t* value = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->transport_blocks, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->transmission_scheme, ppWritePackedMsg, end) && + push8(value->number_of_layers, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + pusharray8(value->codebook_index, NFAPI_MAX_NUM_SUBBANDS, value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->ue_category_capacity, ppWritePackedMsg, end) && + push8(value->pa, ppWritePackedMsg, end) && + push8(value->delta_power_offset_index, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end) && + push8(value->nprb, ppWritePackedMsg, end) && + push8(value->transmission_mode, ppWritePackedMsg, end) && + push8(value->num_bf_prb_per_subband, ppWritePackedMsg, end) && + push8(value->num_bf_vector, ppWritePackedMsg, end) && + packarray(value->bf_vector, sizeof(nfapi_bf_vector_t), NFAPI_MAX_BF_VECTORS, value->num_bf_vector, ppWritePackedMsg, end, &pack_bf_vector_info)); + +} +static uint8_t pack_dl_config_dlsch_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel9_t* value = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; + return ( push8(value->nscid, ppWritePackedMsg, end) ); +} +static uint8_t pack_dl_config_dlsch_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel10_t* value = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; + + return ( push8(value->csi_rs_flag, ppWritePackedMsg, end) && + push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && + push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && + pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && + push8(value->pdsch_start, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel11_t* value = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; + + return( push8(value->drms_config_flag, ppWritePackedMsg, end) && + push16(value->drms_scrambling, ppWritePackedMsg, end) && + push8(value->csi_config_flag, ppWritePackedMsg, end) && + push16(value->csi_scrambling, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_flag, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_atenna_ports, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_freq_shift, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel12_t* value = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; + + return( push8(value->altcqi_table_r12, ppWritePackedMsg, end) && + push8(value->maxlayers, ppWritePackedMsg, end) && + push8(value->n_dl_harq, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel13_t* value = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; + + return( push8(value->dwpts_symbols, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end) && + push8(value->ue_type, ppWritePackedMsg, end) && + push8(value->pdsch_payload_type, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && + push8(value->drms_table_flag, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_pch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel8_t* value = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; + + return( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->p_rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->number_of_transport_blocks, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->transmission_scheme, ppWritePackedMsg, end) && + push8(value->number_of_layers, ppWritePackedMsg, end) && + push8(value->codebook_index, ppWritePackedMsg, end) && + push8(value->ue_category_capacity, ppWritePackedMsg, end) && + push8(value->pa, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->nprb, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_pch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel13_t* value = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; + + return ( push8(value->ue_mode, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_prs_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_prs_pdu_rel9_t* value = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; + + return( push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->prs_bandwidth, ppWritePackedMsg, end) && + push8(value->prs_cyclic_prefix_type, ppWritePackedMsg, end) && + push8(value->prs_muting, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_csi_rs_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel10_t* value = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; + + return( push8(value->csi_rs_antenna_port_count_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end) && + pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_csi_rs_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel13_t* value = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; + + if(!(push8(value->csi_rs_class, ppWritePackedMsg, end) && + push8(value->cdm_type, ppWritePackedMsg, end) && + push8(value->num_bf_vector, ppWritePackedMsg, end))) + { + return 0; + } + + uint16_t i; + for(i = 0; i < value->num_bf_vector; ++i) + { + if(!(push8(value->bf_vector[i].csi_rs_resource_index, ppWritePackedMsg, end) && + pusharray16(value->bf_vector[i].bf_value, NFAPI_MAX_ANTENNA_PORT_COUNT, NFAPI_MAX_ANTENNA_PORT_COUNT, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} +static uint8_t pack_bf_vector(nfapi_bf_vector_t* vector, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(vector->subband_index, ppWritePackedMsg, end) && + push8(vector->num_antennas, ppWritePackedMsg, end) && + pusharray16(vector->bf_value, NFAPI_MAX_NUM_ANTENNAS, vector->num_antennas, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_epdcch_parameters_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel11_t* value = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; + + return ( push8(value->epdcch_resource_assignment_flag, ppWritePackedMsg, end) && + push16(value->epdcch_id, ppWritePackedMsg, end) && + push8(value->epdcch_start_symbol, ppWritePackedMsg, end) && + push8(value->epdcch_num_prb, ppWritePackedMsg, end) && + pusharray8(value->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, value->epdcch_num_prb, ppWritePackedMsg, end) && + pack_bf_vector(&value->bf_vector, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_epdcch_parameters_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel13_t* value = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; + + return (push8(value->dwpts_symbols, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_mpdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_mpdcch_pdu_rel13_t* value = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; + + return ( push8(value->mpdcch_narrow_band, ppWritePackedMsg, end) && + push8(value->number_of_prb_pairs, ppWritePackedMsg, end) && + push8(value->resource_block_assignment, ppWritePackedMsg, end) && + push8(value->mpdcch_tansmission_type, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->ecce_index, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->ce_mode, ppWritePackedMsg, end) && + push16(value->drms_scrambling_init, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->dci_format, ppWritePackedMsg, end) && + push16(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->pdsch_reptition_levels, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->new_data_indicator, ppWritePackedMsg, end) && + push8(value->harq_process, ppWritePackedMsg, end) && + push8(value->tpmi_length, ppWritePackedMsg, end) && + push8(value->tpmi, ppWritePackedMsg, end) && + push8(value->pmi_flag, ppWritePackedMsg, end) && + push8(value->pmi, ppWritePackedMsg, end) && + push8(value->harq_resource_offset, ppWritePackedMsg, end) && + push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push8(value->tpc, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index_length, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index, ppWritePackedMsg, end) && + push8(value->allocate_prach_flag, ppWritePackedMsg, end) && + push8(value->preamble_index, ppWritePackedMsg, end) && + push8(value->prach_mask_index, ppWritePackedMsg, end) && + push8(value->starting_ce_level, ppWritePackedMsg, end) && + push8(value->srs_request, ppWritePackedMsg, end) && + push8(value->antenna_ports_and_scrambling_identity_flag, ppWritePackedMsg, end) && + push8(value->antenna_ports_and_scrambling_identity, ppWritePackedMsg, end) && + push8(value->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(value->paging_direct_indication_differentiation_flag, ppWritePackedMsg, end) && + push8(value->direct_indication, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(value->number_of_tx_antenna_ports, ppWritePackedMsg, end) && + pusharray16(value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, ppWritePackedMsg, end)); +} + + +static uint8_t pack_dl_config_nbch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_nbch_pdu_rel13_t* value = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->hyper_sfn_2_lsbs, ppWritePackedMsg, end)); +} + + +static uint8_t pack_dl_config_npdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_npdcch_pdu_rel13_t* value = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push8(value->ncce_index, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && + push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && + push8(value->dci_format, ppWritePackedMsg, end) && + push8(value->scheduling_delay, ppWritePackedMsg, end) && + push8(value->resource_assignment, ppWritePackedMsg, end) && + push8(value->repetition_number, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->new_data_indicator, ppWritePackedMsg, end) && + push8(value->harq_ack_resource, ppWritePackedMsg, end) && + push8(value->npdcch_order_indication, ppWritePackedMsg, end) && + push8(value->starting_number_of_nprach_repetitions, ppWritePackedMsg, end) && + push8(value->subcarrier_indication_of_nprach, ppWritePackedMsg, end) && + push8(value->paging_direct_indication_differentation_flag, ppWritePackedMsg, end) && + push8(value->direct_indication, ppWritePackedMsg, end) && + push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_ndlsch_pdu_rel13_t* value = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push16(value->resource_assignment, ppWritePackedMsg, end) && + push16(value->repetition_number, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push8(value->number_of_subframes_for_resource_assignment, ppWritePackedMsg, end) && + push8(value->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && + push16(value->sf_idx, ppWritePackedMsg, end) && + push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich); + + if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) && + push8(value->number_dci, ppWritePackedMsg, end) && + push16(value->number_pdu, ppWritePackedMsg, end) && + push8(value->number_pdsch_rnti, ppWritePackedMsg, end) && + push16(value->transmission_power_pcfich, ppWritePackedMsg, end))) + { + return 0; + } + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_pdu; + for(; i < total_number_of_pdus; ++i) + { + nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__); + + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value))) + { + return 0; + } + } + break; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__); + + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_mch_pdu_rel8_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_prs_pdu_rel9_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel11_value) & + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_mpdcch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_nbch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_npdcch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_ndlsch_pdu_rel13_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + +static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; + + //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) && + //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + { + uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value); + uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + + if (!x || !y || !z) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z); + } + + return x && y && z; + } +} + +static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end) +{ + nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; + + return( push32(ulsch_pdu_rel8->handle, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel8->size, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->modulation_type, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->new_data_indication, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->redundancy_version, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->harq_process_number, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->ul_tx_mode, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->current_tx_nb, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->n_srs, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ulsch_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; + + return (push8(ulsch_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && + push32(ulsch_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->transport_blocks, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->transmission_scheme, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->number_of_layers, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->codebook_index, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->disable_sequence_hopping_flag, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; + + return (push8(ulsch_pdu_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel11->npusch_identity, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel11->dmrs_config_flag, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel11->ndmrs_csh_identity, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; + + return (push8(ulsch_pdu_rel13->ue_type, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu* ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &ulsch_pdu->ulsch_pdu_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &ulsch_pdu->ulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel13_value)); +} + +static uint8_t pack_ul_config_request_cqi_ri_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; + + return ( push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->ri_size, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->delta_offset_cqi, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->delta_offset_ri, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; + + if(!(push8(cqi_ri_info_rel9->report_type, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->delta_offset_cqi, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->delta_offset_ri, ppWritePackedMsg, end))) + { + return 0; + } + + switch(cqi_ri_info_rel9->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(!(push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, ppWritePackedMsg, end))) + { + return 0; + } + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t i; + for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t j; + for(j = 0; j < 8; ++j) + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0) + return 0; + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); + } + break; + }; + + return 1; +} + +static uint8_t pack_ul_config_request_cqi_ri_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; + + switch(cqi_ri_info_rel13->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(push16(cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, ppWritePackedMsg, end) == 0) + return 0; + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + // No parameters + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel13->report_type ); + } + break; + }; + + return 1; +} + +static uint8_t pack_ul_config_request_cqi_ri_information(nfapi_ul_config_cqi_ri_information* cqi_ri_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return (pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &cqi_ri_info->cqi_ri_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &cqi_ri_info->cqi_ri_information_rel9, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel9_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &cqi_ri_info->cqi_ri_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel13_value)); + +} + +static uint8_t pack_ul_config_request_init_tx_params_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; + + return (push8(init_tx_params_rel8->n_srs_initial, ppWritePackedMsg, end) && + push8(init_tx_params_rel8->initial_number_of_resource_blocks, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_initial_transmission_parameters(nfapi_ul_config_initial_transmission_parameters* init_tx_params, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return pack_tlv(NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &init_tx_params->initial_transmission_parameters_rel8, ppWritePackedMsg, end, &pack_ul_config_request_init_tx_params_rel8_value); +} + +static uint8_t pack_ul_config_request_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; + + return (push8(harq_info_rel10->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel10->delta_offset_harq, ppWritePackedMsg, end) && + push8(harq_info_rel10->ack_nack_mode, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; + + return (push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && + push8(harq_info_rel13->delta_offset_harq_2, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_harq_information(nfapi_ul_config_ulsch_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &harq_info->harq_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel13_value)); +} + +static uint8_t pack_ul_config_request_ue_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; + + return ( push32(ue_info_rel8->handle, ppWritePackedMsg, end) && + push16(ue_info_rel8->rnti, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ue_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; + + return ( push8(ue_info_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && + push16(ue_info_rel11->npusch_identity, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ue_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; + + return ( push8(ue_info_rel13->ue_type, ppWritePackedMsg, end) && + push8(ue_info_rel13->empty_symbols, ppWritePackedMsg, end) && + push16(ue_info_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && + push16(ue_info_rel13->repetition_number, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ue_information(nfapi_ul_config_ue_information* ue_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &ue_info->ue_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &ue_info->ue_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &ue_info->ue_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel13_value)); +} + +static uint8_t pack_ul_config_request_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_rel10_tdd = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; + + return ( push8(harq_info_rel10_tdd->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel10_tdd->ack_nack_mode, ppWritePackedMsg, end) && + push8(harq_info_rel10_tdd->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_0, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_1, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_2, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_rel8_fdd = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; + + return ( push16(harq_info_rel8_fdd->n_pucch_1_0, ppWritePackedMsg, end) && + push8(harq_info_rel8_fdd->harq_size, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_rel9_fdd = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; + + return ( push8(harq_info_rel9_fdd->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel9_fdd->ack_nack_mode, ppWritePackedMsg, end) && + push8(harq_info_rel9_fdd->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_0, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_1, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_2, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; + + return ( push8(harq_info_rel11->num_ant_ports, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_0, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_1, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_2, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; + + return ( push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && + push8(harq_info_rel13->starting_prb, ppWritePackedMsg, end) && + push8(harq_info_rel13->n_prb, ppWritePackedMsg, end) && + push8(harq_info_rel13->cdm_index, ppWritePackedMsg, end) && + push8(harq_info_rel13->n_srs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_harq_information(nfapi_ul_config_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &harq_info->harq_information_rel10_tdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel10_tdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &harq_info->harq_information_rel8_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel8_fdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &harq_info->harq_information_rel9_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel9_fdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &harq_info->harq_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel13_value)); + +} + +static uint8_t pack_ul_config_request_cqi_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; + + return ( push16(cqi_info_rel8->pucch_index, ppWritePackedMsg, end) && + push8(cqi_info_rel8->dl_cqi_pmi_size, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_cqi_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; + + return ( push8(cqi_info_rel10->number_of_pucch_resource, ppWritePackedMsg, end) && + push16(cqi_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_cqi_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; + + return ( push8(cqi_info_rel13->csi_mode, ppWritePackedMsg, end) && + push16(cqi_info_rel13->dl_cqi_pmi_size_2, ppWritePackedMsg, end) && + push8(cqi_info_rel13->starting_prb, ppWritePackedMsg, end) && + push8(cqi_info_rel13->n_prb, ppWritePackedMsg, end) && + push8(cqi_info_rel13->cdm_index, ppWritePackedMsg, end) && + push8(cqi_info_rel13->n_srs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_cqi_information(nfapi_ul_config_cqi_information* cqi_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &cqi_info->cqi_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &cqi_info->cqi_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &cqi_info->cqi_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel13_value)); + +} + +static uint8_t pack_ul_config_request_sr_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; + return push16(sr_info_rel8->pucch_index, ppWritePackedMsg, end); +} +static uint8_t pack_ul_config_request_sr_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; + + return ( push8(sr_info_rel10->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(sr_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_sr_information(nfapi_ul_config_sr_information* sr_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &sr_info->sr_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &sr_info->sr_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel10_value)); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; + + return (push32(srs_pdu_rel8->handle, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->size, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->srs_bandwidth, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->frequency_domain_position, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->srs_hopping_bandwidth, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->transmission_comb, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->i_srs, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->sounding_reference_cyclic_shift, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; + return push8(srs_pdu_rel10->antenna_port, ppWritePackedMsg, end); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; + + return ( push8(srs_pdu_rel13->number_of_combs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_nb_harq_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_pdu_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; + + return ( push8(nb_harq_pdu_rel13->harq_ack_resource, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; + + return (push8(nulsch_pdu_rel13->nulsch_format, ppWritePackedMsg, end) && + push32(nulsch_pdu_rel13->handle, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->size, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->n_srs, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->sf_idx, ppWritePackedMsg, end) && + pack_ul_config_request_ue_information(&(nulsch_pdu_rel13->ue_information), ppWritePackedMsg, end) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, ppWritePackedMsg, end, &pack_ul_config_request_nb_harq_rel13_value)); +} +static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; + + return ( push8(nrach_pdu_rel13->nprach_config_0, ppWritePackedMsg, end) && + push8(nrach_pdu_rel13->nprach_config_1, ppWritePackedMsg, end) && + push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end)); + +} + +static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; + + if(!(push8(value->number_of_pdus, ppWritePackedMsg, end) && + push8(value->rach_prach_frequency_resources, ppWritePackedMsg, end) && + push8(value->srs_present, ppWritePackedMsg, end))) + return 0; + + uint16_t i = 0; + for(i = 0; i < value->number_of_pdus; ++i) + { + nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + { + if(!pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_pdu), ppWritePackedMsg, end)) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_harq_pdu.harq_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_harq_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && + pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_cqi_harq_ri_pdu.harq_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_pdu.cqi_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_sr_pdu.sr_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_harq_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_cqi_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_pdu.sr_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_harq_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_cqi_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &pdu->srs_pdu.srs_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &pdu->srs_pdu.srs_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &pdu->srs_pdu.srs_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->harq_buffer_pdu.ue_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_csi_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->ulsch_uci_csi_pdu.csi_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->ulsch_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->ulsch_csi_uci_harq_pdu.csi_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->ulsch_csi_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &pdu->nulsch_pdu.nulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nulsch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &pdu->nrach_pdu.nrach_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nrach_pdu_rel13_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + + } + return 1; +} + +static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, ppWritePackedMsg, end, &pack_ul_config_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)) ; +} + +static uint8_t pack_hi_dci0_hi_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; + + return ( push8(hi_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->hi_value, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->i_phich, ppWritePackedMsg, end) && + push16(hi_pdu_rel8->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_hi_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; + + return ( push8(hi_pdu_rel10->flag_tb2, ppWritePackedMsg, end) && + push8(hi_pdu_rel10->hi_value_2, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; + + return ( push8(dci_pdu_rel8->dci_format, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cce_index, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->aggregation_level, ppWritePackedMsg, end) && + push16(dci_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->number_of_resource_block, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->mcs_1, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->new_data_indication_1, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->ue_tx_antenna_seleciton, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->tpc, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cqi_csi_request, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->ul_index, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->dl_assignment_index, ppWritePackedMsg, end) && + push32(dci_pdu_rel8->tpc_bitmap, ppWritePackedMsg, end) && + push16(dci_pdu_rel8->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; + + return ( push8(dci_pdu_rel10->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->carrier_indicator, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->size_of_cqi_csi_feild, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->srs_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->srs_request, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->resource_allocation_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && + push32(dci_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->mcs_2, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->new_data_indication_2, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->number_of_antenna_ports, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->tpmi, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->n_ul_rb, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel12_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; + + return ( push8(dci_pdu_rel12->pscch_resource, ppWritePackedMsg, end) && + push8(dci_pdu_rel12->time_resource_pattern, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_mpdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* mpdcch_dci_pdu_rel13 = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; + + return ( push8(mpdcch_dci_pdu_rel13->mpdcch_narrowband, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_prb_pairs, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->resource_block_assignment, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->mpdcch_transmission_type, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ecce_index, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->aggreagation_level, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->rnti_type, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ce_mode, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->drms_scrambling_init, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->transmission_power, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dci_format, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->resource_block_start, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->pusch_repetition_levels, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->frequency_hopping_flag, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->harq_process, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->redudency_version, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->tpc, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->csi_request, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ul_inex, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dai_presence_flag, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dl_assignment_index, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->srs_request, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push32(mpdcch_dci_pdu_rel13->tcp_bitmap, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->total_dci_length_include_padding, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end) && + pusharray16(mpdcch_dci_pdu_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end)); + +} + +static uint8_t pack_hi_dci0_npdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* npdcch_dci_pdu_rel13 = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; + + return ( push8(npdcch_dci_pdu_rel13->ncce_index, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->aggregation_level, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && + push16(npdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->scheduling_delay, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->new_data_indicator, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end)); +} + + +static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; + + if(!(push16(value->sfnsf, ppWritePackedMsg, end) && + push8(value->number_of_dci, ppWritePackedMsg, end) && + push8(value->number_of_hi, ppWritePackedMsg, end))) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_dci + value->number_of_hi; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_HI_DCI0_HI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_hi_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_hi_rel10_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, ppWritePackedMsg, end, pack_hi_dci0_dci_rel12_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, ppWritePackedMsg, end, pack_dl_config_epdcch_parameters_rel11_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_mpdcch_dci_rel13_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_npdcch_dci_rel13_pdu_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + + } + + return 1; +} + +static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, ppWritePackedMsg, end, &pack_hi_dci0_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_tx_request_body_t* value = (nfapi_tx_request_body_t*)tlv; + + if(push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_tx_request_pdu_t* pdu = &(value->tx_pdu_list[i]); + + if(!(push16(pdu->pdu_length, ppWritePackedMsg, end) && + push16(pdu->pdu_index, ppWritePackedMsg, end))) + return 0; + + uint8_t j; + for(j = 0; j < pdu->num_segments; ++j) + { + // Use -1 as it is unbounded + // DJP - does not handle -1 + // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) + int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end); + + if (0 && pdu->segments[j].segment_length == 3) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, + pdu->segments[j].segment_data[0], + pdu->segments[j].segment_data[1], + pdu->segments[j].segment_data[2] + ); + } + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret); + + if (push_ret == 0) + { + return 0; + } + } + } + + return 1; +} + +static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; + + int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z); + + return x && y && z; +} + +static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) ); +} + +static uint8_t unpack_rx_ue_information_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; + + return ( pull32(ppReadPackedMsg, &value->handle, end) && + pull16(ppReadPackedMsg, &value->rnti, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_bundling(nfapi_harq_indication_tdd_harq_data_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) && + push8(data->value_1, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_multiplexing(nfapi_harq_indication_tdd_harq_data_multiplexing_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) && + push8(data->value_1, ppWritePackedMsg, end) && + push8(data->value_2, ppWritePackedMsg, end) && + push8(data->value_3, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_special_bundling(nfapi_harq_indication_tdd_harq_data_special_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) ); +} + +static uint8_t pack_harq_indication_tdd_harq_data(nfapi_harq_indication_tdd_harq_data_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) ); +} + +static uint8_t pack_harq_indication_tdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel8_t* harq_indication_tdd_rel8 = (nfapi_harq_indication_tdd_rel8_t*)tlv; + + if(!(push8(harq_indication_tdd_rel8->mode, ppWritePackedMsg, end) && + push8(harq_indication_tdd_rel8->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t result = 0; + switch(harq_indication_tdd_rel8->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data_bundling(&harq_indication_tdd_rel8->harq_data.bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data_multiplexing(&harq_indication_tdd_rel8->harq_data.multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel8->harq_data.special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = 1; + break; + default: + // err.... + break; + } + + return result; + +} + +static uint8_t pack_harq_indication_tdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel9_t* harq_indication_tdd_rel9 = (nfapi_harq_indication_tdd_rel9_t*)tlv; + + if(!(push8(harq_indication_tdd_rel9->mode, ppWritePackedMsg, end) && + push8(harq_indication_tdd_rel9->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t idx; + for(idx = 0; idx < harq_indication_tdd_rel9->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + + switch(harq_indication_tdd_rel9->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data(&(harq_indication_tdd_rel9->harq_data[idx].bundling), ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel9->harq_data[idx].special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].channel_selection, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].format_3, ppWritePackedMsg, end); + break; + default: + // err.... + break; + } + + if(result == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_harq_indication_tdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel13_t* harq_indication_tdd_rel13 = (nfapi_harq_indication_tdd_rel13_t*)tlv; + + if(!(push8(harq_indication_tdd_rel13->mode, ppWritePackedMsg, end) && + push16(harq_indication_tdd_rel13->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t idx; + for(idx = 0; idx < harq_indication_tdd_rel13->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(harq_indication_tdd_rel13->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel13->harq_data[idx].special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].channel_selection, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_3, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_4, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_5, ppWritePackedMsg, end); + break; + default: + // err.... + break; + } + + if(result == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_harq_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel8_t* harq_indication_fdd_rel8 = (nfapi_harq_indication_fdd_rel8_t*)tlv; + + return ( push8(harq_indication_fdd_rel8->harq_tb1, ppWritePackedMsg, end) && + push8(harq_indication_fdd_rel8->harq_tb2, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel9_t* harq_indication_fdd_rel9 = (nfapi_harq_indication_fdd_rel9_t*)tlv; + + return ( push8(harq_indication_fdd_rel9->mode, ppWritePackedMsg, end) && + push8(harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end) && + pusharray8(harq_indication_fdd_rel9->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel13_t* harq_indication_fdd_rel13 = (nfapi_harq_indication_fdd_rel13_t*)tlv; + + return ( push8(harq_indication_fdd_rel13->mode, ppWritePackedMsg, end) && + push16(harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end) && + pusharray8(harq_indication_fdd_rel13->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_cqi_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; + + return ( push8(value->ul_cqi, ppWritePackedMsg, end) && + push8(value->channel, ppWritePackedMsg, end)); + +} + +static uint8_t pack_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; + + if(push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_harqs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, ppWritePackedMsg, end, pack_harq_indication_tdd_rel8_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, ppWritePackedMsg, end, pack_harq_indication_tdd_rel9_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, ppWritePackedMsg, end, pack_harq_indication_tdd_rel13_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, ppWritePackedMsg, end, pack_harq_indication_fdd_rel8_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, ppWritePackedMsg, end, pack_harq_indication_fdd_rel9_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_harq_indication_fdd_rel13_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, ppWritePackedMsg, end, pack_harq_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_crc_indication_rel8_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_crc_indication_rel8_t* crc_indication_rel8 = (nfapi_crc_indication_rel8_t*)tlv; + + return ( push8(crc_indication_rel8->crc_flag, ppWritePackedMsg, end) ); +} + +static uint8_t pack_crc_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; + + if(push16(value->number_of_crcs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_crcs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, ppWritePackedMsg, end, pack_crc_indication_rel8_body))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + return 1; +} + +static uint8_t pack_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, ppWritePackedMsg, end, &pack_crc_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} +static uint8_t pack_rx_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->offset, ppWritePackedMsg, end) && + push8(value->ul_cqi, ppWritePackedMsg, end) && + push16(value->timing_advance, ppWritePackedMsg, end)); +} +static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; + + return ( push16(value->timing_advance_r9, ppWritePackedMsg, end)); +} + +static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; + + //printf("RX ULSCH BODY\n"); + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + // need to calculate the data offset's. + uint16_t i = 0; + uint16_t offset = 2; // taking into account the number_of_pdus + uint16_t total_number_of_pdus = value->number_of_pdus; + //printf("ULSCH:pdus:%d\n", total_number_of_pdus); + + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) + { + //printf("NFAPI_RX_UE_INFORMATION_TAG\n"); + offset += 4 + 6; + } + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + //printf("NFAPI_RX_INDICATION_REL8_TAG\n"); + offset += 4 + 7; + } + + if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) + { + //printf("NFAPI_RX_INDICATION_REL9_TAG\n"); + offset += 4 + 2; + } + } + + // Now update the structure to include the offset + for(i =0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + if(pdu->rx_indication_rel8.offset == 1) + { + pdu->rx_indication_rel8.offset = offset; + offset += pdu->rx_indication_rel8.length; + } + } + } + + // Write out the pdu + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_RX_INDICATION_REL8_TAG, &pdu->rx_indication_rel8, ppWritePackedMsg, end, pack_rx_indication_rel8_value) && + pack_tlv(NFAPI_RX_INDICATION_REL9_TAG, &pdu->rx_indication_rel9, ppWritePackedMsg, end, pack_rx_indication_rel9_value))) + return 0; + } + + // Write out the pdu data + for(i = 0; i < total_number_of_pdus; ++i) + { + uint16_t length = 0; + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + length = pdu->rx_indication_rel8.length; + } + + if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0) + return 0; + } + return 1; +} + + +static uint8_t pack_rx_ulsch_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, ppWritePackedMsg, end, pack_rx_ulsch_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_preamble_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel8_t* preamble_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; + + return ( push16(preamble_rel8->rnti, ppWritePackedMsg, end) && + push8(preamble_rel8->preamble, ppWritePackedMsg, end) && + push16(preamble_rel8->timing_advance, ppWritePackedMsg, end)); +} +static uint8_t pack_preamble_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel9_t* preamble_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; + + return ( push16(preamble_rel9->timing_advance_r9, ppWritePackedMsg, end) ); +} +static uint8_t pack_preamble_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel13_t* preamble_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; + + return ( push8(preamble_rel13->rach_resource_type, ppWritePackedMsg, end) ); +} + +static uint8_t pack_rach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; + + if( push16(value->number_of_preambles, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_preambles; + for(; i < total_number_of_pdus; ++i) + { + nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, ppWritePackedMsg, end, pack_preamble_pdu_rel8_value) && + pack_tlv(NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, ppWritePackedMsg, end, pack_preamble_pdu_rel9_value) && + pack_tlv(NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, ppWritePackedMsg, end, pack_preamble_pdu_rel13_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, ppWritePackedMsg, end, pack_rach_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel8_t* srs_pdu_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; + + return ( push16(srs_pdu_rel8->doppler_estimation, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->timing_advance, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->rb_start, ppWritePackedMsg, end) && + pusharray8(srs_pdu_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end)); +} + +static uint8_t pack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel9_t* srs_pdu_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; + + return ( push16(srs_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end) ); +} + +static uint8_t pack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_ttd_rel10_t* srs_pdu_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; + + return ( push8(srs_pdu_rel10->uppts_symbol, ppWritePackedMsg, end) ); + +} + +static uint8_t pack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel11_t* srs_pdu_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; + + return ( push16(srs_pdu_rel11->ul_rtoa, ppWritePackedMsg, end) ) ; +} + +static uint8_t pack_tdd_channel_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; + + if(!(push8(value->num_prb_per_subband, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->num_atennas, ppWritePackedMsg, end))) + return 0; + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + if(!(push8(value->subands[idx].subband_index, ppWritePackedMsg, end) && + pusharray16(value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +static uint8_t pack_srs_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t*)tlv; + + if( push8(value->number_of_ues, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_ues; + for(; i < total_number_of_pdus; ++i) + { + nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, &pack_rx_ue_information_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel8_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel9_value) && + pack_tlv(NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, ppWritePackedMsg, end, &pack_srs_indication_tdd_rel10_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel11_value) && + pack_tlv(NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, ppWritePackedMsg, end, &pack_tdd_channel_measurement_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, ppWritePackedMsg, end, &pack_srs_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_sr_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; + + if(push16(value->number_of_srs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_srs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + return 1; +} + +static uint8_t pack_sr_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, ppWritePackedMsg, end, &pack_sr_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_cqi_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; + + return ( push16(cqi_pdu_rel8->length, ppWritePackedMsg, end) && + push16(cqi_pdu_rel8->data_offset, ppWritePackedMsg, end) && + push8(cqi_pdu_rel8->ul_cqi, ppWritePackedMsg, end) && + push8(cqi_pdu_rel8->ri, ppWritePackedMsg, end) && + push16(cqi_pdu_rel8->timing_advance, ppWritePackedMsg, end)); +} + +static uint8_t pack_cqi_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; + + return ( push16(cqi_pdu_rel9->length, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->data_offset, ppWritePackedMsg, end) && + push8(cqi_pdu_rel9->ul_cqi, ppWritePackedMsg, end) && + push8(cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && + pusharray8(cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->timing_advance, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end)); +} + +static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; + + if( push16(value->number_of_cqis, ppWritePackedMsg, end) == 0) + return 0; + + // need to calculate the data offset's. This very bittle due the hardcoding + // of the sizes. can not use the sizeof as we have an array for the Rel9 + // info + uint16_t i = 0; + uint16_t offset = 2; // taking into account the number_of_cqis + uint16_t total_number_of_pdus = value->number_of_cqis; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + offset += 2; // for the instance length + + if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) + { + offset += 4 + 6; // sizeof(nfapi_rx_ue_information) - sizeof(nfapi_tl_t) + } + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + offset += 4 + 8; + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + offset += 4 + 10 + pdu->cqi_indication_rel9.number_of_cc_reported; + } + + if(pdu->ul_cqi_information.tl.tag == NFAPI_UL_CQI_INFORMATION_TAG) + { + offset += 4 + 2; + } + } + + // Now update the structure to include the offset + for(i =0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + if(pdu->cqi_indication_rel8.data_offset == 1) + { + pdu->cqi_indication_rel8.data_offset = offset; + offset += pdu->cqi_indication_rel8.length; + } + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + if(pdu->cqi_indication_rel9.data_offset == 1) + { + pdu->cqi_indication_rel9.data_offset = offset; + offset += pdu->cqi_indication_rel9.length; + } + } + + } + + // Write out the cqi information + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end ,pack_rx_ue_information_value) && + pack_tlv(NFAPI_CQI_INDICATION_REL8_TAG, &pdu->cqi_indication_rel8, ppWritePackedMsg, end, pack_cqi_indication_rel8_value) && + pack_tlv(NFAPI_CQI_INDICATION_REL9_TAG, &pdu->cqi_indication_rel9, ppWritePackedMsg, end, pack_cqi_indication_rel9_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + + } + + // Write out the cqi raw data + for(i = 0; i < total_number_of_pdus; ++i) + { + uint16_t length = 0; + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + length = pdu->cqi_indication_rel8.length; + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + length = pdu->cqi_indication_rel9.length; + } + + if( pusharray8(value->cqi_raw_pdu_list[i].pdu, NFAPI_CQI_RAW_MAX_LEN, length, ppWritePackedMsg, end) == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_cqi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, ppWritePackedMsg, end, pack_cqi_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->mp_cca, ppWritePackedMsg, end) && + push32(value->n_cca, ppWritePackedMsg, end) && + push32(value->offset, ppWritePackedMsg, end) && + push32(value->lte_txop_sf, ppWritePackedMsg, end) && + push16(value->txop_sfn_sf_end, ppWritePackedMsg, end) && + push32(value->lbt_mode, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->offset, ppWritePackedMsg, end) && + push16(value->sfn_sf_end, ppWritePackedMsg, end) && + push32(value->lbt_mode, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); + + if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if( push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_req_pdu_rel13_value) == 0) + return 0; + } + break; + case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: + { + if(pack_tlv(NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_req_pdu_rel13_value) == 0) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + +static uint8_t pack_lbt_pdsch_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->result, ppWritePackedMsg, end) && + push32(value->lte_txop_symbols, ppWritePackedMsg, end) && + push32(value->initial_partial_sf, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_drs_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->result, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, ppWritePackedMsg, end, &pack_lbt_dl_config_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lbt_dl_config_indication_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); + + if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_rsp_pdu_rel13_value) == 0) + return 0; + } + break; + case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_rsp_pdu_rel13_value) == 0) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + +static uint8_t pack_lbt_dl_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, ppWritePackedMsg, end, &pack_lbt_dl_config_indication_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nb_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_fdd_rel13_t* nb_harq_indication_fdd_rel13 = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; + + return ( push8(nb_harq_indication_fdd_rel13->harq_tb1, ppWritePackedMsg, end) ); +} + +static uint8_t pack_nb_harq_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; + + if( push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_harqs = value->number_of_harqs; + for(; i < total_number_of_harqs; ++i) + { + nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_nb_harq_indication_fdd_rel13_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + + +static uint8_t pack_nb_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, ppWritePackedMsg, end, &pack_nb_harq_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nrach_indication_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_pdu_rel13_t* nrach_indication_fdd_rel13 = (nfapi_nrach_indication_pdu_rel13_t*)tlv; + + return ( push16(nrach_indication_fdd_rel13->rnti, ppWritePackedMsg, end) && + push8(nrach_indication_fdd_rel13->initial_sc, ppWritePackedMsg, end) && + push16(nrach_indication_fdd_rel13->timing_advance, ppWritePackedMsg, end) && + push8(nrach_indication_fdd_rel13->nrach_ce_level, ppWritePackedMsg, end)); +} + + +static uint8_t pack_nrach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; + + if( push8(value->number_of_initial_scs_detected, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_initial_scs_detected = value->number_of_initial_scs_detected; + for(; i < total_number_of_initial_scs_detected; ++i) + { + nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); + + //uint8_t* instance_length_p = *ppWritePackedMsg; + //if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + // return 0; + + if(!(pack_tlv(NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, ppWritePackedMsg, end, pack_nrach_indication_rel13_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + //uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + //push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, ppWritePackedMsg, end, &pack_nrach_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; + + return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->delta_sfn_sf, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; + + return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + push32(pNfapiMsg->t2, ppWritePackedMsg, end) && + push32(pNfapiMsg->t3, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; + + return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) && + push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) && + push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->tx_request_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->ul_config_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->hi_dci0_jitter, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_config_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_request_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_config_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->hi_dci0_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_config_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_request_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_config_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->hi_dci0_earliest_arrival, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + + +// Main pack function - public + +int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config) +{ + nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *end = pPackedBuf + packedBufLen; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); + return -1; + } + + // process the header + if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && + push16(pMessageHeader->message_id, &pWritePackedMessage, end) && + push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) && + push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) && + push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) && + push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); + return -1; + } + + if (pMessageHeader->message_id != NFAPI_TIMING_INFO) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp); + } + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) + { + case NFAPI_DL_CONFIG_REQUEST: + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__); + result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UL_CONFIG_REQUEST: + result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_HI_DCI0_REQUEST: + result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_TX_REQUEST: + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); + result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_HARQ_INDICATION: + result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CRC_INDICATION: + result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_ULSCH_INDICATION: + //printf("RX ULSCH\n"); + result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RACH_INDICATION: + result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SRS_INDICATION: + result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_SR_INDICATION: + result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_CQI_INDICATION: + result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_INDICATION: + result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NB_HARQ_INDICATION: + result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NRACH_INDICATION: + result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_DL_NODE_SYNC: + result = pack_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UL_NODE_SYNC: + result = pack_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_TIMING_INFO: + result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config); + break; + + default: + { + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->pack_p7_vendor_extension) + { + result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + } + break; + } + + if(result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); + return -1; + } + + // check for a valid message length + uintptr_t msgHead = (uintptr_t)pPackedBuf; + uintptr_t msgEnd = (uintptr_t)pWritePackedMessage; + uint32_t packedMsgLen = msgEnd - msgHead; + uint16_t packedMsgLen16; + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + pMessageHeader->message_length = packedMsgLen16; + + if(!push16(packedMsgLen16, &pPackedLengthField, end)) + return -1; + + if(1) + { + //quick test + if(pMessageHeader->message_length != packedMsgLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id); + } + } + + return (packedMsgLen); +} + + + +// Unpack routines + +static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel8_t* dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->dci_format, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->cce_idx, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->aggregation_level, end) && + pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->harq_process, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpmi, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->pmi, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->precoding_information, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpc, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_assignment_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->ngap, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_size_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_power_offset, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->allocate_prach_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->preamble_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->prach_mask_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti_type, end) && + pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->transmission_power, end)); + +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel9_t* dci_dl_pdu_rel9 = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_change_notification, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->scrambling_identity, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel10_t* dci_dl_pdu_rel10 = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->cross_carrier_scheduling_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->carrier_indicator, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_request, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->antenna_ports_scrambling_and_layers, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->n_dl_rb, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel11_t* dci_dl_pdu_rel11 = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->harq_ack_resource_offset, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->pdsch_re_mapping_quasi_co_location_indicator, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel12_t* dci_dl_pdu_rel12 = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->primary_cell_type, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->ul_dl_configuration_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->number_ul_dl_configurations, end) && + pullarray8(ppReadPackedMsg, dci_dl_pdu_rel12->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, dci_dl_pdu_rel12->number_ul_dl_configurations, end)); +} + +static uint8_t unpack_tpm_value(uint8_t **ppReadPackedMsg, nfapi_dl_config_dci_dl_tpm_t *value, uint8_t *end) +{ + if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && + pull8(ppReadPackedMsg, &value->number_of_subbands, end) && + pull8(ppReadPackedMsg, &value->num_antennas, end))) + return 0; + + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); + + if(!(pull8(ppReadPackedMsg, &subband_info->subband_index, end) && + pull8(ppReadPackedMsg, &subband_info->scheduled_ues, end))) + return 0; + + uint8_t antenna_idx = 0; + uint8_t scheduled_ue_idx = 0; + + for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) + { + for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) + { + if(!pull16(ppReadPackedMsg, &(subband_info->precoding_value[antenna_idx][scheduled_ue_idx]), end)) + return 0; + } + } + + } + + + return 1; + +} + + +static uint8_t unpack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel13_t* dci_dl_pdu_rel13 = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; + + // If the length is greater than 5 then the TPM struct flag and possiably the TPM structure have been + // added + uint8_t tpm_struct_flag_present = dci_dl_pdu_rel13->tl.length > 5; + dci_dl_pdu_rel13->tpm_struct_flag = 0; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_configuration, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->initial_lbt_sf, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->codebook_size_determination, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->drms_table_flag, end) && + ( (tpm_struct_flag_present == 1) ? pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm_struct_flag, end) : 1) && + ( (tpm_struct_flag_present == 1 && dci_dl_pdu_rel13->tpm_struct_flag == 1) ? unpack_tpm_value(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm, end) : 1)); + +} + +static uint8_t unpack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_bch_pdu_rel8_t* bch_pdu_rel8 = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &bch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &bch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &bch_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_mch_pdu_rel8_t* mch_pdu_rel8 = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &mch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &mch_pdu_rel8->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &mch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &mch_pdu_rel8->modulation, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->transmission_power, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->mbsfn_area_id, end)); +} + +static uint8_t unpack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel8_t* dlsch_pdu_rel8 = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; + + if (!(pull16(ppReadPackedMsg, &dlsch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &dlsch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->modulation, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_blocks, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_scheme, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_layers, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_subbands, end) && + pullarray8(ppReadPackedMsg, dlsch_pdu_rel8->codebook_index, NFAPI_MAX_NUM_SUBBANDS, dlsch_pdu_rel8->number_of_subbands, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ue_category_capacity, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->pa, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->delta_power_offset_index, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ngap, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->nprb, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_mode, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_prb_per_subband, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_vector, end))) + return 0; + + uint16_t j = 0; + for(j = 0; j < dlsch_pdu_rel8->num_bf_vector; ++j) + { + if(!(pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].subband_index, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].num_antennas, end) && + pullarray16(ppReadPackedMsg, dlsch_pdu_rel8->bf_vector[j].bf_value, NFAPI_MAX_NUM_ANTENNAS, dlsch_pdu_rel8->bf_vector[j].num_antennas, end))) + return 0; + } + return 1; +} +static uint8_t unpack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel9_t* dlsch_pdu_rel9 = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel9->nscid, end) ); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel10_t* dlsch_pdu_rel10 = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_resource_config_r10, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && + pullarray8(ppReadPackedMsg, dlsch_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->pdsch_start, end)) ; +} +static uint8_t unpack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel11_t* dlsch_pdu_rel11 = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel11->drms_config_flag, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel11->drms_scrambling, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->csi_config_flag, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel11->csi_scrambling, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_atenna_ports, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_freq_shift, end)); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel12_t* dlsch_pdu_rel12 = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel12->altcqi_table_r12, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel12->maxlayers, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel12->n_dl_harq, end)); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel13_t* dlsch_pdu_rel13 = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel13->dwpts_symbols, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->initial_lbt_sf, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->ue_type, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->pdsch_payload_type, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel13->initial_transmission_sf_io, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->drms_table_flag, end)); +} + +static uint8_t unpack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel8_t* pch_pdu_rel8 = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &pch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel8->p_rnti, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &pch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->mcs, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_transport_blocks, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->transmission_scheme, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_layers, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->codebook_index, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->ue_category_capacity, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->pa, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel8->transmission_power, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->nprb, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->ngap, end)); +} +static uint8_t unpack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel13_t* pch_pdu_rel13 = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &pch_pdu_rel13->ue_mode, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel13->initial_transmission_sf_io, end)); +} + +static uint8_t unpack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_prs_pdu_rel9_t* prs_pdu_rel9 = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; + + return ( pull16(ppReadPackedMsg, &prs_pdu_rel9->transmission_power, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_bandwidth, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_cyclic_prefix_type, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_muting, end)); +} + +static uint8_t unpack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel10_t* csi_rs_pdu_rel10 = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; + + return ( pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_antenna_port_count_r10, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_resource_config_r10, end) && + pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->transmission_power, end) && + pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end) && + pullarray8(ppReadPackedMsg, csi_rs_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end)); +} + +static uint8_t unpack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel13_t* csi_rs_pdu_rel13 = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; + + if (!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->csi_rs_class, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->cdm_type, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->num_bf_vector, end))) + return 0; + + + uint16_t idx =0; + for(idx = 0; idx < csi_rs_pdu_rel13->num_bf_vector; ++idx) + { + if(!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].csi_rs_resource_index, end))) + return 0; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : HOW TO DECODE BF VALUE \n"); + //pullarray16(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].bf_vector, ??); + } + return 1; +} + +static uint8_t unpack_dl_config_epdcch_params_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel11_t* epdcch_params_rel11 = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_resource_assignment_flag, end) && + pull16(ppReadPackedMsg, &epdcch_params_rel11->epdcch_id, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_start_symbol, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_num_prb, end) && + pullarray8(ppReadPackedMsg, epdcch_params_rel11->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, epdcch_params_rel11->epdcch_num_prb, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.subband_index, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.num_antennas, end) && + pullarray16(ppReadPackedMsg, epdcch_params_rel11->bf_vector.bf_value, NFAPI_MAX_NUM_ANTENNAS, epdcch_params_rel11->bf_vector.num_antennas, end)); +} + +static uint8_t unpack_dl_config_epdcch_params_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel13_t* epdcch_params_rel13 = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &epdcch_params_rel13->dwpts_symbols, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel13->initial_lbt_sf, end)); +} + +static uint8_t unpack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_mpdcch_pdu_rel13_t* mpdcch_params_rel13 = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; + + + return ( pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_narrow_band, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_prb_pairs, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_assignment, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_tansmission_type, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->ecce_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->aggregation_level, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->rnti, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->ce_mode, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->drms_scrambling_init, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->initial_transmission_sf_io, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->transmission_power, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_format, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_coding, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->mcs, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pdsch_reptition_levels, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->redundancy_version, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->new_data_indicator, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_process, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi_length, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_resource_offset, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_subframe_repetition_number, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpc, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index_length, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->allocate_prach_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->preamble_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->prach_mask_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->starting_ce_level, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->srs_request, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->paging_direct_indication_differentiation_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->direct_indication, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_tx_antenna_ports, end) && + pullarray16(ppReadPackedMsg, mpdcch_params_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_params_rel13->number_of_tx_antenna_ports, end)); +} + + +static uint8_t unpack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_nbch_pdu_rel13_t* nbch_params_rel13 = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &nbch_params_rel13->length, end) && + pull16(ppReadPackedMsg, &nbch_params_rel13->pdu_index, end) && + pull16(ppReadPackedMsg, &nbch_params_rel13->transmission_power, end) && + pull16(ppReadPackedMsg, &nbch_params_rel13->hyper_sfn_2_lsbs, end)); +} + +static uint8_t unpack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_npdcch_pdu_rel13_t* npdcch_params_rel13 = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &npdcch_params_rel13->length, end) && + pull16(ppReadPackedMsg, &npdcch_params_rel13->pdu_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->ncce_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->aggregation_level, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &npdcch_params_rel13->rnti, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->scrambling_reinitialization_batch_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_format, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->scheduling_delay, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->resource_assignment, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->mcs, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->new_data_indicator, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->harq_ack_resource, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->npdcch_order_indication, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->starting_number_of_nprach_repetitions, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->subcarrier_indication_of_nprach, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->paging_direct_indication_differentation_flag, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->direct_indication, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_subframe_repetition_number, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->total_dci_length_including_padding, end)); +} + +static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_ndlsch_pdu_rel13_t* ndlsch_params_rel13 = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &ndlsch_params_rel13->length, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->pdu_index, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->rnti, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->resource_assignment, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->modulation, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->number_of_subframes_for_resource_assignment, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end)); +} + + +static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_pdcch_ofdm_symbols, end) && + pull8(ppReadPackedMsg, &value->number_dci, end) && + pull16(ppReadPackedMsg, &value->number_pdu, end) && + pull8(ppReadPackedMsg, &value->number_pdsch_rnti, end) && + pull16(ppReadPackedMsg, &value->transmission_power_pcfich, end))) + return 0; + + if(value->number_pdu > NFAPI_DL_CONFIG_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_pdu, NFAPI_DL_CONFIG_MAX_PDU); + return 0; + } + + if(value->number_pdu) + { + value->dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_dl_config_request_pdu_t) * value->number_pdu, config); + if(value->dl_config_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu); + return 0; + } + } + else + { + value->dl_config_pdu_list = 0; + } + + uint16_t i; + uint16_t total_number_of_pdus = value->number_pdu; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end of beyond buffer end + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, &unpack_dl_config_bch_pdu_rel8_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, &unpack_dl_config_mch_pdu_rel8_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, &unpack_dl_config_dlsch_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, &unpack_dl_config_dlsch_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, &unpack_dl_config_dlsch_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, &unpack_dl_config_dlsch_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, &unpack_dl_config_dlsch_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, &unpack_dl_config_dlsch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, &unpack_dl_config_pch_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, &unpack_dl_config_pch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, &unpack_dl_config_prs_pdu_rel9_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, &unpack_dl_config_csi_rs_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, &unpack_dl_config_csi_rs_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, &unpack_dl_config_epdcch_params_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, &unpack_dl_config_epdcch_params_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, &unpack_dl_config_mpdcch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, &unpack_dl_config_nbch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, &unpack_dl_config_npdcch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + + } + break; + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, &unpack_dl_config_ndlsch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + + } + break; + default: + // Need to log an error + break; + } + } + + return 1; +} + +static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, &unpack_dl_config_request_body_value}, + }; + + return ( pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel8->size, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->modulation_type, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_bits, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->new_data_indication, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->harq_process_number, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->ul_tx_mode, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end )); +} +static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &ulsch_pdu_rel10->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &ulsch_pdu_rel10->resource_block_coding, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transport_blocks, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transmission_scheme, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->number_of_layers, end) & + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->codebook_index, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->disable_sequence_hopping_flag, end)); +} +static uint8_t unpack_ul_config_ulsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; + + return ( pull8(ppReadPackedMsg, &ulsch_pdu_rel11->virtual_cell_id_enabled_flag, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel11->npusch_identity, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel11->dmrs_config_flag, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel11->ndmrs_csh_identity, end)); +} +static uint8_t unpack_ul_config_ulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &ulsch_pdu_rel13->ue_type, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->total_number_of_repetitions, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->repetition_number, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->initial_transmission_sf_io, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, end)); +} +static uint8_t unpack_ul_config_cqi_ri_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->ri_size, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_cqi, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_ri, end)); +} + +static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->report_type, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_cqi, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_ri, end))) + return 0; + + switch(cqi_ri_info_rel9->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, end))) + return 0; + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, end) ==0) + return 0; + + uint8_t i; + for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0) + return 0; + + uint8_t j; + for(j = 0; j < 8; ++j) + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0) + return 0; + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); + return 0; + } + break; + }; + return 1; +} + +// NOTE : This function is a little unconventional as we uese the side to +// determine the report type +static uint8_t unpack_ul_config_cqi_ri_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; + if(cqi_ri_info_rel13->tl.length == 0) + { + cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_APERIODIC; + } + else + { + cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_PERIODIC; + if(pull16(ppReadPackedMsg, &cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, end) == 0) + return 0; + } + return 1; +} +static uint8_t unpack_ul_config_cqi_init_tx_params_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &init_tx_params_rel8->n_srs_initial, end) && + pull8(ppReadPackedMsg, &init_tx_params_rel8->initial_number_of_resource_blocks, end)); +} +static uint8_t unpack_ul_config_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_rel10->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_rel10->delta_offset_harq, end) && + pull8(ppReadPackedMsg, &harq_info_rel10->ack_nack_mode, end)); +} + +static uint8_t unpack_ul_config_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->delta_offset_harq_2, end)); +} + +static uint8_t unpack_ul_config_ue_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &ue_info_rel8->handle, end) && + pull16(ppReadPackedMsg, &ue_info_rel8->rnti, end)); +} +static uint8_t unpack_ul_config_ue_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &ue_info_rel11->virtual_cell_id_enabled_flag, end) && + pull16(ppReadPackedMsg, &ue_info_rel11->npusch_identity, end)); +} +static uint8_t unpack_ul_config_ue_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &ue_info_rel13->ue_type, end) && + pull8(ppReadPackedMsg, &ue_info_rel13->empty_symbols, end) && + pull16(ppReadPackedMsg, &ue_info_rel13->total_number_of_repetitions, end) && + pull16(ppReadPackedMsg, &ue_info_rel13->repetition_number, end)); +} + +static uint8_t unpack_ul_config_cqi_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &cqi_info_rel8->pucch_index, end) && + pull8(ppReadPackedMsg, &cqi_info_rel8->dl_cqi_pmi_size, end)); +} +static uint8_t unpack_ul_config_cqi_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_info_rel10->number_of_pucch_resource, end) && + pull16(ppReadPackedMsg, &cqi_info_rel10->pucch_index_p1, end)); +} +static uint8_t unpack_ul_config_cqi_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_info_rel13->csi_mode, end) && + pull16(ppReadPackedMsg, &cqi_info_rel13->dl_cqi_pmi_size_2, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->starting_prb, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->n_prb, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->cdm_index, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->n_srs, end)); +} + +static uint8_t unpack_ul_config_sr_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &sr_info_rel8->pucch_index, end)); +} + +static uint8_t unpack_ul_config_sr_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &sr_info_rel10->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &sr_info_rel10->pucch_index_p1, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_tdd_rel10 = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_tdd_rel10->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_tdd_rel10->ack_nack_mode, end) && + pull8(ppReadPackedMsg, &harq_info_tdd_rel10->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_0, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_1, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_2, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_fdd_rel8 = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_fdd_rel8->n_pucch_1_0, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel8->harq_size, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_fdd_rel9 = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_fdd_rel9->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel9->ack_nack_mode, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel9->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_0, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_1, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_2, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_rel11->num_ant_ports, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_0, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_1, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_2, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->starting_prb, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->n_prb, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->cdm_index, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->n_srs, end)); +} + + +static uint8_t unpack_ul_config_srs_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &srs_pdu_rel8->handle, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->size, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_bandwidth, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->frequency_domain_position, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_hopping_bandwidth, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->transmission_comb, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->i_srs, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->sounding_reference_cyclic_shift, end)); +} + +static uint8_t unpack_ul_config_srs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; + return pull8(ppReadPackedMsg, &srs_pdu_rel10->antenna_port, end); +} + +static uint8_t unpack_ul_config_srs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &srs_pdu_rel13->number_of_combs, end)); +} + +static uint8_t unpack_ul_nb_harq_info_rel13_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_info_fdd_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &nb_harq_info_fdd_rel13->harq_ack_resource, end)); +} + +static uint8_t unpack_ul_config_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &nulsch_pdu_rel13->nulsch_format, end) && + pull32(ppReadPackedMsg, &nulsch_pdu_rel13->handle, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->size, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->rnti, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->subcarrier_indication, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->resource_assignment, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->mcs, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->redudancy_version, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->new_data_indication, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->n_srs, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->sf_idx, end))) + return 0; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, + { NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, &unpack_ul_nb_harq_info_rel13_fdd_value}, + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, 0, 0); +} + +static uint8_t unpack_ul_config_nrach_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_0, end) && + pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_1, end) && + pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_2, end)); +} + + +static uint8_t unpack_ul_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + #define UL_CONFIG_ULSCH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &_pdu.ulsch_pdu_rel8, &unpack_ul_config_ulsch_pdu_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &_pdu.ulsch_pdu_rel10, &unpack_ul_config_ulsch_pdu_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &_pdu.ulsch_pdu_rel11, &unpack_ul_config_ulsch_pdu_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &_pdu.ulsch_pdu_rel13, &unpack_ul_config_ulsch_pdu_rel13_value}, + + #define UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &_pdu.cqi_ri_information_rel8, &unpack_ul_config_cqi_ri_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &_pdu.cqi_ri_information_rel9, &unpack_ul_config_cqi_ri_info_rel9_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &_pdu.cqi_ri_information_rel13, &unpack_ul_config_cqi_ri_info_rel13_value}, + + #define UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &_pdu.harq_information_rel10, &unpack_ul_config_ulsch_harq_info_rel10_value},\ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_ulsch_harq_info_rel13_value}, + + #define UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &_pdu.initial_transmission_parameters_rel8, &unpack_ul_config_cqi_init_tx_params_rel8_value}, + + #define UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &_pdu.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &_pdu.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &_pdu.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, + + #define UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &_pdu.cqi_information_rel8, &unpack_ul_config_cqi_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &_pdu.cqi_information_rel10, &unpack_ul_config_cqi_info_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &_pdu.cqi_information_rel13, &unpack_ul_config_cqi_info_rel13_value}, + + #define UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &_pdu.sr_information_rel8, &unpack_ul_config_sr_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &_pdu.sr_information_rel10, &unpack_ul_config_sr_info_rel10_value}, + + #define UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &_pdu.harq_information_rel10_tdd, &unpack_ul_config_harq_info_rel10_tdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &_pdu.harq_information_rel8_fdd, &unpack_ul_config_harq_info_rel8_fdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &_pdu.harq_information_rel9_fdd, &unpack_ul_config_harq_info_rel9_fdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &_pdu.harq_information_rel11, &unpack_ul_config_harq_info_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_harq_info_rel13_value}, + + #define UL_CONFIG_SRS_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &_pdu.srs_pdu_rel8, &unpack_ul_config_srs_pdu_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &_pdu.srs_pdu_rel10, &unpack_ul_config_srs_pdu_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &_pdu.srs_pdu_rel13, &unpack_ul_config_srs_pdu_rel13_value}, + + #define UL_CONFIG_NULSCH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &_pdu.nulsch_pdu_rel13, &unpack_ul_config_nulsch_pdu_rel13_value}, + + #define UL_CONFIG_NRACH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &_pdu.nrach_pdu_rel13, &unpack_ul_config_nrach_pdu_rel13_value}, + + + nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_of_pdus, end) && + pull8(ppReadPackedMsg, &value->rach_prach_frequency_resources, end) && + pull8(ppReadPackedMsg, &value->srs_present, end))) + return 0; + + if(value->number_of_pdus > NFAPI_UL_CONFIG_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of ul config pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_UL_CONFIG_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_ul_config_request_pdu_t) * value->number_of_pdus, config); + + if(value->ul_config_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate ul config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->ul_config_pdu_list = 0; + } + + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end is past buffer end + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.ulsch_pdu) + UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.cqi_ri_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_harq_pdu.ulsch_pdu) + UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_harq_pdu.harq_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_harq_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu) + UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information) + UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.harq_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.cqi_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_pdu.ue_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_pdu.sr_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_harq_pdu.ue_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.ue_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.sr_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.cqi_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.cqi_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.sr_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.cqi_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.sr_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_SRS_PDU_UNPACK_FNS(pdu->srs_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->harq_buffer_pdu.ue_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.ulsch_pdu) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.csi_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.ulsch_pdu) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.csi_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_NULSCH_PDU_UNPACK_FNS(pdu->nulsch_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_NRACH_PDU_UNPACK_FNS(pdu->nrach_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + } + } + return 1; +} + + +static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, &unpack_ul_config_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; + + return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->hi_value, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->i_phich, end) && + pull16(ppReadPackedMsg, &hi_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_hi_dci0_hi_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &hi_pdu_rel10->flag_tb2, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel10->hi_value_2, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_pdu_rel8->dci_format, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cce_index, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->aggregation_level, end) && + pull16(ppReadPackedMsg, &dci_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->number_of_resource_block, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->mcs_1, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_bits, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->new_data_indication_1, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->ue_tx_antenna_seleciton, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->tpc, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cqi_csi_request, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->ul_index, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->dl_assignment_index, end) && + pull32(ppReadPackedMsg, &dci_pdu_rel8->tpc_bitmap, end) && + pull16(ppReadPackedMsg, &dci_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_pdu_rel10->cross_carrier_scheduling_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->carrier_indicator, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->size_of_cqi_csi_feild, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_request, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &dci_pdu_rel10->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->mcs_2, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->new_data_indication_2, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->number_of_antenna_ports, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->tpmi, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->n_ul_rb, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dci_pdu_rel12->pscch_resource, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel12->time_resource_pattern, end)); +} + +static uint8_t unpack_hi_dci0_mpdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mpdcch_narrowband, end) && + pull8(ppReadPackedMsg, &value->number_of_prb_pairs, end) && + pull8(ppReadPackedMsg, &value->resource_block_assignment, end) && + pull8(ppReadPackedMsg, &value->mpdcch_transmission_type, end) && + pull8(ppReadPackedMsg, &value->start_symbol, end) && + pull8(ppReadPackedMsg, &value->ecce_index, end) && + pull8(ppReadPackedMsg, &value->aggreagation_level, end) && + pull8(ppReadPackedMsg, &value->rnti_type, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->ce_mode, end) && + pull16(ppReadPackedMsg, &value->drms_scrambling_init, end) && + pull16(ppReadPackedMsg, &value->initial_transmission_sf_io, end) && + pull16(ppReadPackedMsg, &value->transmission_power, end) && + pull8(ppReadPackedMsg, &value->dci_format, end) && + pull8(ppReadPackedMsg, &value->resource_block_start, end) && + pull8(ppReadPackedMsg, &value->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &value->mcs, end) && + pull8(ppReadPackedMsg, &value->pusch_repetition_levels, end) && + pull8(ppReadPackedMsg, &value->frequency_hopping_flag, end) && + pull8(ppReadPackedMsg, &value->new_data_indication, end) && + pull8(ppReadPackedMsg, &value->harq_process, end) && + pull8(ppReadPackedMsg, &value->redudency_version, end) && + pull8(ppReadPackedMsg, &value->tpc, end) && + pull8(ppReadPackedMsg, &value->csi_request, end) && + pull8(ppReadPackedMsg, &value->ul_inex, end) && + pull8(ppReadPackedMsg, &value->dai_presence_flag, end) && + pull8(ppReadPackedMsg, &value->dl_assignment_index, end) && + pull8(ppReadPackedMsg, &value->srs_request, end) && + pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end) && + pull32(ppReadPackedMsg, &value->tcp_bitmap, end) && + pull8(ppReadPackedMsg, &value->total_dci_length_include_padding, end) && + pull8(ppReadPackedMsg, &value->number_of_tx_antenna_ports, end) && + pullarray16(ppReadPackedMsg, value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, end)); +} + +static uint8_t unpack_hi_dci0_npdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->ncce_index, end) && + pull8(ppReadPackedMsg, &value->aggregation_level, end) && + pull8(ppReadPackedMsg, &value->start_symbol, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->scrambling_reinitialization_batch_index, end) && + pull8(ppReadPackedMsg, &value->nrs_antenna_ports_assumed_by_the_ue, end) && + pull8(ppReadPackedMsg, &value->subcarrier_indication, end) && + pull8(ppReadPackedMsg, &value->resource_assignment, end) && + pull8(ppReadPackedMsg, &value->scheduling_delay, end) && + pull8(ppReadPackedMsg, &value->mcs, end) && + pull8(ppReadPackedMsg, &value->redudancy_version, end) && + pull8(ppReadPackedMsg, &value->repetition_number, end) && + pull8(ppReadPackedMsg, &value->new_data_indicator, end) && + pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end)); +} + +static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &value->sfnsf, end) && + pull8(ppReadPackedMsg, &value->number_of_dci, end) && + pull8(ppReadPackedMsg, &value->number_of_hi, end))) + return 0; + + uint8_t totalNumPdus = value->number_of_hi + value->number_of_dci; + + if(totalNumPdus > NFAPI_HI_DCI0_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dci0 pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, totalNumPdus, NFAPI_HI_DCI0_MAX_PDU); + return 0; + } + + if(totalNumPdus > 0) + { + value->hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_hi_dci0_request_pdu_t) * totalNumPdus, config); + if(value->hi_dci0_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate hi dci0 pdu list (count:%d)\n", __FUNCTION__, totalNumPdus); + return 0; + } + } + else + { + value->hi_dci0_pdu_list = 0; + } + + uint8_t i; + for(i = 0; i < totalNumPdus; ++i) + { + nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end if past buffer end + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end); + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_HI_DCI0_HI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, &unpack_hi_dci0_hi_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, &unpack_hi_dci0_hi_pdu_rel10_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, &unpack_hi_dci0_dci_pdu_rel12_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, + { NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, &unpack_dl_config_epdcch_params_rel11_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, &unpack_hi_dci0_mpdcch_dci_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, &unpack_hi_dci0_npdcch_dci_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + } + + return 1; +} + +static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, &unpack_hi_dci0_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + +static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + uint8_t proceed = 1; + nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; + + if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0) + return 0; + + while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_TX_REQUEST_BODY_TAG: + { + pNfapiMsg->tx_request_body.tl = generic_tl; + + if( pull16(ppReadPackedMsg, &pNfapiMsg->tx_request_body.number_of_pdus, end) == 0) + return 0; + + if(pNfapiMsg->tx_request_body.number_of_pdus > NFAPI_TX_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of tx pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus, NFAPI_TX_MAX_PDU); + return 0; + } + + if(pNfapiMsg->tx_request_body.number_of_pdus > 0) + { + pNfapiMsg->tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_tx_request_pdu_t) * pNfapiMsg->tx_request_body.number_of_pdus, config); + if(pNfapiMsg->tx_request_body.tx_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate tx pdu list (count:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus); + return 0; + } + } + else + { + pNfapiMsg->tx_request_body.tx_pdu_list = 0; + } + + + uint16_t i; + uint16_t totalNumPdus = pNfapiMsg->tx_request_body.number_of_pdus; + for(i = 0; i < totalNumPdus; ++i) + { + nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]); + + uint16_t length = 0; + uint16_t index = 0; + + if(!(pull16(ppReadPackedMsg, &length, end) && + pull16(ppReadPackedMsg, &index, end))) + return 0; + + pdu->pdu_length = length; + pdu->pdu_index = index; + + + // TODO : May need to rethink this bit + pdu->num_segments = 1; + pdu->segments[0].segment_length = pdu->pdu_length; + pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config); + + if(pdu->segments[0].segment_data) + { + if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end)) + return 0; + if (0 && pdu->segments[0].segment_length == 3) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, + pdu->segments[0].segment_data[0], + pdu->segments[0].segment_data[1], + pdu->segments[0].segment_data[2] + ); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index); + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag ); + } + break; + }; + } + + return 1; +} + +static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->value_0, end) && + pull8(ppReadPackedMsg, &value->value_1, end)); +} + +static uint8_t unpack_harq_indication_tdd_harq_data_multiplexing(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_multiplexing_t* value = (nfapi_harq_indication_tdd_harq_data_multiplexing_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->value_0, end) && + pull8(ppReadPackedMsg, &value->value_1, end) && + pull8(ppReadPackedMsg, &value->value_2, end) && + pull8(ppReadPackedMsg, &value->value_3, end)); +} +static uint8_t unpack_harq_indication_tdd_harq_data_special_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_special_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_special_bundling_t*)tlv; + return ( pull8(ppReadPackedMsg, &value->value_0, end)); +} +static uint8_t unpack_harq_indication_tdd_harq_data(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_t* value = (nfapi_harq_indication_tdd_harq_data_t*)tlv; + return (pull8(ppReadPackedMsg, &value->value_0, end)); +} + +static uint8_t unpack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel8_t* value = (nfapi_harq_indication_tdd_rel8_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_bundling(&value->harq_data.bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data_multiplexing(&value->harq_data.multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data.special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = 1; + break; + default: + // TODO add error message + return 0; + break; + } + return result; +} + +static uint8_t unpack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel9_t* value = (nfapi_harq_indication_tdd_rel9_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) + { + // TODO : add error message + return 0; + } + + uint16_t idx = 0; + for(idx = 0; idx < value->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); + break; + default: + // TODO add error message + return 0; + break; + } + + if(result == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel13_t* value = (nfapi_harq_indication_tdd_rel13_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull16(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) + { + // TODO : add error message + return 0; + } + + uint16_t idx = 0; + for(idx = 0; idx < value->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_4, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_5, ppReadPackedMsg, end); + break; + default: + // TODO add error message + return 0; + break; + } + + if(result == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel8_t* value = (nfapi_harq_indication_fdd_rel8_t*)tlv; + return (pull8(ppReadPackedMsg, &value->harq_tb1, end) && + pull8(ppReadPackedMsg, &value->harq_tb2, end)); +} + +static uint8_t unpack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel9_t* value = (nfapi_harq_indication_fdd_rel9_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end) && + pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, value->number_of_ack_nack, end)); +} + +static uint8_t unpack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel13_t* value = (nfapi_harq_indication_fdd_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mode, end) && + pull16(ppReadPackedMsg, &value->number_of_ack_nack, end) && + pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, value->number_of_ack_nack, end)); +} + +static uint8_t unpack_ul_cqi_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->ul_cqi, end) && + pull8(ppReadPackedMsg, &value->channel, end)); +} + + + +static uint8_t unpack_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; + uint8_t* harqBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(harqBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) + return 0; + + if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); + return 0; + } + + value->harq_pdu_list = (nfapi_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config); + if(value->harq_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_harqs; ++i) + { + nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, &unpack_harq_indication_tdd_rel8_value}, + { NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, &unpack_harq_indication_tdd_rel9_value}, + { NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, &unpack_harq_indication_tdd_rel13_value}, + { NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, &unpack_harq_indication_fdd_rel8_value}, + { NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, &unpack_harq_indication_fdd_rel9_value}, + { NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, &unpack_harq_indication_fdd_rel13_value}, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, &unpack_harq_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_crc_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_crc_indication_rel8_t* crc_pdu_rel8 = (nfapi_crc_indication_rel8_t*)tlv; + return ( pull8(ppReadPackedMsg, &crc_pdu_rel8->crc_flag, end) ); +} + +static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; + uint8_t* crcBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(crcBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_crcs, end) == 0) + return 0; + + if(value->number_of_crcs > NFAPI_CRC_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of crc ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_crcs, NFAPI_CRC_IND_MAX_PDU); + return 0; + } + + if(value->number_of_crcs > 0) + { + value->crc_pdu_list = (nfapi_crc_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config); + if(value->crc_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs); + return 0; + } + } + else + { + value->crc_pdu_list = 0; + } + + + uint8_t i = 0; + for(i = 0; i < value->number_of_crcs; ++i) + { + nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* crcPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, unpack_crc_indication_rel8_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, crcPduInstanceEnd, 0, 0) == 0) + return 0; + } + + return 1; +} + +static uint8_t unpack_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, &unpack_crc_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_rx_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->length, end) && + pull16(ppReadPackedMsg, &value->offset, end) && + pull8(ppReadPackedMsg, &value->ul_cqi, end) && + pull16(ppReadPackedMsg, &value->timing_advance, end)); +} +static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; + return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end)); +} + +static uint8_t unpack_rx_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; + + // the rxBodyEnd points to the end of the cqi PDU's + uint8_t* rxBodyEnd = *ppReadPackedMsg + value->tl.length; + uint8_t* rxPduEnd = rxBodyEnd; + + uint8_t* numberOfPdusAddress = *ppReadPackedMsg; + + if(rxBodyEnd > end) + { + // pdu end is past buffer end + return 0; + } + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->rx_pdu_list = (nfapi_rx_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config); + if(value->rx_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->rx_pdu_list = 0; + } + + uint8_t i = 0; + nfapi_rx_indication_pdu_t* pdu = 0; + while((uint8_t*)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t*)(*ppReadPackedMsg) < rxPduEnd) + { + nfapi_tl_t generic_tl; + if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_RX_UE_INFORMATION_TAG: + { + pdu = &(value->rx_pdu_list[i++]); + pdu->rx_ue_information.tl = generic_tl; + if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) + return 0; + } + break; + case NFAPI_RX_INDICATION_REL8_TAG: + { + if(pdu != 0) + { + pdu->rx_indication_rel8.tl = generic_tl; + if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0) + return 0; + + if(pdu->rx_indication_rel8.offset > 0) + { + // Need to check that the data is within the tlv + if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd) + { + // If this the first pdu set the rxPduEnd + if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd) + { + rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset; + + if(rxPduEnd > end) + { + // pdu end is past buffer end + return 0; + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n"); + } + } + } + } + break; + case NFAPI_RX_INDICATION_REL9_TAG: + { + if(pdu != 0) + { + pdu->rx_indication_rel9.tl = generic_tl; + if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0) + return 0; + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag ); + } + break; + } + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_pdus; ++idx) + { + if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length; + value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config); + if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0) + { + return 0; + } + } + } + + return 1; +} + +static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, &unpack_rx_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel8_t* preamble_pdu_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &preamble_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &preamble_pdu_rel8->preamble, end) && + pull16(ppReadPackedMsg, &preamble_pdu_rel8->timing_advance, end)); +} + +static uint8_t unpack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel9_t* preamble_pdu_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; + return pull16(ppReadPackedMsg, &preamble_pdu_rel9->timing_advance_r9, end); +} + +static uint8_t unpack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel13_t* preamble_pdu_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; + return pull8(ppReadPackedMsg, &preamble_pdu_rel13->rach_resource_type, end); +} + +static uint8_t unpack_rach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; + uint8_t* rachBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(rachBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_preambles, end) == 0) + return 0; + + if(value->number_of_preambles > NFAPI_PREAMBLE_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of preamble du's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_preambles, NFAPI_PREAMBLE_MAX_PDU); + return 0; + } + + if(value->number_of_preambles > 0) + { + value->preamble_list = (nfapi_preamble_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_preamble_pdu_t) * value->number_of_preambles, config); + if(value->preamble_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate preamble pdu list (count:%d)\n", __FUNCTION__, value->number_of_preambles); + return 0; + } + } + else + { + value->preamble_list = 0; + } + + + uint8_t i = 0; + for(i = 0; i < value->number_of_preambles; ++i) + { + nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* preamblePduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, unpack_preamble_pdu_rel8_value }, + { NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, unpack_preamble_pdu_rel9_value }, + { NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, unpack_preamble_pdu_rel13_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, preamblePduInstanceEnd, 0, 0) == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, &unpack_rach_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel8_t* srs_pdu_fdd_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->doppler_estimation, end) && + pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->timing_advance, end) && + pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->rb_start, end) && + pullarray8(ppReadPackedMsg, srs_pdu_fdd_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_fdd_rel8->number_of_resource_blocks, end))) + return 0; + return 1; +} + +static uint8_t unpack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel9_t* srs_pdu_fdd_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; + return (pull16(ppReadPackedMsg, &srs_pdu_fdd_rel9->timing_advance_r9, end)); +} + +static uint8_t unpack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_ttd_rel10_t* srs_pdu_tdd_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; + return (pull8(ppReadPackedMsg, &srs_pdu_tdd_rel10->uppts_symbol, end)); +} + +static uint8_t unpack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel11_t* srs_pdu_fdd_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; + return ( pull16(ppReadPackedMsg, &srs_pdu_fdd_rel11->ul_rtoa, end)); +} + +static uint8_t unpack_tdd_channel_measurement_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && + pull8(ppReadPackedMsg, &value->number_of_subbands, end) && + pull8(ppReadPackedMsg, &value->num_atennas, end))) + return 0; + + if(value->number_of_subbands > NFAPI_MAX_NUM_SUBBANDS) + { + // todo : add error + return 0; + } + + if(value->num_atennas > NFAPI_MAX_NUM_PHYSICAL_ANTENNAS) + { + // todo : add error + return 0; + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + if(!(pull8(ppReadPackedMsg, &value->subands[idx].subband_index, end) && + pullarray16(ppReadPackedMsg, value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, end))) + return 0; + } + + return 1; +} + + +static uint8_t unpack_srs_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_body_t* value = (nfapi_srs_indication_body_t*)tlv; + uint8_t* srsBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(srsBodyEnd > end) + return 0; + + if(pull8(ppReadPackedMsg, &value->number_of_ues, end) == 0) + return 0; + + if(value->number_of_ues > NFAPI_SRS_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of srs ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_ues, NFAPI_SRS_IND_MAX_PDU); + return 0; + } + + if(value->number_of_ues > 0) + { + value->srs_pdu_list = (nfapi_srs_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_srs_indication_pdu_t) * value->number_of_ues, config); + if(value->srs_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate srs ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_ues); + return 0; + } + } + else + { + value->srs_pdu_list = 0; + } + + + + uint8_t i = 0; + for(i = 0; i < value->number_of_ues; ++i) + { + nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); + + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* srsPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, unpack_srs_indication_fdd_rel8_value}, + { NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, unpack_srs_indication_fdd_rel9_value}, + { NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, unpack_srs_indication_tdd_rel10_value}, + { NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, unpack_srs_indication_fdd_rel11_value}, + { NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, unpack_tdd_channel_measurement_value}, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srsPduInstanceEnd, 0, 0) == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, &unpack_srs_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static uint8_t unpack_sr_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; + uint8_t* srBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(srBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_srs, end) == 0) + return 0; + + if(value->number_of_srs > NFAPI_SR_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of sr ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_srs, NFAPI_SR_IND_MAX_PDU); + return 0; + } + + if(value->number_of_srs > 0) + { + value->sr_pdu_list = (nfapi_sr_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_sr_indication_pdu_t) * value->number_of_srs, config); + if(value->sr_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_srs); + return 0; + } + } + else + { + value->sr_pdu_list = 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_srs; ++i) + { + nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* srPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, unpack_ul_cqi_information_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srPduInstanceEnd, 0, 0) == 0) + return 0; + } + + return 1; + +} + +static int unpack_sr_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, &unpack_sr_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} +static uint8_t unpack_cqi_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &cqi_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel8->data_offset, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel8->ul_cqi, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel8->ri, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel8->timing_advance, end)); + +} + +static uint8_t unpack_cqi_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &cqi_pdu_rel9->length, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->data_offset, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel9->ul_cqi, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel9->number_of_cc_reported, end))) + return 0; + + if(cqi_pdu_rel9->number_of_cc_reported > NFAPI_CC_MAX) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : out of bound array\n"); + return 0; + } + + if(!(pullarray8(ppReadPackedMsg, cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance_r9, end))) + return 0; + + return 1; +} + +static uint8_t unpack_cqi_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; + + // the cqiBodyEnd points to the end of the cqi PDU's + uint8_t* cqiBodyEnd = *ppReadPackedMsg + value->tl.length; + + //uint8_t* cqiPduEnd = cqiBodyEnd; + //uint8_t* numberOfPdusAddress = *ppReadPackedMsg; + + if(cqiBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_cqis, end) == 0) + return 0; + + if(value->number_of_cqis > NFAPI_CQI_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of cqi ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_cqis, NFAPI_CQI_IND_MAX_PDU); + return -1; + } + + if(value->number_of_cqis > 0) + { + value->cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_pdu_t) * value->number_of_cqis, config); + if(value->cqi_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); + return 0; + } + } + else + { + value->cqi_pdu_list = 0; + } + + if(value->number_of_cqis > 0) + { + value->cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_raw_pdu_t) * value->number_of_cqis, config); + if(value->cqi_raw_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate raw cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); + return 0; + } + } + else + { + value->cqi_raw_pdu_list = 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_cqis; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + memset(pdu, 0, sizeof(nfapi_cqi_indication_pdu_t)); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* cqiPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + while((uint8_t*)(*ppReadPackedMsg) < cqiPduInstanceEnd) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_RX_UE_INFORMATION_TAG: + pdu->rx_ue_information.tl = generic_tl; + if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) + return 0; + break; + case NFAPI_CQI_INDICATION_REL8_TAG: + pdu->cqi_indication_rel8.tl = generic_tl; + if(unpack_cqi_indication_rel8_value(&pdu->cqi_indication_rel8, ppReadPackedMsg, end) == 0) + return 0; + + break; + case NFAPI_CQI_INDICATION_REL9_TAG: + pdu->cqi_indication_rel9.tl = generic_tl; + if(unpack_cqi_indication_rel9_value(&pdu->cqi_indication_rel9, ppReadPackedMsg, end) == 0) + return 0; + + break; + case NFAPI_UL_CQI_INFORMATION_TAG: + pdu->ul_cqi_information.tl = generic_tl; + if(unpack_ul_cqi_information_value(&pdu->ul_cqi_information, ppReadPackedMsg, end) == 0) + return 0; + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_CQI.indication Invalid pdu type %d \n", generic_tl.tag ); + } + break; + + }; + } + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_cqis; ++idx) + { + if(value->cqi_pdu_list[idx].cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel8.length, end) == 0) + return 0; + } + else if(value->cqi_pdu_list[idx].cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel9.length, end) == 0) + return 0; + } + } + + + return 1; + +} + +static uint8_t unpack_cqi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, &unpack_cqi_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} +static uint8_t unpack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->mp_cca, end) && + pull32(ppReadPackedMsg, &value->n_cca, end) && + pull32(ppReadPackedMsg, &value->offset, end) && + pull32(ppReadPackedMsg, &value->lte_txop_sf, end) && + pull16(ppReadPackedMsg, &value->txop_sfn_sf_end, end) && + pull32(ppReadPackedMsg, &value->lbt_mode, end)); +} + +static uint8_t unpack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->offset, end) && + pull16(ppReadPackedMsg, &value->sfn_sf_end, end) && + pull32(ppReadPackedMsg, &value->lbt_mode, end)); +} + + +static uint8_t unpack_lbt_config_request_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU); + return 0; + } + + if(value->number_of_pdus) + { + value->lbt_dl_config_req_pdu_list = (nfapi_lbt_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_config_request_pdu_t) * value->number_of_pdus, config); + if(value->lbt_dl_config_req_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->lbt_dl_config_req_pdu_list = 0; + } + + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, &unpack_lbt_pdsch_req_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, &unpack_lbt_drs_req_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request body invalid pdu type %d\n", pdu->pdu_type); + return 0; + } + } + + return 1; +} +static uint8_t unpack_lbt_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, &unpack_lbt_config_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->result, end) && + pull32(ppReadPackedMsg, &value->lte_txop_symbols, end) && + pull32(ppReadPackedMsg, &value->initial_partial_sf, end)); + +} +static uint8_t unpack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->result, end)); +} + +static uint8_t unpack_lbt_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_LBT_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_IND_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->lbt_indication_pdu_list = (nfapi_lbt_dl_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_indication_pdu_t) * value->number_of_pdus, config); + if(value->lbt_indication_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl ind config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->lbt_indication_pdu_list = 0; + } + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, &unpack_lbt_pdsch_rsp_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, &unpack_lbt_drs_rsp_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d\n", pdu->pdu_type); + return 0; + } + } + + return 1; +} +static uint8_t unpack_lbt_dl_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, &unpack_lbt_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_fdd_rel13_t* value = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; + return (pull8(ppReadPackedMsg, &value->harq_tb1, end)); +} + + +static uint8_t unpack_nb_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; + uint8_t* nbharqBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(nbharqBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) + return 0; + + if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); + return 0; + } + + value->nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nb_harq_indication_pdu_t) * value->number_of_harqs, config); + if(value->nb_harq_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_harqs; ++i) + { + nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, &unpack_nb_harq_indication_fdd_rel13_value}, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_nb_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, &unpack_nb_harq_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_pdu_rel13_t* value = (nfapi_nrach_indication_pdu_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->initial_sc, end) && + pull16(ppReadPackedMsg, &value->timing_advance, end) && + pull8(ppReadPackedMsg, &value->nrach_ce_level, end)); +} + + +static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; + uint8_t* nrachBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(nrachBodyEnd > end) + return 0; + + if(pull8(ppReadPackedMsg, &value->number_of_initial_scs_detected, end) == 0) + return 0; + + if(value->number_of_initial_scs_detected > NFAPI_PREAMBLE_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of detected scs ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected, NFAPI_PREAMBLE_MAX_PDU); + return 0; + } + + value->nrach_pdu_list = (nfapi_nrach_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nrach_indication_pdu_t) * value->number_of_initial_scs_detected, config); + if(value->nrach_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nrach ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_initial_scs_detected; ++i) + { + nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); + + uint8_t* nrachPduInstanceEnd = *ppReadPackedMsg + 4 + 6; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, &unpack_nrach_indication_rel13_value}, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, nrachPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, &unpack_nrach_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->tx_request_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->ul_config_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_jitter, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_earliest_arrival, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +// unpack length check + +static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_DL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_dl_config_request_t)) + retLen = sizeof(nfapi_dl_config_request_t); + break; + + case NFAPI_UL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_ul_config_request_t)) + retLen = sizeof(nfapi_ul_config_request_t); + break; + + case NFAPI_SUBFRAME_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t)) + retLen = sizeof(nfapi_subframe_indication_t); + break; + + case NFAPI_HI_DCI0_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_hi_dci0_request_t)) + retLen = sizeof(nfapi_hi_dci0_request_t); + break; + + case NFAPI_TX_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_tx_request_t)) + retLen = sizeof(nfapi_tx_request_t); + break; + + case NFAPI_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_harq_indication_t)) + retLen = sizeof(nfapi_harq_indication_t); + break; + + case NFAPI_CRC_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_crc_indication_t)) + retLen = sizeof(nfapi_crc_indication_t); + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rx_indication_t)) + retLen = sizeof(nfapi_rx_indication_t); + break; + + case NFAPI_RACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rach_indication_t)) + retLen = sizeof(nfapi_rach_indication_t); + break; + + case NFAPI_SRS_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_srs_indication_t)) + retLen = sizeof(nfapi_srs_indication_t); + break; + + case NFAPI_RX_SR_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_sr_indication_t)) + retLen = sizeof(nfapi_sr_indication_t); + break; + + case NFAPI_RX_CQI_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t)) + retLen = sizeof(nfapi_cqi_indication_t); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t)) + retLen = sizeof(nfapi_lbt_dl_config_request_t); + break; + + case NFAPI_LBT_DL_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t)) + retLen = sizeof(nfapi_lbt_dl_indication_t); + break; + + case NFAPI_NB_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t)) + retLen = sizeof(nfapi_nb_harq_indication_t); + break; + + case NFAPI_NRACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t)) + retLen = sizeof(nfapi_nrach_indication_t); + break; + + case NFAPI_DL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_dl_node_sync_t)) + retLen = sizeof(nfapi_dl_node_sync_t); + break; + + case NFAPI_UL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_ul_node_sync_t)) + retLen = sizeof(nfapi_ul_node_sync_t); + break; + + case NFAPI_TIMING_INFO: + if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) + retLen = sizeof(nfapi_timing_info_t); + break; + + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); + break; + } + + return retLen; +} + + +// Main unpack functions - public + +int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) +{ + nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && + pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && + pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) + return -1; + + return 0; +} + +int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) +{ + int result = 0; + nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && + pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && + pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n"); + return -1; + } + + if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n"); + return -1; + } + + /* + if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n"); + return -1; + } + */ + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_DL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_UL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_ul_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_HI_DCI0_REQUEST: + if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen)) + result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_TX_REQUEST: + if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen)) + result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_HARQ_INDICATION: + if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) + result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_CRC_INDICATION: + if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen)) + result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen)) + result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RACH_INDICATION: + if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen)) + result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_SRS_INDICATION: + if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen)) + result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_SR_INDICATION: + if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen)) + result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_CQI_INDICATION: + if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen)) + result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_INDICATION: + if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen)) + result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NB_HARQ_INDICATION: + if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen)) + result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NRACH_INDICATION: + if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen)) + result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_DL_NODE_SYNC: + if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen)) + result = unpack_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UL_NODE_SYNC: + if (check_unpack_length(NFAPI_UL_NODE_SYNC, unpackedBufLen)) + result = unpack_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_TIMING_INFO: + if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen)) + result = unpack_timing_info(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + default: + + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p7_vendor_extension) + { + result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + if(result == 0) + return -1; + else + return 0; +} + diff --git a/nfapi/open-nFAPI/nfapi/tests/Makefile.am b/nfapi/open-nFAPI/nfapi/tests/Makefile.am new file mode 100644 index 0000000000..46785869b0 --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/tests/Makefile.am @@ -0,0 +1,36 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +#nfapi unit test +AUTOMAKE_OPTIONS=subdir-objects + +AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror +AM_CFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror + +check_PROGRAMS= test_nfapi +test_nfapi_SOURCES = nfapi_cunit_main.c ../src/nfapi.c ../src/nfapi_p7.c ../../common/src/debug.c ../src/nfapi_p5.c ../src/nfapi_p4.c +test_nfapi_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit + + +#jTEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh --ingore-exit +#TEST_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh + +#AM_TESTS_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL); +LOG_DRIVER = $(top_srcdir)/tap-driver.sh +#AM_LOG_FLAGS = -- test_nfapi + +TESTS=$(check_PROGRAMS) +EXTRA_DIST = $(TESTS) diff --git a/nfapi/open-nFAPI/nfapi/tests/nfapi_cunit_main.c b/nfapi/open-nFAPI/nfapi/tests/nfapi_cunit_main.c new file mode 100644 index 0000000000..daaf65a3ff --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/tests/nfapi_cunit_main.c @@ -0,0 +1,5511 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "CUnit.h" +#include "Basic.h" +#include "Automated.h" +//#include "CUnit/Console.h" + +#include "nfapi_interface.h" +#include "nfapi.h" +#include // for printf +#include +#include "debug.h" +#include "nfapi_interface.h" +/* Test Suite setup and cleanup functions: */ + +int init_suite(void) { return 0; } +int clean_suite(void) { return 0; } + +#define MAX_PACKED_MESSAGE_SIZE 8192 + +#define IN_OUT_ASSERT(_V) { CU_ASSERT_EQUAL(in._V, out._V); } + +typedef struct +{ + nfapi_tl_t tl; + uint16_t value1; + uint32_t value2; +} my_vendor_extention; + +extern void* nfapi_allocate_pdu(size_t size) +{ + return malloc(size); +} + +extern int nfapi_test_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config) +{ + printf("nfapi_unpack_vendor_extension_tlv\n"); + + if(tl->tag == NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE) + { + my_vendor_extention* mve = (my_vendor_extention*)malloc(sizeof(my_vendor_extention)); + mve->tl.tag = NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE; + + if(!(pull16(ppReadPackedMsg, &mve->value1, end) && + pull32(ppReadPackedMsg, &mve->value2, end))) + { + free(mve); + return 0; + } + + (*ve) = mve; + + } + + return 1; +} + +int nfapi_pack_vendor_extension_tlv_called = 0; +extern int nfapi_test_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + printf("nfapi_pack_vendor_extension_tlv\n"); + nfapi_pack_vendor_extension_tlv_called++; + + my_vendor_extention* mve = (my_vendor_extention*)ve; + + return (push16(mve->value1, ppWritePackedMsg, end) && + push32(mve->value2, ppWritePackedMsg, end)); + +} + +uint8_t gTestNfapiMessageTx[MAX_PACKED_MESSAGE_SIZE]; + + +uint8_t rand8(uint8_t min, uint8_t max) +{ + return ((rand() % (max + 1 - min)) + min); +} + +/************* Test case functions ****************/ + +void test_case_sample(void) +{ + /*Sample assert function, use as per your test case scenario.*/ + CU_ASSERT(CU_TRUE); + CU_ASSERT_NOT_EQUAL(2, -1); + CU_ASSERT_STRING_EQUAL("string #1", "string #1"); + CU_ASSERT_STRING_NOT_EQUAL("string #1", "string #2"); + + CU_ASSERT(CU_FALSE); + CU_ASSERT_EQUAL(2, 3); + CU_ASSERT_STRING_NOT_EQUAL("string #1", "string #1"); + CU_ASSERT_STRING_EQUAL("string #1", "string #2"); +} + + +int nfapi_test_verify_configreq_params(nfapi_pnf_config_request_t pnfConfigRequest_in, nfapi_pnf_config_request_t pnfConfigRequest_out) +{ + int i=0; + if(memcmp(&pnfConfigRequest_in, &pnfConfigRequest_out, sizeof(nfapi_pnf_config_request_t)) == 0) + { + /*packed and unpacked phy config request are matched.*/ + + printf("Success: packed and unpacked phy config request are matched\n"); + return 1; + } + else + { + if (pnfConfigRequest_in.header.message_id != pnfConfigRequest_out.header.message_id) + { + printf("Mismatch: packed message id %d, unpacked message id %d\n", + pnfConfigRequest_in.header.message_id, pnfConfigRequest_out.header.message_id); + } + if (pnfConfigRequest_in.header.message_length != pnfConfigRequest_out.header.message_length) + { + printf("Mismatch: packed message_length %d, unpacked message_length %d\n", + pnfConfigRequest_in.header.message_length, pnfConfigRequest_out.header.message_length); + } + if (pnfConfigRequest_in.header.phy_id != pnfConfigRequest_out.header.phy_id) + { + printf("Mismatch: packed phy_id %d, unpacked phy_id %d\n", + pnfConfigRequest_in.header.phy_id, pnfConfigRequest_out.header.phy_id); + } + if (pnfConfigRequest_in.pnf_phy_rf_config.number_phy_rf_config_info != pnfConfigRequest_out.pnf_phy_rf_config.number_phy_rf_config_info) + { + printf("Mismatch: packed number_phy_rf_config_info %d, unpacked number_phy_rf_config_info %d\n", + pnfConfigRequest_in.pnf_phy_rf_config.number_phy_rf_config_info, pnfConfigRequest_out.pnf_phy_rf_config.number_phy_rf_config_info); + } + + for (i=0; i < NFAPI_MAX_PHY_RF_INSTANCES; i++) + { + if (pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].phy_id != pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].phy_id) + { + printf("Mismatch: rf idx %d, packed phy id %d, unpacked phy id %d\n", + i, pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].phy_id, pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].phy_id); + } + if (pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].phy_config_index!= pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].phy_config_index) + { + printf("Mismatch: rf idx %d, packed phy_config_index %d, unpacked phy_config_index %d\n", + i, pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].phy_config_index, pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].phy_config_index); + } + if (pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].rf_config_index != pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].rf_config_index) + { + printf("Mismatch: rf idx %d, packed rf_config_index %d, unpacked rf_config_index %d\n", + i, pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[i].rf_config_index, pnfConfigRequest_out.pnf_phy_rf_config.phy_rf_config[i].rf_config_index); + } + } + return 0; + } + +} + + +void nfapi_test_pnf_config_req(void) +{ + + nfapi_pnf_config_request_t pnfConfigRequest_out; + nfapi_pnf_config_request_t pnfConfigRequest_in; + int packedMessageLength =0; + + printf(" nfapi_test_pnf_config_req run \n"); + + /* Build phy config req */ + pnfConfigRequest_in.header.phy_id = NFAPI_PHY_ID_NA; + pnfConfigRequest_in.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + pnfConfigRequest_in.header.message_length = 22; + pnfConfigRequest_in.header.spare = 0; + + pnfConfigRequest_in.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + pnfConfigRequest_in.pnf_phy_rf_config.tl.length = 0; + pnfConfigRequest_in.pnf_phy_rf_config.number_phy_rf_config_info = 2; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[0].phy_id = 4; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[0].phy_config_index = 1; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[0].rf_config_index = 1; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[1].phy_id = 5; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[1].phy_config_index = 2; + pnfConfigRequest_in.pnf_phy_rf_config.phy_rf_config[1].rf_config_index = 2; + + /*Pack pnf config req*/ + packedMessageLength = nfapi_p5_message_pack(&pnfConfigRequest_in, sizeof(nfapi_pnf_config_request_t), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + /*Unpack pnf config request*/ + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &pnfConfigRequest_out, sizeof(nfapi_pnf_config_request_t), 0); + + /*Verify unpacked message*/ + CU_ASSERT_EQUAL(nfapi_test_verify_configreq_params(pnfConfigRequest_in, pnfConfigRequest_out), 1); + +} + +void nfapi_test_2(void) { + /*Sample test function*/ + CU_ASSERT_EQUAL( 0, 0); +} + +void nfapi_test_rssi_request_lte() +{ + uint16_t idx; + nfapi_rssi_request_t in; + nfapi_rssi_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; + in.lte_rssi_request.frequency_band_indicator = 0; + in.lte_rssi_request.bandwidth = 0; + in.lte_rssi_request.timeout = 0; + in.lte_rssi_request.number_of_earfcns = 4; + in.lte_rssi_request.earfcn[0] = 42; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int upack_result = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_NOT_EQUAL(packedMessageLength, -1); + CU_ASSERT_NOT_EQUAL(packedMessageLength, 0); + CU_ASSERT_NOT_EQUAL(upack_result, 0); + CU_ASSERT_NOT_EQUAL(upack_result, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_rssi_request.frequency_band_indicator, out.lte_rssi_request.frequency_band_indicator); + CU_ASSERT_EQUAL(in.lte_rssi_request.bandwidth, out.lte_rssi_request.bandwidth); + CU_ASSERT_EQUAL(in.lte_rssi_request.timeout, out.lte_rssi_request.timeout); + CU_ASSERT_EQUAL(in.lte_rssi_request.number_of_earfcns, out.lte_rssi_request.number_of_earfcns); + + for(idx = 0; idx < out.lte_rssi_request.number_of_earfcns; ++idx) + { + CU_ASSERT_EQUAL(in.lte_rssi_request.earfcn[idx], out.lte_rssi_request.earfcn[idx]); + } +} + +void nfapi_test_rssi_request_lte2() +{ + uint16_t idx; + nfapi_rssi_request_t in; + nfapi_rssi_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; + in.lte_rssi_request.frequency_band_indicator = 0; + in.lte_rssi_request.bandwidth = 0; + in.lte_rssi_request.timeout = 0; + in.lte_rssi_request.number_of_earfcns = 4; + in.lte_rssi_request.earfcn[0] = 42; + + // try and pak with a buffer that is too small + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, NFAPI_HEADER_LENGTH + 4, 0); + CU_ASSERT_EQUAL(packedMessageLength, -1); + + // pack correctly + packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + // unpack with a small bufer + int upack_result = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength - 1, &out, sizeof(out), 0); + + upack_result = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_NOT_EQUAL(packedMessageLength, -1); + CU_ASSERT_NOT_EQUAL(packedMessageLength, 0); + CU_ASSERT_NOT_EQUAL(upack_result, 0); + CU_ASSERT_NOT_EQUAL(upack_result, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_rssi_request.frequency_band_indicator, out.lte_rssi_request.frequency_band_indicator); + CU_ASSERT_EQUAL(in.lte_rssi_request.bandwidth, out.lte_rssi_request.bandwidth); + CU_ASSERT_EQUAL(in.lte_rssi_request.timeout, out.lte_rssi_request.timeout); + CU_ASSERT_EQUAL(in.lte_rssi_request.number_of_earfcns, out.lte_rssi_request.number_of_earfcns); + + for(idx = 0; idx < out.lte_rssi_request.number_of_earfcns; ++idx) + { + CU_ASSERT_EQUAL(in.lte_rssi_request.earfcn[idx], out.lte_rssi_request.earfcn[idx]); + } +} + + + +// Test decoding of message which has a large number if earfcn which could +// cause a buffer over run if not handled +void nfapi_test_rssi_request_lte_overrun() +{ + nfapi_rssi_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t* end = p + 1024; + push16(0, &p, end); + push16(NFAPI_RSSI_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_LTE, &p, end); + push16(NFAPI_LTE_RSSI_REQUEST_TAG, &p, end); + push16(11, &p, end); + + push8(0, &p, end); + push16(0, &p, end); + push8(0, &p, end); + push32(0, &p, end); + push8(123, &p, end); // to many EARFCN's + push16(16, &p, end); + + int result = nfapi_p4_message_unpack(buffer, sizeof(buffer), &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_rssi_request_lte_rat_type_mismatch() +{ + nfapi_rssi_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_RSSI_REQUEST, &p, end); + push16(16, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_GERAN, &p, end); + + push16(NFAPI_LTE_RSSI_REQUEST_TAG, &p, end); + push16(11, &p, end); + + push8(0, &p, end); + push16(0, &p, end); + push8(0, &p, end); + push32(0, &p, end); + push8(1, &p, end); + push16(16, &p, end); + + int result = nfapi_p4_message_unpack(buffer, sizeof(buffer), &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_rssi_request_utran() +{ + uint16_t idx; + nfapi_rssi_request_t in; + nfapi_rssi_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_UTRAN; + + + in.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG; + in.utran_rssi_request.frequency_band_indicator = 0; + in.utran_rssi_request.measurement_period = 0; + in.utran_rssi_request.timeout = 0; + in.utran_rssi_request.number_of_uarfcns = 3; + in.utran_rssi_request.uarfcn[0] = 42; + in.utran_rssi_request.uarfcn[1] = 42; + in.utran_rssi_request.uarfcn[2] = 42; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.utran_rssi_request.frequency_band_indicator, out.utran_rssi_request.frequency_band_indicator); + CU_ASSERT_EQUAL(in.utran_rssi_request.measurement_period, out.utran_rssi_request.measurement_period); + CU_ASSERT_EQUAL(in.utran_rssi_request.timeout, out.utran_rssi_request.timeout); + CU_ASSERT_EQUAL(in.utran_rssi_request.number_of_uarfcns, out.utran_rssi_request.number_of_uarfcns); + + for(idx = 0; idx < out.utran_rssi_request.number_of_uarfcns; ++idx) + { + CU_ASSERT_EQUAL(in.utran_rssi_request.uarfcn[idx], out.utran_rssi_request.uarfcn[idx]); + } + +} + +void nfapi_test_rssi_request_geran() +{ + uint16_t idx; + nfapi_rssi_request_t in; + nfapi_rssi_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_GERAN; + + in.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG; + in.geran_rssi_request.frequency_band_indicator = 0; + in.geran_rssi_request.measurement_period = 0; + in.geran_rssi_request.timeout = 0; + in.geran_rssi_request.number_of_arfcns = 3; + in.geran_rssi_request.arfcn[0].arfcn = 42; + in.geran_rssi_request.arfcn[0].direction = 0; + in.geran_rssi_request.arfcn[1].arfcn = 42; + in.geran_rssi_request.arfcn[1].direction = 1; + in.geran_rssi_request.arfcn[2].arfcn = 42; + in.geran_rssi_request.arfcn[2].direction = 1; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.geran_rssi_request.frequency_band_indicator, out.geran_rssi_request.frequency_band_indicator); + CU_ASSERT_EQUAL(in.geran_rssi_request.measurement_period, out.geran_rssi_request.measurement_period); + CU_ASSERT_EQUAL(in.geran_rssi_request.timeout, out.geran_rssi_request.timeout); + CU_ASSERT_EQUAL(in.geran_rssi_request.number_of_arfcns, out.geran_rssi_request.number_of_arfcns); + + for(idx = 0; idx < out.geran_rssi_request.number_of_arfcns; ++idx) + { + CU_ASSERT_EQUAL(in.geran_rssi_request.arfcn[idx].arfcn, out.geran_rssi_request.arfcn[idx].arfcn); + CU_ASSERT_EQUAL(in.geran_rssi_request.arfcn[idx].direction, out.geran_rssi_request.arfcn[idx].direction); + } +} + +void nfapi_test_rssi_request_nb_iot() +{ + uint16_t idx, idx2; + nfapi_rssi_request_t in; + nfapi_rssi_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_NB_IOT; + + in.nb_iot_rssi_request.tl.tag = NFAPI_NB_IOT_RSSI_REQUEST_TAG; + in.nb_iot_rssi_request.frequency_band_indicator = 34; + in.nb_iot_rssi_request.measurement_period = 900; + in.nb_iot_rssi_request.timeout = 4321; + in.nb_iot_rssi_request.number_of_earfcns = 3; + in.nb_iot_rssi_request.earfcn[0].earfcn = 42; + in.nb_iot_rssi_request.earfcn[0].number_of_ro_dl = 1; + in.nb_iot_rssi_request.earfcn[0].ro_dl[0] = 2; + in.nb_iot_rssi_request.earfcn[1].earfcn = 43; + in.nb_iot_rssi_request.earfcn[1].number_of_ro_dl = 0; + in.nb_iot_rssi_request.earfcn[2].earfcn = 44; + in.nb_iot_rssi_request.earfcn[2].number_of_ro_dl = 2; + in.nb_iot_rssi_request.earfcn[2].ro_dl[0] = 0; + in.nb_iot_rssi_request.earfcn[2].ro_dl[1] = 4; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + IN_OUT_ASSERT(header.message_id); + IN_OUT_ASSERT(rat_type); + IN_OUT_ASSERT(nb_iot_rssi_request.frequency_band_indicator); + IN_OUT_ASSERT(nb_iot_rssi_request.measurement_period); + IN_OUT_ASSERT(nb_iot_rssi_request.timeout); + IN_OUT_ASSERT(nb_iot_rssi_request.number_of_earfcns); + + for(idx = 0; idx < out.nb_iot_rssi_request.number_of_earfcns; ++idx) + { + IN_OUT_ASSERT(nb_iot_rssi_request.earfcn[idx].earfcn); + IN_OUT_ASSERT(nb_iot_rssi_request.earfcn[idx].number_of_ro_dl); + + for(idx2 = 0; idx2 < out.nb_iot_rssi_request.earfcn[idx].number_of_ro_dl; ++idx2) + IN_OUT_ASSERT(nb_iot_rssi_request.earfcn[idx].ro_dl[idx2]); + } +} + + +void nfapi_test_rssi_response() +{ + nfapi_rssi_response_t in; + nfapi_rssi_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + +} + +void nfapi_test_rssi_indication() +{ + uint16_t idx = 0; + nfapi_rssi_indication_t in; + nfapi_rssi_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_RSSI_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_OK; + in.rssi_indication_body.tl.tag = NFAPI_RSSI_INDICATION_TAG; + in.rssi_indication_body.tl.length = 0; + in.rssi_indication_body.number_of_rssi = 4; + in.rssi_indication_body.rssi[0] = 2; + in.rssi_indication_body.rssi[1] = 0; + in.rssi_indication_body.rssi[2] = -23; + in.rssi_indication_body.rssi[3] = -18000; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.rssi_indication_body.tl.tag, out.rssi_indication_body.tl.tag); + CU_ASSERT_EQUAL(in.rssi_indication_body.number_of_rssi, out.rssi_indication_body.number_of_rssi); + + for(idx = 0; idx < out.rssi_indication_body.number_of_rssi; ++idx) + { + CU_ASSERT_EQUAL(in.rssi_indication_body.rssi[idx], out.rssi_indication_body.rssi[idx]); + } + +} +void nfapi_test_rssi_indication_overrun() +{ + nfapi_rssi_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_RSSI_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error code + + push16(NFAPI_RSSI_INDICATION_TAG, &p, end); + push16(11, &p, end); + + push16(NFAPI_MAX_RSSI + 23, &p, end); // to many EARFCN's + push16(16, &p, end); + + int result = nfapi_p4_message_unpack(buffer, sizeof(buffer), &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_cell_search_request_lte() +{ + uint16_t idx; + nfapi_cell_search_request_t in; + nfapi_cell_search_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG; + in.lte_cell_search_request.earfcn = 213; + in.lte_cell_search_request.measurement_bandwidth = 1; + in.lte_cell_search_request.exhaustive_search = 0; + in.lte_cell_search_request.timeout = 123; + in.lte_cell_search_request.number_of_pci = 3; + in.lte_cell_search_request.pci[0] = 3; + in.lte_cell_search_request.pci[1] = 6; + in.lte_cell_search_request.pci[2] = 9; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_cell_search_request.earfcn, out.lte_cell_search_request.earfcn); + CU_ASSERT_EQUAL(in.lte_cell_search_request.measurement_bandwidth, out.lte_cell_search_request.measurement_bandwidth); + CU_ASSERT_EQUAL(in.lte_cell_search_request.exhaustive_search, out.lte_cell_search_request.exhaustive_search); + CU_ASSERT_EQUAL(in.lte_cell_search_request.timeout, out.lte_cell_search_request.timeout); + CU_ASSERT_EQUAL(in.lte_cell_search_request.number_of_pci, out.lte_cell_search_request.number_of_pci); + + for(idx = 0; idx < out.lte_cell_search_request.number_of_pci; ++idx) + { + CU_ASSERT_EQUAL(in.lte_cell_search_request.pci[idx], out.lte_cell_search_request.pci[idx]); + } +} + +void nfapi_test_cell_search_request_utran() +{ + uint16_t idx; + nfapi_cell_search_request_t in; + nfapi_cell_search_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_UTRAN; + + in.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG; + in.utran_cell_search_request.uarfcn = 213; + in.utran_cell_search_request.exhaustive_search = 0; + in.utran_cell_search_request.timeout = 123; + in.utran_cell_search_request.number_of_psc = 3; + in.utran_cell_search_request.psc[0] = 3; + in.utran_cell_search_request.psc[1] = 6; + in.utran_cell_search_request.psc[2] = 9; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.utran_cell_search_request.uarfcn, out.utran_cell_search_request.uarfcn); + CU_ASSERT_EQUAL(in.utran_cell_search_request.exhaustive_search, out.utran_cell_search_request.exhaustive_search); + CU_ASSERT_EQUAL(in.utran_cell_search_request.timeout, out.utran_cell_search_request.timeout); + CU_ASSERT_EQUAL(in.utran_cell_search_request.number_of_psc, out.utran_cell_search_request.number_of_psc); + + for(idx = 0; idx < out.utran_cell_search_request.number_of_psc; ++idx) + { + CU_ASSERT_EQUAL(in.utran_cell_search_request.psc[idx], out.utran_cell_search_request.psc[idx]); + } +} + +void nfapi_test_cell_search_request_geran() +{ + uint16_t idx; + nfapi_cell_search_request_t in; + nfapi_cell_search_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_GERAN; + + in.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG; + in.geran_cell_search_request.timeout = 123; + in.geran_cell_search_request.number_of_arfcn = 3; + in.geran_cell_search_request.arfcn[0] = 3; + in.geran_cell_search_request.arfcn[1] = 6; + in.geran_cell_search_request.arfcn[2] = 9; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.geran_cell_search_request.timeout, out.geran_cell_search_request.timeout); + CU_ASSERT_EQUAL(in.geran_cell_search_request.number_of_arfcn, out.geran_cell_search_request.number_of_arfcn); + + for(idx = 0; idx < out.geran_cell_search_request.number_of_arfcn; ++idx) + { + CU_ASSERT_EQUAL(in.geran_cell_search_request.arfcn[idx], out.geran_cell_search_request.arfcn[idx]); + } +} + +void nfapi_test_cell_search_request_nb_iot() +{ + uint16_t idx; + nfapi_cell_search_request_t in; + nfapi_cell_search_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_NB_IOT; + + in.nb_iot_cell_search_request.tl.tag = NFAPI_NB_IOT_CELL_SEARCH_REQUEST_TAG; + in.nb_iot_cell_search_request.earfcn = 54; + in.nb_iot_cell_search_request.ro_dl = 3; + in.nb_iot_cell_search_request.exhaustive_search = 1; + in.nb_iot_cell_search_request.timeout = 123; + in.nb_iot_cell_search_request.number_of_pci = 3; + in.nb_iot_cell_search_request.pci[0] = 3; + in.nb_iot_cell_search_request.pci[1] = 6; + in.nb_iot_cell_search_request.pci[2] = 9; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + IN_OUT_ASSERT(header.message_id); + IN_OUT_ASSERT(rat_type); + IN_OUT_ASSERT(nb_iot_cell_search_request.earfcn); + IN_OUT_ASSERT(nb_iot_cell_search_request.ro_dl); + IN_OUT_ASSERT(nb_iot_cell_search_request.exhaustive_search); + IN_OUT_ASSERT(nb_iot_cell_search_request.timeout); + IN_OUT_ASSERT(nb_iot_cell_search_request.number_of_pci); + + for(idx = 0; idx < out.nb_iot_cell_search_request.number_of_pci; ++idx) + { + IN_OUT_ASSERT(nb_iot_cell_search_request.pci[idx]); + } +} + +void nfapi_test_cell_search_response() +{ + nfapi_cell_search_response_t in; + nfapi_cell_search_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} + +void nfapi_test_cell_search_indication_lte() +{ + uint16_t idx = 0; + nfapi_cell_search_indication_t in; + nfapi_cell_search_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_OK; + in.lte_cell_search_indication.tl.tag = NFAPI_LTE_CELL_SEARCH_INDICATION_TAG; + in.lte_cell_search_indication.number_of_lte_cells_found = 2; + in.lte_cell_search_indication.lte_found_cells[0].pci = 0; + in.lte_cell_search_indication.lte_found_cells[0].rsrp = 42; + in.lte_cell_search_indication.lte_found_cells[0].rsrq= 11; + in.lte_cell_search_indication.lte_found_cells[0].frequency_offset = -100; + + in.lte_cell_search_indication.lte_found_cells[1].pci = 123; + in.lte_cell_search_indication.lte_found_cells[1].rsrp = 2; + in.lte_cell_search_indication.lte_found_cells[1].rsrq= 17; + in.lte_cell_search_indication.lte_found_cells[1].frequency_offset = 123; + + in.utran_cell_search_indication.tl.tag = 0; + in.geran_cell_search_indication.tl.tag = 0; + in.nb_iot_cell_search_indication.tl.tag = 0; + in.pnf_cell_search_state.tl.tag = 0; + + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_cell_search_indication.tl.tag, out.lte_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.lte_cell_search_indication.number_of_lte_cells_found, out.lte_cell_search_indication.number_of_lte_cells_found); + + for(idx = 0; idx < out.lte_cell_search_indication.number_of_lte_cells_found; ++idx) + { + CU_ASSERT_EQUAL(in.lte_cell_search_indication.lte_found_cells[idx].pci, out.lte_cell_search_indication.lte_found_cells[idx].pci); + CU_ASSERT_EQUAL(in.lte_cell_search_indication.lte_found_cells[idx].rsrp, out.lte_cell_search_indication.lte_found_cells[idx].rsrp); + CU_ASSERT_EQUAL(in.lte_cell_search_indication.lte_found_cells[idx].rsrq, out.lte_cell_search_indication.lte_found_cells[idx].rsrq); + CU_ASSERT_EQUAL(in.lte_cell_search_indication.lte_found_cells[idx].frequency_offset, out.lte_cell_search_indication.lte_found_cells[idx].frequency_offset); + } + + + CU_ASSERT_EQUAL(in.utran_cell_search_indication.tl.tag, out.utran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.tl.tag, out.geran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_search_state.tl.tag, out.pnf_cell_search_state.tl.tag); +} +void nfapi_test_cell_search_indication_utran() +{ + uint16_t idx = 0; + nfapi_cell_search_indication_t in; + nfapi_cell_search_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_OK; + in.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; + in.utran_cell_search_indication.number_of_utran_cells_found = 1; + in.utran_cell_search_indication.utran_found_cells[0].psc = 123; + in.utran_cell_search_indication.utran_found_cells[0].rscp = 2; + in.utran_cell_search_indication.utran_found_cells[0].ecno = 89; + in.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -1000; + + in.lte_cell_search_indication.tl.tag = 0; + in.geran_cell_search_indication.tl.tag = 0; + in.nb_iot_cell_search_indication.tl.tag = 0; + in.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + in.pnf_cell_search_state.length = 12; + in.pnf_cell_search_state.value[0] = 34; + in.pnf_cell_search_state.value[1] = 35; + in.pnf_cell_search_state.value[2] = 36; + in.pnf_cell_search_state.value[3] = 37; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.tl.tag, out.utran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.number_of_utran_cells_found, out.utran_cell_search_indication.number_of_utran_cells_found); + + for(idx = 0; idx < out.utran_cell_search_indication.number_of_utran_cells_found; ++idx) + { + CU_ASSERT_EQUAL(in.utran_cell_search_indication.utran_found_cells[idx].psc, out.utran_cell_search_indication.utran_found_cells[idx].psc); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.utran_found_cells[idx].rscp, out.utran_cell_search_indication.utran_found_cells[idx].rscp); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.utran_found_cells[idx].ecno, out.utran_cell_search_indication.utran_found_cells[idx].ecno); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.utran_found_cells[idx].frequency_offset, out.utran_cell_search_indication.utran_found_cells[idx].frequency_offset); + } + + CU_ASSERT_EQUAL(in.lte_cell_search_indication.tl.tag, out.lte_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.tl.tag, out.geran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_search_state.tl.tag, out.pnf_cell_search_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_search_state.length, out.pnf_cell_search_state.length); + + for(idx = 0; idx < out.pnf_cell_search_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_search_state.value[idx], out.pnf_cell_search_state.value[idx]); + } +} +void nfapi_test_cell_search_indication_geran() +{ + uint16_t idx = 0; + nfapi_cell_search_indication_t in; + nfapi_cell_search_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_OK; + in.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; + in.geran_cell_search_indication.number_of_gsm_cells_found = 1; + in.geran_cell_search_indication.gsm_found_cells[0].arfcn = 123; + in.geran_cell_search_indication.gsm_found_cells[0].bsic = 2; + in.geran_cell_search_indication.gsm_found_cells[0].rxlev = 89; + in.geran_cell_search_indication.gsm_found_cells[0].rxqual = 12; + in.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = 2389; + in.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 23; + + in.lte_cell_search_indication.tl.tag = 0; + in.utran_cell_search_indication.tl.tag = 0; + in.nb_iot_cell_search_indication.tl.tag = 0; + in.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + in.pnf_cell_search_state.length = 63; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.tl.tag, out.geran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.number_of_gsm_cells_found, out.geran_cell_search_indication.number_of_gsm_cells_found); + + for(idx = 0; idx < out.geran_cell_search_indication.number_of_gsm_cells_found; ++idx) + { + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].arfcn, out.geran_cell_search_indication.gsm_found_cells[idx].arfcn); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].bsic, out.geran_cell_search_indication.gsm_found_cells[idx].bsic); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].rxlev, out.geran_cell_search_indication.gsm_found_cells[idx].rxlev); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].rxqual, out.geran_cell_search_indication.gsm_found_cells[idx].rxqual); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].frequency_offset, out.geran_cell_search_indication.gsm_found_cells[idx].frequency_offset); + CU_ASSERT_EQUAL(in.geran_cell_search_indication.gsm_found_cells[idx].sfn_offset, out.geran_cell_search_indication.gsm_found_cells[idx].sfn_offset); + } + + CU_ASSERT_EQUAL(in.lte_cell_search_indication.tl.tag, out.lte_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_cell_search_indication.tl.tag, out.utran_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_cell_search_indication.tl.tag, out.nb_iot_cell_search_indication.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_search_state.tl.tag, out.pnf_cell_search_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_search_state.length, out.pnf_cell_search_state.length); + + for(idx = 0; idx < out.pnf_cell_search_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_search_state.value[idx], out.pnf_cell_search_state.value[idx]); + } +} + +void nfapi_test_cell_search_indication_nb_iot() +{ + uint16_t idx = 0; + nfapi_cell_search_indication_t in; + nfapi_cell_search_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_OK; + in.nb_iot_cell_search_indication.tl.tag = NFAPI_NB_IOT_CELL_SEARCH_INDICATION_TAG; + in.nb_iot_cell_search_indication.number_of_nb_iot_cells_found = 1; + in.nb_iot_cell_search_indication.nb_iot_found_cells[0].pci = 123; + in.nb_iot_cell_search_indication.nb_iot_found_cells[0].rsrp = 2; + in.nb_iot_cell_search_indication.nb_iot_found_cells[0].rsrq = 89; + in.nb_iot_cell_search_indication.nb_iot_found_cells[0].frequency_offset = 2389; + + in.lte_cell_search_indication.tl.tag = 0; + in.utran_cell_search_indication.tl.tag = 0; + in.geran_cell_search_indication.tl.tag = 0; + + in.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + in.pnf_cell_search_state.length = 63; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + IN_OUT_ASSERT(header.message_id); + IN_OUT_ASSERT(error_code); + IN_OUT_ASSERT(nb_iot_cell_search_indication.tl.tag); + IN_OUT_ASSERT(nb_iot_cell_search_indication.number_of_nb_iot_cells_found); + + for(idx = 0; idx < out.nb_iot_cell_search_indication.number_of_nb_iot_cells_found; ++idx) + { + IN_OUT_ASSERT(nb_iot_cell_search_indication.nb_iot_found_cells[idx].pci); + IN_OUT_ASSERT(nb_iot_cell_search_indication.nb_iot_found_cells[idx].rsrp); + IN_OUT_ASSERT(nb_iot_cell_search_indication.nb_iot_found_cells[idx].rsrq); + IN_OUT_ASSERT(nb_iot_cell_search_indication.nb_iot_found_cells[idx].frequency_offset); + } + + IN_OUT_ASSERT(lte_cell_search_indication.tl.tag); + IN_OUT_ASSERT(utran_cell_search_indication.tl.tag); + IN_OUT_ASSERT(geran_cell_search_indication.tl.tag); + IN_OUT_ASSERT(pnf_cell_search_state.tl.tag); + IN_OUT_ASSERT(pnf_cell_search_state.length); + + for(idx = 0; idx < out.pnf_cell_search_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_search_state.value[idx], out.pnf_cell_search_state.value[idx]); + } +} + +void nfapi_test_cell_search_request_lte_overrun() +{ + nfapi_cell_search_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(0, &p, end); // rat_type + + push16(NFAPI_LTE_CELL_SEARCH_REQUEST_TAG, &p, end); + push16(8, &p, end); + + push16(11, &p, end); + push8(11, &p, end); + push8(11, &p, end); + push32(11, &p, end); + push8(NFAPI_MAX_PCI_LIST + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); + +} +void nfapi_test_cell_search_request_utran_overrun() +{ + nfapi_cell_search_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_UTRAN, &p, end); // rat_type + + push16(NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG, &p, end); + push16(8, &p, end); + + push16(11, &p, end); + push8(11, &p, end); + push32(11, &p, end); + push8(NFAPI_MAX_PSC_LIST + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_cell_search_request_geran_overrun() +{ + nfapi_cell_search_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_GERAN, &p, end); // rat_type + + push16(NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG, &p, end); + push16(8, &p, end); + + push32(11, &p, end); + push8(NFAPI_MAX_ARFCN_LIST + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_cell_search_indication_lte_overrun() +{ + nfapi_cell_search_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_LTE_CELL_SEARCH_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_LTE_CELLS_FOUND + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_cell_search_indication_utran_overrun() +{ + nfapi_cell_search_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_UTRAN_CELLS_FOUND + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_cell_search_indication_geran_overrun() +{ + nfapi_cell_search_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_GSM_CELLS_FOUND + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_cell_search_indication_state_overrun() +{ + nfapi_cell_search_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_CELL_SEARCH_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG, &p, end); + push16(13, &p, end); + + push16(1, &p, end); + if(1) + { + push16(42, &p, end); + push8(42, &p, end); + push8(42, &p, end); + push8(42, &p, end); + pushs16(42, &p, end); + push32(42, &p, end); + } + + push16(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &p, end); + push16(NFAPI_MAX_OPAQUE_DATA + 12, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_broadcast_detect_request_lte() +{ + nfapi_broadcast_detect_request_t in; + nfapi_broadcast_detect_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG; + in.lte_broadcast_detect_request.earfcn = 123; + in.lte_broadcast_detect_request.pci = 12; + in.lte_broadcast_detect_request.timeout = 1246; + + in.pnf_cell_search_state.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_request.earfcn, out.lte_broadcast_detect_request.earfcn); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_request.pci, out.lte_broadcast_detect_request.pci); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_request.timeout, out.lte_broadcast_detect_request.timeout); + +} +void nfapi_test_broadcast_detect_request_utran() +{ + uint16_t idx; + nfapi_broadcast_detect_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_broadcast_detect_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_UTRAN; + + in.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG; + in.utran_broadcast_detect_request.uarfcn = 123; + in.utran_broadcast_detect_request.psc = 12; + in.utran_broadcast_detect_request.timeout = 1246; + + in.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + in.pnf_cell_search_state.length = 60; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + CU_ASSERT_NOT_EQUAL(packedMessageLength, 0); + CU_ASSERT_NOT_EQUAL(packedMessageLength, -1); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_request.uarfcn, out.utran_broadcast_detect_request.uarfcn); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_request.psc, out.utran_broadcast_detect_request.psc); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_request.timeout, out.utran_broadcast_detect_request.timeout); + + CU_ASSERT_EQUAL(in.pnf_cell_search_state.length, out.pnf_cell_search_state.length); + + for(idx = 0; idx < out.pnf_cell_search_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_search_state.value[idx], out.pnf_cell_search_state.value[idx]); + } + +} + +void nfapi_test_broadcast_detect_request_nb_iot() +{ + uint16_t idx; + nfapi_broadcast_detect_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_broadcast_detect_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_NB_IOT; + + in.nb_iot_broadcast_detect_request.tl.tag = NFAPI_NB_IOT_BROADCAST_DETECT_REQUEST_TAG; + in.nb_iot_broadcast_detect_request.earfcn = 123; + in.nb_iot_broadcast_detect_request.ro_dl = 12; + in.nb_iot_broadcast_detect_request.pci = 12; + in.nb_iot_broadcast_detect_request.timeout = 1246; + + in.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + in.pnf_cell_search_state.length = 60; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + CU_ASSERT_NOT_EQUAL(packedMessageLength, 0); + CU_ASSERT_NOT_EQUAL(packedMessageLength, -1); + + int unpackResult = nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_NOT_EQUAL(unpackResult, 0); + CU_ASSERT_NOT_EQUAL(unpackResult, -1); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_request.earfcn, out.nb_iot_broadcast_detect_request.earfcn); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_request.ro_dl, out.nb_iot_broadcast_detect_request.ro_dl); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_request.pci, out.nb_iot_broadcast_detect_request.pci); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_request.timeout, out.nb_iot_broadcast_detect_request.timeout); + + CU_ASSERT_EQUAL(in.pnf_cell_search_state.length, out.pnf_cell_search_state.length); + + for(idx = 0; idx < out.pnf_cell_search_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_search_state.value[idx], out.pnf_cell_search_state.value[idx]); + } + +} + + +void nfapi_test_broadcast_detect_request_state_overrun() +{ + nfapi_broadcast_detect_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_BROADCAST_DETECT_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_UTRAN, &p, end); // error_code + + push16(NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG, &p, end); + push16(8, &p, end); + + push16(42, &p, end); + push16(42, &p, end); + push32(42, &p, end); + + push16(NFAPI_PNF_CELL_SEARCH_STATE_TAG, &p, end); + push16(NFAPI_MAX_OPAQUE_DATA + 12, &p, end); + + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_broadcast_detect_response() +{ + nfapi_broadcast_detect_response_t in; + nfapi_broadcast_detect_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + +} +void nfapi_test_broadcast_detect_indication_lte() +{ + uint16_t idx; + nfapi_broadcast_detect_indication_t in; + nfapi_broadcast_detect_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + in.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; + in.lte_broadcast_detect_indication.number_of_tx_antenna = 1; + in.lte_broadcast_detect_indication.mib_length = 8; + in.lte_broadcast_detect_indication.sfn_offset = 4; + in.utran_broadcast_detect_indication.tl.tag = 0; + in.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + in.pnf_cell_broadcast_state.length = 23; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.tl.tag, out.lte_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.number_of_tx_antenna, out.lte_broadcast_detect_indication.number_of_tx_antenna); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.mib_length, out.lte_broadcast_detect_indication.mib_length); + for(idx = 0; idx < out.lte_broadcast_detect_indication.mib_length; ++idx) + { + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.mib[idx], out.lte_broadcast_detect_indication.mib[idx]); + } + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.sfn_offset, out.lte_broadcast_detect_indication.sfn_offset); + + + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.tl.tag, out.utran_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); + for(idx = 0; idx < out.pnf_cell_broadcast_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.value[idx], out.pnf_cell_broadcast_state.value[idx]); + } +} +void nfapi_test_broadcast_detect_indication_lte_overrun() +{ + nfapi_broadcast_detect_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_BROADCAST_DETECT_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push8(1, &p, end); + push16(NFAPI_MAX_MIB_LENGTH + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out) ,0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_broadcast_detect_indication_utran() +{ + uint16_t idx; + nfapi_broadcast_detect_indication_t in; + nfapi_broadcast_detect_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + in.lte_broadcast_detect_indication.tl.tag = 0; + in.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; + in.utran_broadcast_detect_indication.mib_length = 16; + in.utran_broadcast_detect_indication.sfn_offset = 4; + in.pnf_cell_broadcast_state.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.tl.tag, out.lte_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.tl.tag, out.utran_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.mib_length, out.utran_broadcast_detect_indication.mib_length); + for(idx = 0; idx < out.utran_broadcast_detect_indication.mib_length; ++idx) + { + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.mib[idx], out.utran_broadcast_detect_indication.mib[idx]); + } + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.sfn_offset, out.utran_broadcast_detect_indication.sfn_offset); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); +} +void nfapi_test_broadcast_detect_indication_nb_iot() +{ + uint16_t idx; + nfapi_broadcast_detect_indication_t in; + nfapi_broadcast_detect_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + in.lte_broadcast_detect_indication.tl.tag = 0; + in.utran_broadcast_detect_indication.tl.tag = 0; + in.nb_iot_broadcast_detect_indication.tl.tag = NFAPI_NB_IOT_BROADCAST_DETECT_INDICATION_TAG; + in.nb_iot_broadcast_detect_indication.number_of_tx_antenna = 2; + in.nb_iot_broadcast_detect_indication.mib_length = 16; + in.nb_iot_broadcast_detect_indication.sfn_offset = 4; + in.pnf_cell_broadcast_state.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_broadcast_detect_indication.tl.tag, out.lte_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_broadcast_detect_indication.tl.tag, out.utran_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_indication.tl.tag, out.nb_iot_broadcast_detect_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_indication.number_of_tx_antenna, out.nb_iot_broadcast_detect_indication.number_of_tx_antenna); + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_indication.mib_length, out.nb_iot_broadcast_detect_indication.mib_length); + for(idx = 0; idx < out.nb_iot_broadcast_detect_indication.mib_length; ++idx) + { + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_indication.mib[idx], out.nb_iot_broadcast_detect_indication.mib[idx]); + } + CU_ASSERT_EQUAL(in.nb_iot_broadcast_detect_indication.sfn_offset, out.nb_iot_broadcast_detect_indication.sfn_offset); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); +} +void nfapi_test_broadcast_detect_indication_utran_overrun() +{ + nfapi_broadcast_detect_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_BROADCAST_DETECT_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error_code + + push16(NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_MIB_LENGTH + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_broadcast_detect_indication_state_overrun() +{ +} +void nfapi_test_system_information_schedule_request_lte() +{ + uint16_t idx; + nfapi_system_information_schedule_request_t in; + nfapi_system_information_schedule_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.nb_iot_system_information_schedule_request.tl.tag = 0; + + in.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; + in.lte_system_information_schedule_request.earfcn = 16; + in.lte_system_information_schedule_request.pci = 4; + in.lte_system_information_schedule_request.downlink_channel_bandwidth = 20; + in.lte_system_information_schedule_request.phich_configuration = 1; + in.lte_system_information_schedule_request.number_of_tx_antenna = 2; + in.lte_system_information_schedule_request.retry_count = 4; + in.lte_system_information_schedule_request.timeout = 0; + in.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + in.pnf_cell_broadcast_state.length = 7; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.tl.tag, out.lte_system_information_schedule_request.tl.tag); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.earfcn, out.lte_system_information_schedule_request.earfcn); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.pci, out.lte_system_information_schedule_request.pci); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.downlink_channel_bandwidth, out.lte_system_information_schedule_request.downlink_channel_bandwidth); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.downlink_channel_bandwidth, out.lte_system_information_schedule_request.downlink_channel_bandwidth); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.number_of_tx_antenna, out.lte_system_information_schedule_request.number_of_tx_antenna); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.retry_count, out.lte_system_information_schedule_request.retry_count); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.timeout, out.lte_system_information_schedule_request.timeout); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.length, out.pnf_cell_broadcast_state.length); + for(idx = 0; idx < out.pnf_cell_broadcast_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.value[idx], out.pnf_cell_broadcast_state.value[idx]); + } +} + +void nfapi_test_system_information_schedule_request_nb_iot() +{ + uint16_t idx; + nfapi_system_information_schedule_request_t in; + nfapi_system_information_schedule_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_NB_IOT; + + in.lte_system_information_schedule_request.tl.tag = 0; + in.nb_iot_system_information_schedule_request.tl.tag = NFAPI_NB_IOT_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; + in.nb_iot_system_information_schedule_request.earfcn = 16; + in.nb_iot_system_information_schedule_request.ro_dl = 4; + in.nb_iot_system_information_schedule_request.pci = 4; + in.nb_iot_system_information_schedule_request.scheduling_info_sib1_nb = 4; + in.nb_iot_system_information_schedule_request.timeout = 0; + in.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + in.pnf_cell_broadcast_state.length = 7; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_system_information_schedule_request.tl.tag, out.lte_system_information_schedule_request.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.tl.tag, out.nb_iot_system_information_schedule_request.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.earfcn, out.nb_iot_system_information_schedule_request.earfcn); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.ro_dl, out.nb_iot_system_information_schedule_request.ro_dl); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.pci, out.nb_iot_system_information_schedule_request.pci); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.scheduling_info_sib1_nb, out.nb_iot_system_information_schedule_request.scheduling_info_sib1_nb); + CU_ASSERT_EQUAL(in.nb_iot_system_information_schedule_request.timeout, out.nb_iot_system_information_schedule_request.timeout); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.length, out.pnf_cell_broadcast_state.length); + for(idx = 0; idx < out.pnf_cell_broadcast_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.value[idx], out.pnf_cell_broadcast_state.value[idx]); + } +} + +void nfapi_test_system_information_schedule_request_state_overrun() +{ + nfapi_system_information_schedule_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(0, &p, end); // rat type + + push16(NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG, &p, end); + push16(13, &p, end); + + push16(1, &p, end); + push16(1, &p, end); + push16(1, &p, end); + push8(142, &p, end); + push8(142, &p, end); + push8(142, &p, end); + push32(42, &p, end); + + push16(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &p, end); + push16(NFAPI_MAX_OPAQUE_DATA + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); + +} +void nfapi_test_system_information_schedule_response() +{ + nfapi_system_information_schedule_response_t in; + nfapi_system_information_schedule_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_system_information_schedule_indication_lte() +{ + uint16_t idx; + nfapi_system_information_schedule_indication_t in; + nfapi_system_information_schedule_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = 0; + + in.nb_iot_system_information_indication.tl.tag = 0; + in.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + in.lte_system_information_indication.sib_type = 16; + in.lte_system_information_indication.sib_length = 4; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib_type, out.lte_system_information_indication.sib_type); + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib_length, out.lte_system_information_indication.sib_length); + + for(idx = 0; idx < out.lte_system_information_indication.sib_length; ++idx) + { + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib[idx], out.lte_system_information_indication.sib[idx]); + } +} +void nfapi_test_system_information_schedule_indication_nb_iot() +{ + uint16_t idx; + nfapi_system_information_schedule_indication_t in; + nfapi_system_information_schedule_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = 0; + + in.lte_system_information_indication.tl.tag = 0; + in.nb_iot_system_information_indication.tl.tag = NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG; + in.nb_iot_system_information_indication.sib_type = 16; + in.nb_iot_system_information_indication.sib_length = 4; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.tl.tag, out.nb_iot_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib_type, out.nb_iot_system_information_indication.sib_type); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib_length, out.nb_iot_system_information_indication.sib_length); + + for(idx = 0; idx < out.nb_iot_system_information_indication.sib_length; ++idx) + { + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib[idx], out.nb_iot_system_information_indication.sib[idx]); + } +} +void nfapi_test_system_information_request_lte() +{ + uint16_t idx; + nfapi_system_information_request_t in; + nfapi_system_information_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_LTE; + + in.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG; + in.lte_system_information_request.earfcn = 16; + in.lte_system_information_request.pci = 4; + in.lte_system_information_request.downlink_channel_bandwidth = 20; + in.lte_system_information_request.phich_configuration = 1; + in.lte_system_information_request.number_of_tx_antenna = 2; + in.lte_system_information_request.number_of_si_periodicity = 1; + in.lte_system_information_request.si_periodicity[0].si_periodicity = 3; + in.lte_system_information_request.si_periodicity[0].si_index = 0; + in.lte_system_information_request.si_window_length = 0; + in.lte_system_information_request.timeout = 2000; + + in.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + in.pnf_cell_broadcast_state.length = 7; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.lte_system_information_request.tl.tag, out.lte_system_information_request.tl.tag); + CU_ASSERT_EQUAL(in.lte_system_information_request.earfcn, out.lte_system_information_request.earfcn); + CU_ASSERT_EQUAL(in.lte_system_information_request.pci, out.lte_system_information_request.pci); + CU_ASSERT_EQUAL(in.lte_system_information_request.downlink_channel_bandwidth, out.lte_system_information_request.downlink_channel_bandwidth); + CU_ASSERT_EQUAL(in.lte_system_information_request.downlink_channel_bandwidth, out.lte_system_information_request.downlink_channel_bandwidth); + CU_ASSERT_EQUAL(in.lte_system_information_request.number_of_tx_antenna, out.lte_system_information_request.number_of_tx_antenna); + CU_ASSERT_EQUAL(in.lte_system_information_request.number_of_si_periodicity, out.lte_system_information_request.number_of_si_periodicity); + for(idx = 0; idx < in.lte_system_information_request.number_of_si_periodicity; ++idx) + { + CU_ASSERT_EQUAL(in.lte_system_information_request.si_periodicity[idx].si_periodicity, out.lte_system_information_request.si_periodicity[idx].si_periodicity); + CU_ASSERT_EQUAL(in.lte_system_information_request.si_periodicity[idx].si_index, out.lte_system_information_request.si_periodicity[idx].si_index); + } + + CU_ASSERT_EQUAL(in.lte_system_information_request.si_window_length, out.lte_system_information_request.si_window_length); + CU_ASSERT_EQUAL(in.lte_system_information_request.timeout, out.lte_system_information_request.timeout); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.length, out.pnf_cell_broadcast_state.length); + for(idx = 0; idx < out.pnf_cell_broadcast_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.value[idx], out.pnf_cell_broadcast_state.value[idx]); + } +} +void nfapi_test_system_information_request_lte_overrun() +{ + nfapi_system_information_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_LTE, &p, end); + + push16(NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &p, end); + push16(8, &p, end); + + push16(8, &p, end); + push16(8, &p, end); + push16(8, &p, end); + push8(8, &p, end); + push8(8, &p, end); + push8(NFAPI_MAX_SI_PERIODICITY + 1, &p, end); + + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_system_information_request_utran() +{ + nfapi_system_information_request_t in; + nfapi_system_information_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_UTRAN; + + in.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG; + in.utran_system_information_request.uarfcn = 16; + in.utran_system_information_request.psc = 4; + in.utran_system_information_request.timeout = 2000; + + in.pnf_cell_broadcast_state.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.utran_system_information_request.tl.tag, out.utran_system_information_request.tl.tag); + CU_ASSERT_EQUAL(in.utran_system_information_request.uarfcn, out.utran_system_information_request.uarfcn); + CU_ASSERT_EQUAL(in.utran_system_information_request.psc, out.utran_system_information_request.psc); + CU_ASSERT_EQUAL(in.utran_system_information_request.timeout, out.utran_system_information_request.timeout); + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); +} +void nfapi_test_system_information_request_geran() +{ + nfapi_system_information_request_t in; + nfapi_system_information_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_GERAN; + + in.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG; + in.geran_system_information_request.arfcn = 16; + in.geran_system_information_request.bsic = 4; + in.geran_system_information_request.timeout = 2000; + + in.pnf_cell_broadcast_state.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.rat_type, out.rat_type); + CU_ASSERT_EQUAL(in.geran_system_information_request.tl.tag, out.geran_system_information_request.tl.tag); + CU_ASSERT_EQUAL(in.geran_system_information_request.arfcn, out.geran_system_information_request.arfcn); + CU_ASSERT_EQUAL(in.geran_system_information_request.bsic, out.geran_system_information_request.bsic); + CU_ASSERT_EQUAL(in.geran_system_information_request.timeout, out.geran_system_information_request.timeout); + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); +} +void nfapi_test_system_information_request_state_overrun() +{ + nfapi_system_information_request_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_REQUEST, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push8(NFAPI_RAT_TYPE_LTE, &p, end); + + push16(NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG, &p, end); + push16(16, &p, end); + + push16(8, &p, end); + push16(8, &p, end); + push16(8, &p, end); + push8(8, &p, end); + push8(8, &p, end); + push8(1, &p, end); + { + push8(1, &p, end); + push8(1, &p, end); + } + push8(1, &p, end); + push32(1, &p, end); + + push16(NFAPI_PNF_CELL_BROADCAST_STATE_TAG, &p, end); + push16(NFAPI_MAX_OPAQUE_DATA + 1, &p, end); + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_system_information_request_nb_iot() +{ + uint16_t idx, idx2; + nfapi_system_information_request_t in; + nfapi_system_information_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.rat_type = NFAPI_RAT_TYPE_NB_IOT; + + in.nb_iot_system_information_request.tl.tag = NFAPI_NB_IOT_SYSTEM_INFORMATION_REQUEST_TAG; + in.nb_iot_system_information_request.earfcn = 16; + in.nb_iot_system_information_request.ro_dl = 1; + in.nb_iot_system_information_request.pci = 4; + in.nb_iot_system_information_request.number_of_si_periodicity = 1; + in.nb_iot_system_information_request.si_periodicity[0].si_periodicity = 3; + in.nb_iot_system_information_request.si_periodicity[0].si_repetition_pattern = 0; + in.nb_iot_system_information_request.si_periodicity[0].si_tb_size = 0; + in.nb_iot_system_information_request.si_periodicity[0].number_of_si_index = 2; + in.nb_iot_system_information_request.si_periodicity[0].si_index[0] = 2; + in.nb_iot_system_information_request.si_periodicity[0].si_index[1] = 20; + in.nb_iot_system_information_request.si_window_length = 0; + in.nb_iot_system_information_request.timeout = 2000; + + in.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + in.pnf_cell_broadcast_state.length = 7; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + IN_OUT_ASSERT(header.message_id); + IN_OUT_ASSERT(rat_type); + IN_OUT_ASSERT(nb_iot_system_information_request.tl.tag); + IN_OUT_ASSERT(nb_iot_system_information_request.earfcn); + IN_OUT_ASSERT(nb_iot_system_information_request.ro_dl); + IN_OUT_ASSERT(nb_iot_system_information_request.pci); + IN_OUT_ASSERT(nb_iot_system_information_request.number_of_si_periodicity); + + for(idx = 0; idx < in.nb_iot_system_information_request.number_of_si_periodicity; ++idx) + { + IN_OUT_ASSERT(nb_iot_system_information_request.si_periodicity[idx].si_periodicity); + IN_OUT_ASSERT(nb_iot_system_information_request.si_periodicity[idx].si_repetition_pattern); + IN_OUT_ASSERT(nb_iot_system_information_request.si_periodicity[idx].si_tb_size); + IN_OUT_ASSERT(nb_iot_system_information_request.si_periodicity[idx].number_of_si_index); + + for(idx2 = 0; idx2 < in.nb_iot_system_information_request.si_periodicity[idx].number_of_si_index; ++idx2) + IN_OUT_ASSERT(nb_iot_system_information_request.si_periodicity[idx].si_index[idx2]); + } + + IN_OUT_ASSERT(nb_iot_system_information_request.si_window_length); + IN_OUT_ASSERT(nb_iot_system_information_request.timeout); + + + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.tl.tag, out.pnf_cell_broadcast_state.tl.tag); + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.length, out.pnf_cell_broadcast_state.length); + for(idx = 0; idx < out.pnf_cell_broadcast_state.length; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_cell_broadcast_state.value[idx], out.pnf_cell_broadcast_state.value[idx]); + } +} + + +void nfapi_test_system_information_response() +{ + nfapi_system_information_response_t in; + nfapi_system_information_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_system_information_indication_lte() +{ + uint16_t idx; + nfapi_system_information_indication_t in; + nfapi_system_information_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + in.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + in.lte_system_information_indication.sib_type = 2; + in.lte_system_information_indication.sib_length = 15; + + in.utran_system_information_indication.tl.tag = 0; + in.geran_system_information_indication.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib_type, out.lte_system_information_indication.sib_type); + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib_length, out.lte_system_information_indication.sib_length); + + for(idx = 0; idx < out.lte_system_information_indication.sib_length; ++idx) + { + CU_ASSERT_EQUAL(in.lte_system_information_indication.sib[idx], out.lte_system_information_indication.sib[idx]); + } + + CU_ASSERT_EQUAL(in.utran_system_information_indication.tl.tag, out.utran_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_system_information_indication.tl.tag, out.geran_system_information_indication.tl.tag); + +} +void nfapi_test_system_information_indication_lte_overrun() +{ + nfapi_system_information_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error code + + push16(NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push8(1, &p, end); + push16(NFAPI_MAX_SIB_LENGTH + 1, &p, end); + + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_system_information_indication_utran() +{ + uint16_t idx; + nfapi_system_information_indication_t in; + nfapi_system_information_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + in.lte_system_information_indication.tl.tag = 0; + + in.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; + in.utran_system_information_indication.sib_length = 25; + + in.geran_system_information_indication.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_system_information_indication.tl.tag, out.utran_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_system_information_indication.sib_length, out.utran_system_information_indication.sib_length); + + for(idx = 0; idx < out.utran_system_information_indication.sib_length; ++idx) + { + CU_ASSERT_EQUAL(in.utran_system_information_indication.sib[idx], out.utran_system_information_indication.sib[idx]); + } + + CU_ASSERT_EQUAL(in.geran_system_information_indication.tl.tag, out.geran_system_information_indication.tl.tag); + +} +void nfapi_test_system_information_indication_utran_overrun() +{ + nfapi_system_information_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error code + + push16(NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_SIB_LENGTH + 1, &p, end); + + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} +void nfapi_test_system_information_indication_geran() +{ + uint16_t idx; + nfapi_system_information_indication_t in; + nfapi_system_information_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + in.lte_system_information_indication.tl.tag = 0; + in.utran_system_information_indication.tl.tag = 0; + + in.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; + in.geran_system_information_indication.si_length = 25; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_system_information_indication.tl.tag, out.utran_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_system_information_indication.tl.tag, out.geran_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_system_information_indication.si_length, out.geran_system_information_indication.si_length); + + for(idx = 0; idx < out.geran_system_information_indication.si_length; ++idx) + { + CU_ASSERT_EQUAL(in.geran_system_information_indication.si[idx], out.geran_system_information_indication.si[idx]); + } + +} +void nfapi_test_system_information_indication_geran_overrun() +{ + nfapi_system_information_indication_t out; + + uint8_t buffer[1024]; + uint8_t* p = &buffer[0]; + uint8_t *end = p + 1024; + push16(0, &p, end); + push16(NFAPI_SYSTEM_INFORMATION_INDICATION, &p, end); + push16(64, &p, end); + push16(0, &p, end); + + push32(0, &p, end); // error code + + push16(NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG, &p, end); + push16(8, &p, end); + + push16(NFAPI_MAX_SI_LENGTH + 1, &p, end); + + + int result = nfapi_p4_message_unpack(buffer, 34, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(result, -1); +} + +void nfapi_test_system_information_indication_nb_iot() +{ + uint16_t idx; + nfapi_system_information_indication_t in; + nfapi_system_information_indication_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + in.nb_iot_system_information_indication.tl.tag = NFAPI_NB_IOT_SYSTEM_INFORMATION_INDICATION_TAG; + in.nb_iot_system_information_indication.sib_type = 2; + in.nb_iot_system_information_indication.sib_length = 15; + + in.lte_system_information_indication.tl.tag = 0; + in.utran_system_information_indication.tl.tag = 0; + in.geran_system_information_indication.tl.tag = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.tl.tag, out.nb_iot_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib_type, out.nb_iot_system_information_indication.sib_type); + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib_length, out.nb_iot_system_information_indication.sib_length); + + for(idx = 0; idx < out.nb_iot_system_information_indication.sib_length; ++idx) + { + CU_ASSERT_EQUAL(in.nb_iot_system_information_indication.sib[idx], out.nb_iot_system_information_indication.sib[idx]); + } + + CU_ASSERT_EQUAL(in.lte_system_information_indication.tl.tag, out.lte_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.utran_system_information_indication.tl.tag, out.utran_system_information_indication.tl.tag); + CU_ASSERT_EQUAL(in.geran_system_information_indication.tl.tag, out.geran_system_information_indication.tl.tag); + +} + +void nfapi_test_nmm_stop_request() +{ + nfapi_nmm_stop_request_t in; + nfapi_nmm_stop_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_NMM_STOP_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} +void nfapi_test_nmm_stop_response() +{ + nfapi_nmm_stop_response_t in; + nfapi_nmm_stop_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_NMM_STOP_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_P4_MSG_RAT_NOT_SUPPORTED; + + int packedMessageLength = nfapi_p4_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p4_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} + + +void nfapi_test_pnf_param_request() +{ + nfapi_pnf_param_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_param_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_PARAM_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} +void nfapi_test_pnf_param_request_ve() +{ + nfapi_pnf_param_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_param_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_PARAM_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + my_vendor_extention ve; + ve.tl.tag = NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE; + ve.value1 = 56; + ve.value2 = 1234; + in.vendor_extension = (void*)&ve; + + nfapi_p4_p5_codec_config_t codec; + memset(&codec, 0, sizeof(codec)); + codec.unpack_vendor_extension_tlv = &nfapi_test_unpack_vendor_extension_tlv; + codec.pack_vendor_extension_tlv = &nfapi_test_pack_vendor_extension_tlv; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, &codec); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), &codec); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + + CU_ASSERT_NOT_EQUAL(in.vendor_extension, 0); + CU_ASSERT_EQUAL(((my_vendor_extention*)(out.vendor_extension))->tl.tag, ve.tl.tag); + CU_ASSERT_EQUAL(((my_vendor_extention*)(out.vendor_extension))->value1, ve.value1); + CU_ASSERT_EQUAL(((my_vendor_extention*)(out.vendor_extension))->value2, ve.value2); + + free(out.vendor_extension); +} +void nfapi_test_pnf_param_response() +{ + uint16_t idx = 0; + uint16_t idx2 = 0; + nfapi_pnf_param_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_param_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = 0; + in.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + in.pnf_param_general.nfapi_sync_mode = 2; + in.pnf_param_general.location_mode = 1; + in.pnf_param_general.location_coordinates_length = 1; + in.pnf_param_general.location_coordinates[0] = 123; + in.pnf_param_general.dl_config_timing = 12; + in.pnf_param_general.tx_timing = 12; + in.pnf_param_general.ul_config_timing = 12; + in.pnf_param_general.hi_dci0_timing = 12; + in.pnf_param_general.maximum_number_phys = 2; + in.pnf_param_general.maximum_total_bandwidth = 100; + in.pnf_param_general.maximum_total_number_dl_layers = 2; + in.pnf_param_general.maximum_total_number_ul_layers = 2; + in.pnf_param_general.shared_bands = 0; + in.pnf_param_general.shared_pa = 0; + in.pnf_param_general.maximum_total_power = -190; + in.pnf_param_general.oui[0] = 88; + + in.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + in.pnf_phy.number_of_phys = 2; + in.pnf_phy.phy[0].phy_config_index = 0; + in.pnf_phy.phy[0].number_of_rfs = 2; + in.pnf_phy.phy[0].rf_config[0].rf_config_index = 0; + in.pnf_phy.phy[0].number_of_rf_exclusions = 1; + in.pnf_phy.phy[0].rf_config[0].rf_config_index = 1; + in.pnf_phy.phy[0].downlink_channel_bandwidth_supported = 20; + in.pnf_phy.phy[0].uplink_channel_bandwidth_supported = 20; + in.pnf_phy.phy[0].number_of_dl_layers_supported = 2; + in.pnf_phy.phy[0].number_of_ul_layers_supported = 1; + in.pnf_phy.phy[0].maximum_3gpp_release_supported = 3; + in.pnf_phy.phy[0].nmm_modes_supported = 2; + + in.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG; + in.pnf_rf.number_of_rfs = 2; + in.pnf_rf.rf[0].rf_config_index = 0; + in.pnf_rf.rf[0].band = 1; + in.pnf_rf.rf[0].maximum_transmit_power = -100; + in.pnf_rf.rf[0].minimum_transmit_power = -90; + in.pnf_rf.rf[0].number_of_antennas_suppported = 4; + in.pnf_rf.rf[0].minimum_downlink_frequency = 100; + in.pnf_rf.rf[0].maximum_downlink_frequency = 2132; + in.pnf_rf.rf[0].minimum_uplink_frequency = 1231; + in.pnf_rf.rf[0].maximum_uplink_frequency = 123; + + + in.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; + in.pnf_phy_rel10.number_of_phys = 2; + in.pnf_phy_rel10.phy[0].phy_config_index = 0; + in.pnf_phy_rel10.phy[0].transmission_mode_7_supported = 1; + in.pnf_phy_rel10.phy[0].transmission_mode_8_supported = 2; + in.pnf_phy_rel10.phy[0].two_antenna_ports_for_pucch = 3; + in.pnf_phy_rel10.phy[0].transmission_mode_9_supported = 4; + in.pnf_phy_rel10.phy[0].simultaneous_pucch_pusch = 5; + in.pnf_phy_rel10.phy[0].four_layer_tx_with_tm3_and_tm4 = 6; + + in.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG; + in.pnf_phy_rel11.number_of_phys = 2; + in.pnf_phy_rel11.phy[0].phy_config_index = 0; + in.pnf_phy_rel11.phy[0].edpcch_supported = 1; + in.pnf_phy_rel11.phy[0].multi_ack_csi_reporting = 2; + in.pnf_phy_rel11.phy[0].pucch_tx_diversity = 3; + in.pnf_phy_rel11.phy[0].ul_comp_supported = 4; + in.pnf_phy_rel11.phy[0].transmission_mode_5_supported = 5; + + in.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG; + in.pnf_phy_rel12.number_of_phys = 2; + in.pnf_phy_rel12.phy[0].phy_config_index = 0; + in.pnf_phy_rel12.phy[0].csi_subframe_set = 1; + in.pnf_phy_rel12.phy[0].enhanced_4tx_codebook = 2; + in.pnf_phy_rel12.phy[0].drs_supported = 3; + in.pnf_phy_rel12.phy[0].ul_64qam_supported = 4; + in.pnf_phy_rel12.phy[0].transmission_mode_10_supported = 5; + in.pnf_phy_rel12.phy[0].alternative_bts_indices = 6; + + in.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG; + in.pnf_phy_rel13.number_of_phys = 2; + in.pnf_phy_rel13.phy[0].phy_config_index = 0; + in.pnf_phy_rel13.phy[0].pucch_format4_supported = 1; + in.pnf_phy_rel13.phy[0].pucch_format5_supported = 2; + in.pnf_phy_rel13.phy[0].more_than_5_ca_support = 3; + in.pnf_phy_rel13.phy[0].laa_supported = 4; + in.pnf_phy_rel13.phy[0].laa_ending_in_dwpts_supported = 5; + in.pnf_phy_rel13.phy[0].laa_starting_in_second_slot_supported = 6; + in.pnf_phy_rel13.phy[0].beamforming_supported = 7; + in.pnf_phy_rel13.phy[0].csi_rs_enhancement_supported = 8; + in.pnf_phy_rel13.phy[0].drms_enhancement_supported = 9; + in.pnf_phy_rel13.phy[0].srs_enhancement_supported = 10; + + in.pnf_phy_rel13_nb_iot.tl.tag = NFAPI_PNF_PHY_REL13_NB_IOT_TAG; + in.pnf_phy_rel13_nb_iot.number_of_phys = 2; + in.pnf_phy_rel13_nb_iot.phy[0].phy_config_index = 0; + in.pnf_phy_rel13_nb_iot.phy[0].number_of_rfs = 2; + in.pnf_phy_rel13_nb_iot.phy[0].rf_config[0].rf_config_index = 0; + in.pnf_phy_rel13_nb_iot.phy[0].number_of_rf_exclusions = 1; + in.pnf_phy_rel13_nb_iot.phy[0].rf_config[0].rf_config_index = 1; + in.pnf_phy_rel13_nb_iot.phy[0].number_of_dl_layers_supported = 2; + in.pnf_phy_rel13_nb_iot.phy[0].number_of_ul_layers_supported = 1; + in.pnf_phy_rel13_nb_iot.phy[0].maximum_3gpp_release_supported = 3; + in.pnf_phy_rel13_nb_iot.phy[0].nmm_modes_supported = 2; + + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpack_result = nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(unpack_result, 1); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.pnf_param_general.tl.tag, out.pnf_param_general.tl.tag); + CU_ASSERT_EQUAL(in.pnf_param_general.nfapi_sync_mode, out.pnf_param_general.nfapi_sync_mode); + CU_ASSERT_EQUAL(in.pnf_param_general.location_mode, out.pnf_param_general.location_mode); + + for(idx = 0; idx < NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH; ++idx) + CU_ASSERT_EQUAL(in.pnf_param_general.location_coordinates[idx], out.pnf_param_general.location_coordinates[idx]); + + CU_ASSERT_EQUAL(in.pnf_param_general.dl_config_timing, out.pnf_param_general.dl_config_timing); + CU_ASSERT_EQUAL(in.pnf_param_general.tx_timing, out.pnf_param_general.tx_timing); + CU_ASSERT_EQUAL(in.pnf_param_general.ul_config_timing, out.pnf_param_general.ul_config_timing); + CU_ASSERT_EQUAL(in.pnf_param_general.hi_dci0_timing, out.pnf_param_general.hi_dci0_timing); + CU_ASSERT_EQUAL(in.pnf_param_general.maximum_number_phys, out.pnf_param_general.maximum_number_phys); + CU_ASSERT_EQUAL(in.pnf_param_general.maximum_total_bandwidth, out.pnf_param_general.maximum_total_bandwidth); + CU_ASSERT_EQUAL(in.pnf_param_general.maximum_total_number_dl_layers, out.pnf_param_general.maximum_total_number_dl_layers); + CU_ASSERT_EQUAL(in.pnf_param_general.maximum_total_number_ul_layers, out.pnf_param_general.maximum_total_number_ul_layers); + CU_ASSERT_EQUAL(in.pnf_param_general.shared_bands, out.pnf_param_general.shared_bands); + CU_ASSERT_EQUAL(in.pnf_param_general.shared_pa, out.pnf_param_general.shared_pa); + CU_ASSERT_EQUAL(in.pnf_param_general.maximum_total_power, out.pnf_param_general.maximum_total_power); + for(idx = 0; idx < NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH; ++idx) + CU_ASSERT_EQUAL(in.pnf_param_general.oui[idx], out.pnf_param_general.oui[idx]); + + CU_ASSERT_EQUAL(in.pnf_phy.tl.tag, out.pnf_phy.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy.number_of_phys, out.pnf_phy.number_of_phys); + + for(idx = 0; idx < out.pnf_phy.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].phy_config_index, out.pnf_phy.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].number_of_rfs, out.pnf_phy.phy[idx].number_of_rfs); + + + for(idx2 = 0; idx2 < out.pnf_phy.phy[idx].number_of_rfs; ++idx2) + { + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].rf_config[idx2].rf_config_index, out.pnf_phy.phy[idx].rf_config[idx2].rf_config_index); + } + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].number_of_rf_exclusions, out.pnf_phy.phy[idx].number_of_rf_exclusions); + + for(idx2 = 0; idx2 < out.pnf_phy.phy[idx].number_of_rf_exclusions; ++idx2) + { + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].excluded_rf_config[idx2].rf_config_index, out.pnf_phy.phy[idx].excluded_rf_config[idx2].rf_config_index); + } + + + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].downlink_channel_bandwidth_supported, out.pnf_phy.phy[idx].downlink_channel_bandwidth_supported); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].uplink_channel_bandwidth_supported, out.pnf_phy.phy[idx].uplink_channel_bandwidth_supported); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].number_of_dl_layers_supported, out.pnf_phy.phy[idx].number_of_dl_layers_supported); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].number_of_ul_layers_supported, out.pnf_phy.phy[idx].number_of_ul_layers_supported); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].maximum_3gpp_release_supported, out.pnf_phy.phy[idx].maximum_3gpp_release_supported); + CU_ASSERT_EQUAL(in.pnf_phy.phy[idx].nmm_modes_supported, out.pnf_phy.phy[idx].nmm_modes_supported); + } + + CU_ASSERT_EQUAL(in.pnf_rf.tl.tag, out.pnf_rf.tl.tag); + CU_ASSERT_EQUAL(in.pnf_rf.number_of_rfs, out.pnf_rf.number_of_rfs); + for(idx = 0; idx < out.pnf_rf.number_of_rfs; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].rf_config_index, out.pnf_rf.rf[idx].rf_config_index); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].band, out.pnf_rf.rf[idx].band); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].maximum_transmit_power, out.pnf_rf.rf[idx].maximum_transmit_power); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].minimum_transmit_power, out.pnf_rf.rf[idx].minimum_transmit_power); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].number_of_antennas_suppported, out.pnf_rf.rf[idx].number_of_antennas_suppported); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].minimum_downlink_frequency, out.pnf_rf.rf[idx].minimum_downlink_frequency); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].maximum_downlink_frequency, out.pnf_rf.rf[idx].maximum_downlink_frequency); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].minimum_uplink_frequency, out.pnf_rf.rf[idx].minimum_uplink_frequency); + CU_ASSERT_EQUAL(in.pnf_rf.rf[idx].maximum_uplink_frequency, out.pnf_rf.rf[idx].maximum_uplink_frequency); + } + + + CU_ASSERT_EQUAL(in.pnf_phy_rel10.tl.tag, out.pnf_phy_rel10.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.number_of_phys, out.pnf_phy_rel10.number_of_phys); + for(idx = 0; idx < out.pnf_phy_rel10.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].phy_config_index, out.pnf_phy_rel10.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].transmission_mode_7_supported, out.pnf_phy_rel10.phy[idx].transmission_mode_7_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].transmission_mode_8_supported, out.pnf_phy_rel10.phy[idx].transmission_mode_8_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].two_antenna_ports_for_pucch, out.pnf_phy_rel10.phy[idx].two_antenna_ports_for_pucch); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].transmission_mode_9_supported, out.pnf_phy_rel10.phy[idx].transmission_mode_9_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].simultaneous_pucch_pusch, out.pnf_phy_rel10.phy[idx].simultaneous_pucch_pusch); + CU_ASSERT_EQUAL(in.pnf_phy_rel10.phy[idx].four_layer_tx_with_tm3_and_tm4, out.pnf_phy_rel10.phy[idx].four_layer_tx_with_tm3_and_tm4); + } + + CU_ASSERT_EQUAL(in.pnf_phy_rel11.tl.tag, out.pnf_phy_rel11.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.number_of_phys, out.pnf_phy_rel11.number_of_phys); + for(idx = 0; idx < out.pnf_phy_rel11.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].phy_config_index, out.pnf_phy_rel11.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].edpcch_supported, out.pnf_phy_rel11.phy[idx].edpcch_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].multi_ack_csi_reporting, out.pnf_phy_rel11.phy[idx].multi_ack_csi_reporting); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].pucch_tx_diversity, out.pnf_phy_rel11.phy[idx].pucch_tx_diversity); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].ul_comp_supported, out.pnf_phy_rel11.phy[idx].ul_comp_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel11.phy[idx].transmission_mode_5_supported, out.pnf_phy_rel11.phy[idx].transmission_mode_5_supported); + } + + CU_ASSERT_EQUAL(in.pnf_phy_rel12.tl.tag, out.pnf_phy_rel12.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.number_of_phys, out.pnf_phy_rel12.number_of_phys); + for(idx = 0; idx < out.pnf_phy_rel12.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].phy_config_index, out.pnf_phy_rel12.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].csi_subframe_set, out.pnf_phy_rel12.phy[idx].csi_subframe_set); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].enhanced_4tx_codebook, out.pnf_phy_rel12.phy[idx].enhanced_4tx_codebook); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].drs_supported, out.pnf_phy_rel12.phy[idx].drs_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].ul_64qam_supported, out.pnf_phy_rel12.phy[idx].ul_64qam_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].transmission_mode_10_supported, out.pnf_phy_rel12.phy[idx].transmission_mode_10_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel12.phy[idx].alternative_bts_indices, out.pnf_phy_rel12.phy[idx].alternative_bts_indices); + } + + CU_ASSERT_EQUAL(in.pnf_phy_rel13.tl.tag, out.pnf_phy_rel13.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.number_of_phys, out.pnf_phy_rel13.number_of_phys); + for(idx = 0; idx < out.pnf_phy_rel13.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].phy_config_index, out.pnf_phy_rel13.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].pucch_format4_supported, out.pnf_phy_rel13.phy[idx].pucch_format4_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].pucch_format5_supported, out.pnf_phy_rel13.phy[idx].pucch_format5_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].more_than_5_ca_support, out.pnf_phy_rel13.phy[idx].more_than_5_ca_support); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].laa_supported, out.pnf_phy_rel13.phy[idx].laa_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].laa_ending_in_dwpts_supported, out.pnf_phy_rel13.phy[idx].laa_ending_in_dwpts_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].laa_starting_in_second_slot_supported, out.pnf_phy_rel13.phy[idx].laa_starting_in_second_slot_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].beamforming_supported, out.pnf_phy_rel13.phy[idx].beamforming_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].csi_rs_enhancement_supported, out.pnf_phy_rel13.phy[idx].csi_rs_enhancement_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].drms_enhancement_supported, out.pnf_phy_rel13.phy[idx].drms_enhancement_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13.phy[idx].srs_enhancement_supported, out.pnf_phy_rel13.phy[idx].srs_enhancement_supported); + } + + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.tl.tag, out.pnf_phy_rel13_nb_iot.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.number_of_phys, out.pnf_phy_rel13_nb_iot.number_of_phys); + + for(idx = 0; idx < out.pnf_phy_rel13_nb_iot.number_of_phys; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].phy_config_index, out.pnf_phy_rel13_nb_iot.phy[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].number_of_rfs, out.pnf_phy_rel13_nb_iot.phy[idx].number_of_rfs); + + + for(idx2 = 0; idx2 < out.pnf_phy_rel13_nb_iot.phy[idx].number_of_rfs; ++idx2) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].rf_config[idx2].rf_config_index, out.pnf_phy_rel13_nb_iot.phy[idx].rf_config[idx2].rf_config_index); + } + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].number_of_rf_exclusions, out.pnf_phy_rel13_nb_iot.phy[idx].number_of_rf_exclusions); + + for(idx2 = 0; idx2 < out.pnf_phy_rel13_nb_iot.phy[idx].number_of_rf_exclusions; ++idx2) + { + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].excluded_rf_config[idx2].rf_config_index, out.pnf_phy_rel13_nb_iot.phy[idx].excluded_rf_config[idx2].rf_config_index); + } + + + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].number_of_dl_layers_supported, out.pnf_phy_rel13_nb_iot.phy[idx].number_of_dl_layers_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].number_of_ul_layers_supported, out.pnf_phy_rel13_nb_iot.phy[idx].number_of_ul_layers_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].maximum_3gpp_release_supported, out.pnf_phy_rel13_nb_iot.phy[idx].maximum_3gpp_release_supported); + CU_ASSERT_EQUAL(in.pnf_phy_rel13_nb_iot.phy[idx].nmm_modes_supported, out.pnf_phy_rel13_nb_iot.phy[idx].nmm_modes_supported); + } + + +} + +void nfapi_test_pnf_config_request() +{ + uint16_t idx; + nfapi_pnf_config_request_t in; + nfapi_pnf_config_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + in.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + in.pnf_phy_rf_config.number_phy_rf_config_info = 2; + in.pnf_phy_rf_config.phy_rf_config[0].phy_id = 0; + in.pnf_phy_rf_config.phy_rf_config[0].phy_config_index = 0; + in.pnf_phy_rf_config.phy_rf_config[0].rf_config_index = 0; + + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + int unpack_result = nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(unpack_result, 1); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + //CU_ASSERT_EQUAL(in.error_code, out.error_code); + + CU_ASSERT_EQUAL(in.pnf_phy_rf_config.tl.tag, out.pnf_phy_rf_config.tl.tag); + CU_ASSERT_EQUAL(in.pnf_phy_rf_config.number_phy_rf_config_info, out.pnf_phy_rf_config.number_phy_rf_config_info); + + for(idx = 0; idx < out.pnf_phy_rf_config.number_phy_rf_config_info; ++idx) + { + CU_ASSERT_EQUAL(in.pnf_phy_rf_config.phy_rf_config[idx].phy_id, out.pnf_phy_rf_config.phy_rf_config[idx].phy_id); + CU_ASSERT_EQUAL(in.pnf_phy_rf_config.phy_rf_config[idx].phy_config_index, out.pnf_phy_rf_config.phy_rf_config[idx].phy_config_index); + CU_ASSERT_EQUAL(in.pnf_phy_rf_config.phy_rf_config[idx].rf_config_index, out.pnf_phy_rf_config.phy_rf_config[idx].rf_config_index); + } +} + + + +void nfapi_test_pnf_config_response() +{ + nfapi_pnf_config_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_config_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_pnf_config_response1() +{ + uint8_t buffer[NFAPI_HEADER_LENGTH + 1]; + + nfapi_pnf_config_response_t in; + memset(&in, 0, sizeof(in)); + //nfapi_pnf_config_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), buffer, sizeof(buffer), 0); + CU_ASSERT_EQUAL(packedMessageLength, -1); + + //nfapi_p5_message_unpack(buffer, sizeof(buffer), &out, sizeof(out), 0); + //CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + //CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_pnf_start_request() +{ + nfapi_pnf_start_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_start_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_START_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} + +void nfapi_test_pnf_start_response() +{ + nfapi_pnf_start_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_start_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_START_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_pnf_stop_request() +{ + nfapi_pnf_stop_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_stop_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_STOP_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} +void nfapi_test_pnf_stop_response() +{ + nfapi_pnf_stop_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_pnf_stop_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PNF_STOP_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} + +void nfapi_test_param_request() +{ + nfapi_param_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_param_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PARAM_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} +void nfapi_test_param_response() +{ + #define SET_TLV(_TLV, _TAG, _VALUE) { _TLV.tl.tag = _TAG; _TLV.value = _VALUE; num_tlv++; } + #define ASSERT_TLV(IN_TLV, OUT_TLV) { CU_ASSERT_EQUAL(IN_TLV.tl.tag, OUT_TLV.tl.tag); CU_ASSERT_EQUAL(IN_TLV.value, OUT_TLV.value);} + + nfapi_param_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_param_response_t out; + memset(&out, 0, sizeof(out)); + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_PARAM_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + uint16_t idx = 0; + uint16_t num_tlv = 0; // Bit of a hack, it is incremented in the SET_UINT16_TLV macro + + SET_TLV(in.l1_status.phy_state, NFAPI_L1_STATUS_PHY_STATE_TAG, 1); + SET_TLV(in.phy_capabilities.dl_bandwidth_support, NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 63); + SET_TLV(in.phy_capabilities.ul_bandwidth_support, NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 63); + SET_TLV(in.phy_capabilities.dl_modulation_support, NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG, 3); + SET_TLV(in.phy_capabilities.ul_modulation_support, NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG, 3); + SET_TLV(in.phy_capabilities.phy_antenna_capability, NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG, 8); + SET_TLV(in.phy_capabilities.release_capability, NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG, 63); + SET_TLV(in.phy_capabilities.mbsfn_capability, NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG, 0); + + SET_TLV(in.laa_capability.laa_support, NFAPI_LAA_CAPABILITY_LAA_SUPPORT_TAG, 1); + SET_TLV(in.laa_capability.pd_sensing_lbt_support, NFAPI_LAA_CAPABILITY_PD_SENSING_LBT_SUPPORT_TAG, 0); + SET_TLV(in.laa_capability.multi_carrier_lbt_support, NFAPI_LAA_CAPABILITY_MULTI_CARRIER_LBT_SUPPORT_TAG, 3); + SET_TLV(in.laa_capability.partial_sf_support, NFAPI_LAA_CAPABILITY_PARTIAL_SF_SUPPORT_TAG, 2); + + SET_TLV(in.subframe_config.duplex_mode, NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, 1); + SET_TLV(in.subframe_config.pcfich_power_offset, NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, 1000); + SET_TLV(in.subframe_config.pb, NFAPI_SUBFRAME_CONFIG_PB_TAG, 1); + SET_TLV(in.subframe_config.dl_cyclic_prefix_type, NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, 0); + SET_TLV(in.subframe_config.ul_cyclic_prefix_type, NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, 0); + + SET_TLV(in.rf_config.dl_channel_bandwidth, NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, 50); + SET_TLV(in.rf_config.ul_channel_bandwidth, NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, 50); + SET_TLV(in.rf_config.reference_signal_power, NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, 120); + SET_TLV(in.rf_config.tx_antenna_ports, NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, 2); + SET_TLV(in.rf_config.rx_antenna_ports, NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, 2); + + SET_TLV(in.phich_config.phich_resource, NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, 3); + SET_TLV(in.phich_config.phich_duration, NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, 0); + SET_TLV(in.phich_config.phich_power_offset, NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, 500); + + SET_TLV(in.sch_config.primary_synchronization_signal_epre_eprers, NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, 1000); + SET_TLV(in.sch_config.secondary_synchronization_signal_epre_eprers, NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, 2000); + SET_TLV(in.sch_config.physical_cell_id, NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, 12344); + + + SET_TLV(in.prach_config.configuration_index, NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, 63); + SET_TLV(in.prach_config.root_sequence_index, NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, 800); + SET_TLV(in.prach_config.zero_correlation_zone_configuration, NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, 14); + SET_TLV(in.prach_config.high_speed_flag, NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, 0); + SET_TLV(in.prach_config.frequency_offset, NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, 23); + + SET_TLV(in.pusch_config.hopping_mode, NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, 0); + SET_TLV(in.pusch_config.hopping_offset, NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, 55); + SET_TLV(in.pusch_config.number_of_subbands, NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, 1); + + SET_TLV(in.pucch_config.delta_pucch_shift, NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, 2); + SET_TLV(in.pucch_config.n_cqi_rb, NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, 88); + SET_TLV(in.pucch_config.n_an_cs, NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, 3); + SET_TLV(in.pucch_config.n1_pucch_an, NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, 2015); + + SET_TLV(in.srs_config.bandwidth_configuration, NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, 3); + SET_TLV(in.srs_config.max_up_pts, NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, 0); + SET_TLV(in.srs_config.srs_subframe_configuration, NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, 11); + SET_TLV(in.srs_config.srs_acknack_srs_simultaneous_transmission, NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, 1); + + SET_TLV(in.uplink_reference_signal_config.uplink_rs_hopping, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, 2); + SET_TLV(in.uplink_reference_signal_config.group_assignment, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, 22); + SET_TLV(in.uplink_reference_signal_config.cyclic_shift_1_for_drms, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, 2); + + SET_TLV(in.tdd_frame_structure_config.subframe_assignment, NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, 5); + SET_TLV(in.tdd_frame_structure_config.special_subframe_patterns, NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, 3); + + SET_TLV(in.l23_config.data_report_mode, NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, 1); + SET_TLV(in.l23_config.sfnsf, NFAPI_L23_CONFIG_SFNSF_TAG, 12354); + + in.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + num_tlv++; + + in.nfapi_config.p7_vnf_address_ipv6.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG; + num_tlv++; + + SET_TLV(in.nfapi_config.p7_vnf_port, NFAPI_NFAPI_P7_VNF_PORT_TAG, 1111); + + in.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + num_tlv++; + + in.nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG; + num_tlv++; + + SET_TLV(in.nfapi_config.p7_pnf_port, NFAPI_NFAPI_P7_PNF_PORT_TAG, 9999); + SET_TLV(in.nfapi_config.dl_ue_per_sf, NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, 4); + SET_TLV(in.nfapi_config.ul_ue_per_sf, NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, 4); + + in.nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + in.nfapi_config.rf_bands.number_rf_bands = 2; + in.nfapi_config.rf_bands.rf_band[0] = 783; + num_tlv++; + + SET_TLV(in.nfapi_config.timing_window, NFAPI_NFAPI_TIMING_WINDOW_TAG, 29); + SET_TLV(in.nfapi_config.timing_info_mode, NFAPI_NFAPI_TIMING_INFO_MODE_TAG, 2); + SET_TLV(in.nfapi_config.timing_info_period, NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, 23); + SET_TLV(in.nfapi_config.max_transmit_power, NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, 123); + SET_TLV(in.nfapi_config.earfcn, NFAPI_NFAPI_EARFCN_TAG, 1800); + + in.nfapi_config.nmm_gsm_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands = 2; + num_tlv++; + + in.nfapi_config.nmm_umts_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands = 3; + num_tlv++; + + in.nfapi_config.nmm_lte_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands = 1; + num_tlv++; + + SET_TLV(in.nfapi_config.nmm_uplink_rssi_supported, NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, 1); + + + in.num_tlv = num_tlv; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + CU_ASSERT_EQUAL(in.num_tlv, out.num_tlv); + + ASSERT_TLV(in.l1_status.phy_state, out.l1_status.phy_state); + ASSERT_TLV(in.phy_capabilities.dl_bandwidth_support, out.phy_capabilities.dl_bandwidth_support); + ASSERT_TLV(in.phy_capabilities.ul_bandwidth_support, out.phy_capabilities.ul_bandwidth_support); + ASSERT_TLV(in.phy_capabilities.dl_modulation_support, out.phy_capabilities.dl_modulation_support); + ASSERT_TLV(in.phy_capabilities.ul_modulation_support, out.phy_capabilities.ul_modulation_support); + ASSERT_TLV(in.phy_capabilities.phy_antenna_capability, out.phy_capabilities.phy_antenna_capability); + ASSERT_TLV(in.phy_capabilities.release_capability, out.phy_capabilities.release_capability); + ASSERT_TLV(in.phy_capabilities.mbsfn_capability, out.phy_capabilities.mbsfn_capability); + + ASSERT_TLV(in.laa_capability.laa_support, in.laa_capability.laa_support); + ASSERT_TLV(in.laa_capability.pd_sensing_lbt_support, in.laa_capability.pd_sensing_lbt_support); + ASSERT_TLV(in.laa_capability.multi_carrier_lbt_support, in.laa_capability.multi_carrier_lbt_support); + ASSERT_TLV(in.laa_capability.partial_sf_support, in.laa_capability.partial_sf_support); + + ASSERT_TLV(in.subframe_config.duplex_mode, out.subframe_config.duplex_mode); + ASSERT_TLV(in.subframe_config.pcfich_power_offset, out.subframe_config.pcfich_power_offset); + ASSERT_TLV(in.subframe_config.pb, out.subframe_config.pb); + ASSERT_TLV(in.subframe_config.dl_cyclic_prefix_type, out.subframe_config.dl_cyclic_prefix_type); + ASSERT_TLV(in.subframe_config.ul_cyclic_prefix_type, out.subframe_config.ul_cyclic_prefix_type); + + ASSERT_TLV(in.rf_config.dl_channel_bandwidth, out.rf_config.dl_channel_bandwidth); + ASSERT_TLV(in.rf_config.ul_channel_bandwidth, out.rf_config.ul_channel_bandwidth); + ASSERT_TLV(in.rf_config.reference_signal_power, out.rf_config.reference_signal_power); + ASSERT_TLV(in.rf_config.tx_antenna_ports, out.rf_config.tx_antenna_ports); + ASSERT_TLV(in.rf_config.rx_antenna_ports, out.rf_config.rx_antenna_ports); + + ASSERT_TLV(in.phich_config.phich_resource, out.phich_config.phich_resource); + ASSERT_TLV(in.phich_config.phich_duration, out.phich_config.phich_duration); + ASSERT_TLV(in.phich_config.phich_power_offset, out.phich_config.phich_power_offset); + + ASSERT_TLV(in.sch_config.primary_synchronization_signal_epre_eprers, out.sch_config.primary_synchronization_signal_epre_eprers); + ASSERT_TLV(in.sch_config.secondary_synchronization_signal_epre_eprers, out.sch_config.secondary_synchronization_signal_epre_eprers); + ASSERT_TLV(in.sch_config.physical_cell_id, out.sch_config.physical_cell_id); + + + ASSERT_TLV(in.prach_config.configuration_index, out.prach_config.configuration_index); + ASSERT_TLV(in.prach_config.root_sequence_index, out.prach_config.root_sequence_index); + ASSERT_TLV(in.prach_config.zero_correlation_zone_configuration, out.prach_config.zero_correlation_zone_configuration); + ASSERT_TLV(in.prach_config.high_speed_flag, out.prach_config.high_speed_flag); + ASSERT_TLV(in.prach_config.frequency_offset, out.prach_config.frequency_offset); + + ASSERT_TLV(in.pusch_config.hopping_mode, in.pusch_config.hopping_mode); + ASSERT_TLV(in.pusch_config.hopping_offset, in.pusch_config.hopping_offset); + ASSERT_TLV(in.pusch_config.number_of_subbands, in.pusch_config.number_of_subbands); + + ASSERT_TLV(in.pucch_config.delta_pucch_shift, out.pucch_config.delta_pucch_shift); + ASSERT_TLV(in.pucch_config.n_cqi_rb, out.pucch_config.n_cqi_rb); + ASSERT_TLV(in.pucch_config.n_an_cs, out.pucch_config.n_an_cs); + ASSERT_TLV(in.pucch_config.n1_pucch_an, out.pucch_config.n1_pucch_an); + + ASSERT_TLV(in.srs_config.bandwidth_configuration, out.srs_config.bandwidth_configuration); + ASSERT_TLV(in.srs_config.max_up_pts, out.srs_config.max_up_pts); + ASSERT_TLV(in.srs_config.srs_subframe_configuration, out.srs_config.srs_subframe_configuration); + ASSERT_TLV(in.srs_config.srs_acknack_srs_simultaneous_transmission, out.srs_config.srs_acknack_srs_simultaneous_transmission); + + ASSERT_TLV(in.uplink_reference_signal_config.uplink_rs_hopping, out.uplink_reference_signal_config.uplink_rs_hopping); + ASSERT_TLV(in.uplink_reference_signal_config.group_assignment, out.uplink_reference_signal_config.group_assignment); + ASSERT_TLV(in.uplink_reference_signal_config.cyclic_shift_1_for_drms, out.uplink_reference_signal_config.cyclic_shift_1_for_drms); + + ASSERT_TLV(in.tdd_frame_structure_config.subframe_assignment, out.tdd_frame_structure_config.subframe_assignment); + ASSERT_TLV(in.tdd_frame_structure_config.special_subframe_patterns, out.tdd_frame_structure_config.special_subframe_patterns); + + ASSERT_TLV(in.l23_config.data_report_mode, out.l23_config.data_report_mode); + ASSERT_TLV(in.l23_config.sfnsf, out.l23_config.sfnsf); + + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv4.tl.tag, out.nfapi_config.p7_vnf_address_ipv4.tl.tag); + for(idx = 0; idx < NFAPI_IPV4_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv4.address[idx], out.nfapi_config.p7_vnf_address_ipv4.address[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv6.tl.tag, out.nfapi_config.p7_vnf_address_ipv6.tl.tag); + for(idx = 0; idx < NFAPI_IPV6_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv6.address[idx], out.nfapi_config.p7_vnf_address_ipv6.address[idx]); + } + + ASSERT_TLV(in.nfapi_config.p7_vnf_port, out.nfapi_config.p7_vnf_port); + + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv4.tl.tag, out.nfapi_config.p7_pnf_address_ipv4.tl.tag); + for(idx = 0; idx < NFAPI_IPV4_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv4.address[idx], out.nfapi_config.p7_pnf_address_ipv4.address[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv6.tl.tag, out.nfapi_config.p7_pnf_address_ipv6.tl.tag); + for(idx = 0; idx < NFAPI_IPV6_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv6.address[idx], out.nfapi_config.p7_pnf_address_ipv6.address[idx]); + } + + ASSERT_TLV(in.nfapi_config.p7_pnf_port, out.nfapi_config.p7_pnf_port); + ASSERT_TLV(in.nfapi_config.dl_ue_per_sf, out.nfapi_config.dl_ue_per_sf); + ASSERT_TLV(in.nfapi_config.ul_ue_per_sf, out.nfapi_config.ul_ue_per_sf); + + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.tl.tag, out.nfapi_config.rf_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.number_rf_bands, out.nfapi_config.rf_bands.number_rf_bands); + for(idx = 0; idx < out.nfapi_config.rf_bands.number_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.rf_band[idx], out.nfapi_config.rf_bands.rf_band[idx]); + } + + ASSERT_TLV(in.nfapi_config.timing_window, out.nfapi_config.timing_window); + ASSERT_TLV(in.nfapi_config.timing_info_mode, out.nfapi_config.timing_info_mode); + ASSERT_TLV(in.nfapi_config.timing_info_period, out.nfapi_config.timing_info_period); + ASSERT_TLV(in.nfapi_config.max_transmit_power, out.nfapi_config.max_transmit_power); + ASSERT_TLV(in.nfapi_config.earfcn, out.nfapi_config.earfcn); + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.tl.tag, out.nfapi_config.nmm_gsm_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.bands[idx], out.nfapi_config.nmm_gsm_frequency_bands.bands[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.tl.tag, out.nfapi_config.nmm_umts_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.bands[idx], out.nfapi_config.nmm_umts_frequency_bands.bands[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.tl.tag, out.nfapi_config.nmm_lte_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.bands[idx], out.nfapi_config.nmm_lte_frequency_bands.bands[idx]); + } + + ASSERT_TLV(in.nfapi_config.nmm_uplink_rssi_supported, out.nfapi_config.nmm_uplink_rssi_supported); +} +void nfapi_test_config_request() +{ + #define SET_TLV(_TLV, _TAG, _VALUE) { _TLV.tl.tag = _TAG; _TLV.value = _VALUE; num_tlv++; } + #define ASSERT_TLV(IN_TLV, OUT_TLV) { CU_ASSERT_EQUAL(IN_TLV.tl.tag, OUT_TLV.tl.tag); CU_ASSERT_EQUAL(IN_TLV.value, OUT_TLV.value);} + + nfapi_config_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_config_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CONFIG_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + + uint16_t idx = 0; + uint16_t num_tlv = 0; // Bit of a hack, it is incremented in the SET_UINT16_TLV macro + + SET_TLV(in.subframe_config.duplex_mode, NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, 1); + SET_TLV(in.subframe_config.pcfich_power_offset, NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, 1000); + SET_TLV(in.subframe_config.pb, NFAPI_SUBFRAME_CONFIG_PB_TAG, 1); + SET_TLV(in.subframe_config.dl_cyclic_prefix_type, NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, 0); + SET_TLV(in.subframe_config.ul_cyclic_prefix_type, NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, 0); + + SET_TLV(in.rf_config.dl_channel_bandwidth, NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, 50); + SET_TLV(in.rf_config.ul_channel_bandwidth, NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, 50); + SET_TLV(in.rf_config.reference_signal_power, NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, 120); + SET_TLV(in.rf_config.tx_antenna_ports, NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, 2); + SET_TLV(in.rf_config.rx_antenna_ports, NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, 2); + + SET_TLV(in.phich_config.phich_resource, NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, 3); + SET_TLV(in.phich_config.phich_duration, NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, 0); + SET_TLV(in.phich_config.phich_power_offset, NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, 500); + + SET_TLV(in.sch_config.primary_synchronization_signal_epre_eprers, NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, 1000); + SET_TLV(in.sch_config.secondary_synchronization_signal_epre_eprers, NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, 2000); + SET_TLV(in.sch_config.physical_cell_id, NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, 12344); + + + SET_TLV(in.prach_config.configuration_index, NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, 63); + SET_TLV(in.prach_config.root_sequence_index, NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, 800); + SET_TLV(in.prach_config.zero_correlation_zone_configuration, NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, 14); + SET_TLV(in.prach_config.high_speed_flag, NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, 0); + SET_TLV(in.prach_config.frequency_offset, NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, 23); + + SET_TLV(in.pusch_config.hopping_mode, NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, 0); + SET_TLV(in.pusch_config.hopping_offset, NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, 55); + SET_TLV(in.pusch_config.number_of_subbands, NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, 1); + + SET_TLV(in.pucch_config.delta_pucch_shift, NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, 2); + SET_TLV(in.pucch_config.n_cqi_rb, NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, 88); + SET_TLV(in.pucch_config.n_an_cs, NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, 3); + SET_TLV(in.pucch_config.n1_pucch_an, NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, 2015); + + SET_TLV(in.srs_config.bandwidth_configuration, NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, 3); + SET_TLV(in.srs_config.max_up_pts, NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, 0); + SET_TLV(in.srs_config.srs_subframe_configuration, NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, 11); + SET_TLV(in.srs_config.srs_acknack_srs_simultaneous_transmission, NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, 1); + + SET_TLV(in.uplink_reference_signal_config.uplink_rs_hopping, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, 2); + SET_TLV(in.uplink_reference_signal_config.group_assignment, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, 22); + SET_TLV(in.uplink_reference_signal_config.cyclic_shift_1_for_drms, NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, 2); + + + // laa config + SET_TLV(in.laa_config.ed_threshold_lbt_pdsch, NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, 45); + SET_TLV(in.laa_config.ed_threshold_lbt_drs, NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, 69); + SET_TLV(in.laa_config.pd_threshold, NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, 65535); + SET_TLV(in.laa_config.multi_carrier_type, NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, 3); + SET_TLV(in.laa_config.multi_carrier_tx, NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, 1); + SET_TLV(in.laa_config.multi_carrier_freeze, NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, 0); + SET_TLV(in.laa_config.tx_antenna_ports_drs, NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, 4); + SET_TLV(in.laa_config.tx_power_drs, NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, 10000); + // + // emtc config + SET_TLV(in.emtc_config.pbch_repetitions_enable_r13, NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, 1); + SET_TLV(in.emtc_config.prach_catm_root_sequence_index, NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, 837); + SET_TLV(in.emtc_config.prach_catm_zero_correlation_zone_configuration, NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, 15); + SET_TLV(in.emtc_config.prach_catm_high_speed_flag, NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, 15); + SET_TLV(in.emtc_config.prach_ce_level_0_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_0_configuration_index, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, 60); + SET_TLV(in.emtc_config.prach_ce_level_0_frequency_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, 90); + SET_TLV(in.emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, 128); + SET_TLV(in.emtc_config.prach_ce_level_0_starting_subframe_periodicity, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, 256); + SET_TLV(in.emtc_config.prach_ce_level_0_hopping_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_0_hopping_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, 0); + SET_TLV(in.emtc_config.prach_ce_level_1_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_1_configuration_index, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, 45); + SET_TLV(in.emtc_config.prach_ce_level_1_frequency_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, 88); + SET_TLV(in.emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, 64); + SET_TLV(in.emtc_config.prach_ce_level_1_starting_subframe_periodicity, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, 0xFFFF); + SET_TLV(in.emtc_config.prach_ce_level_1_hopping_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_1_hopping_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, 22); + SET_TLV(in.emtc_config.prach_ce_level_2_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_2_configuration_index, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, 63); + SET_TLV(in.emtc_config.prach_ce_level_2_frequency_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, 22); + SET_TLV(in.emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, 8); + SET_TLV(in.emtc_config.prach_ce_level_2_starting_subframe_periodicity, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, 64) + SET_TLV(in.emtc_config.prach_ce_level_2_hopping_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, 1); + SET_TLV(in.emtc_config.prach_ce_level_2_hopping_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, 45); + SET_TLV(in.emtc_config.prach_ce_level_3_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, 0); + SET_TLV(in.emtc_config.prach_ce_level_3_configuration_index, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, 45); + SET_TLV(in.emtc_config.prach_ce_level_3_frequency_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, 22); + SET_TLV(in.emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, 4); + SET_TLV(in.emtc_config.prach_ce_level_3_starting_subframe_periodicity, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, 4); + SET_TLV(in.emtc_config.prach_ce_level_3_hopping_enable, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, 0); + SET_TLV(in.emtc_config.prach_ce_level_3_hopping_offset, NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, 0); + SET_TLV(in.emtc_config.pucch_interval_ulhoppingconfigcommonmodea, NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, 8); + SET_TLV(in.emtc_config.pucch_interval_ulhoppingconfigcommonmodeb, NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, 8); + + + SET_TLV(in.tdd_frame_structure_config.subframe_assignment, NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, 5); + SET_TLV(in.tdd_frame_structure_config.special_subframe_patterns, NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, 3); + + SET_TLV(in.l23_config.data_report_mode, NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, 1); + SET_TLV(in.l23_config.sfnsf, NFAPI_L23_CONFIG_SFNSF_TAG, 12354); + + in.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + num_tlv++; + + in.nfapi_config.p7_vnf_address_ipv6.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG; + num_tlv++; + + SET_TLV(in.nfapi_config.p7_vnf_port, NFAPI_NFAPI_P7_VNF_PORT_TAG, 1111); + + in.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + num_tlv++; + + in.nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG; + for(idx = 0; idx < NFAPI_IPV6_ADDRESS_LENGTH; ++idx) + { + in.nfapi_config.p7_pnf_address_ipv6.address[idx] = idx; + } + num_tlv++; + + SET_TLV(in.nfapi_config.p7_pnf_port, NFAPI_NFAPI_P7_PNF_PORT_TAG, 9999); + SET_TLV(in.nfapi_config.dl_ue_per_sf, NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, 4); + SET_TLV(in.nfapi_config.ul_ue_per_sf, NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, 4); + + in.nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + in.nfapi_config.rf_bands.number_rf_bands = 2; + in.nfapi_config.rf_bands.rf_band[0] = 783; + num_tlv++; + + SET_TLV(in.nfapi_config.timing_window, NFAPI_NFAPI_TIMING_WINDOW_TAG, 29); + SET_TLV(in.nfapi_config.timing_info_mode, NFAPI_NFAPI_TIMING_INFO_MODE_TAG, 2); + SET_TLV(in.nfapi_config.timing_info_period, NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, 23); + SET_TLV(in.nfapi_config.max_transmit_power, NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, 123); + SET_TLV(in.nfapi_config.earfcn, NFAPI_NFAPI_EARFCN_TAG, 1800); + + in.nfapi_config.nmm_gsm_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands = 2; + num_tlv++; + + in.nfapi_config.nmm_umts_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands = 3; + num_tlv++; + + in.nfapi_config.nmm_lte_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG; + in.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands = 1; + num_tlv++; + + SET_TLV(in.nfapi_config.nmm_uplink_rssi_supported, NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, 1); + + + in.num_tlv = num_tlv; + + in.vendor_extension = 0; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.num_tlv, out.num_tlv); + + ASSERT_TLV(in.subframe_config.duplex_mode, out.subframe_config.duplex_mode); + ASSERT_TLV(in.subframe_config.pcfich_power_offset, out.subframe_config.pcfich_power_offset); + ASSERT_TLV(in.subframe_config.pb, out.subframe_config.pb); + ASSERT_TLV(in.subframe_config.dl_cyclic_prefix_type, out.subframe_config.dl_cyclic_prefix_type); + ASSERT_TLV(in.subframe_config.ul_cyclic_prefix_type, out.subframe_config.ul_cyclic_prefix_type); + + ASSERT_TLV(in.rf_config.dl_channel_bandwidth, out.rf_config.dl_channel_bandwidth); + ASSERT_TLV(in.rf_config.ul_channel_bandwidth, out.rf_config.ul_channel_bandwidth); + ASSERT_TLV(in.rf_config.reference_signal_power, out.rf_config.reference_signal_power); + ASSERT_TLV(in.rf_config.tx_antenna_ports, out.rf_config.tx_antenna_ports); + ASSERT_TLV(in.rf_config.rx_antenna_ports, out.rf_config.rx_antenna_ports); + + ASSERT_TLV(in.phich_config.phich_resource, out.phich_config.phich_resource); + ASSERT_TLV(in.phich_config.phich_duration, out.phich_config.phich_duration); + ASSERT_TLV(in.phich_config.phich_power_offset, out.phich_config.phich_power_offset); + + ASSERT_TLV(in.sch_config.primary_synchronization_signal_epre_eprers, out.sch_config.primary_synchronization_signal_epre_eprers); + ASSERT_TLV(in.sch_config.secondary_synchronization_signal_epre_eprers, out.sch_config.secondary_synchronization_signal_epre_eprers); + ASSERT_TLV(in.sch_config.physical_cell_id, out.sch_config.physical_cell_id); + + + ASSERT_TLV(in.prach_config.configuration_index, out.prach_config.configuration_index); + ASSERT_TLV(in.prach_config.root_sequence_index, out.prach_config.root_sequence_index); + ASSERT_TLV(in.prach_config.zero_correlation_zone_configuration, out.prach_config.zero_correlation_zone_configuration); + ASSERT_TLV(in.prach_config.high_speed_flag, out.prach_config.high_speed_flag); + ASSERT_TLV(in.prach_config.frequency_offset, out.prach_config.frequency_offset); + + ASSERT_TLV(in.pusch_config.hopping_mode, in.pusch_config.hopping_mode); + ASSERT_TLV(in.pusch_config.hopping_offset, in.pusch_config.hopping_offset); + ASSERT_TLV(in.pusch_config.number_of_subbands, in.pusch_config.number_of_subbands); + + ASSERT_TLV(in.pucch_config.delta_pucch_shift, out.pucch_config.delta_pucch_shift); + ASSERT_TLV(in.pucch_config.n_cqi_rb, out.pucch_config.n_cqi_rb); + ASSERT_TLV(in.pucch_config.n_an_cs, out.pucch_config.n_an_cs); + ASSERT_TLV(in.pucch_config.n1_pucch_an, out.pucch_config.n1_pucch_an); + + ASSERT_TLV(in.srs_config.bandwidth_configuration, out.srs_config.bandwidth_configuration); + ASSERT_TLV(in.srs_config.max_up_pts, out.srs_config.max_up_pts); + ASSERT_TLV(in.srs_config.srs_subframe_configuration, out.srs_config.srs_subframe_configuration); + ASSERT_TLV(in.srs_config.srs_acknack_srs_simultaneous_transmission, out.srs_config.srs_acknack_srs_simultaneous_transmission); + + ASSERT_TLV(in.uplink_reference_signal_config.uplink_rs_hopping, out.uplink_reference_signal_config.uplink_rs_hopping); + ASSERT_TLV(in.uplink_reference_signal_config.group_assignment, out.uplink_reference_signal_config.group_assignment); + ASSERT_TLV(in.uplink_reference_signal_config.cyclic_shift_1_for_drms, out.uplink_reference_signal_config.cyclic_shift_1_for_drms); + + ASSERT_TLV(in.tdd_frame_structure_config.subframe_assignment, out.tdd_frame_structure_config.subframe_assignment); + ASSERT_TLV(in.tdd_frame_structure_config.special_subframe_patterns, out.tdd_frame_structure_config.special_subframe_patterns); + + // laa config + ASSERT_TLV(in.laa_config.ed_threshold_lbt_pdsch, out.laa_config.ed_threshold_lbt_pdsch); + ASSERT_TLV(in.laa_config.ed_threshold_lbt_drs, out.laa_config.ed_threshold_lbt_drs); + ASSERT_TLV(in.laa_config.pd_threshold, out.laa_config.pd_threshold); + ASSERT_TLV(in.laa_config.multi_carrier_type, out.laa_config.multi_carrier_type); + ASSERT_TLV(in.laa_config.multi_carrier_tx, out.laa_config.multi_carrier_tx); + ASSERT_TLV(in.laa_config.multi_carrier_freeze, out.laa_config.multi_carrier_freeze); + ASSERT_TLV(in.laa_config.tx_antenna_ports_drs, out.laa_config.tx_antenna_ports_drs); + ASSERT_TLV(in.laa_config.tx_power_drs, out.laa_config.tx_power_drs); + // emtc config + ASSERT_TLV(in.emtc_config.pbch_repetitions_enable_r13, out.emtc_config.pbch_repetitions_enable_r13); + ASSERT_TLV(in.emtc_config.prach_catm_root_sequence_index, out.emtc_config.prach_catm_root_sequence_index); + ASSERT_TLV(in.emtc_config.prach_catm_zero_correlation_zone_configuration, out.emtc_config.prach_catm_zero_correlation_zone_configuration); + ASSERT_TLV(in.emtc_config.prach_catm_high_speed_flag, out.emtc_config.prach_catm_high_speed_flag); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_enable, out.emtc_config.prach_ce_level_0_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_configuration_index, out.emtc_config.prach_ce_level_0_configuration_index); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_frequency_offset, out.emtc_config.prach_ce_level_0_frequency_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt, out.emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_starting_subframe_periodicity, out.emtc_config.prach_ce_level_0_starting_subframe_periodicity); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_hopping_enable, out.emtc_config.prach_ce_level_0_hopping_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_0_hopping_offset, out.emtc_config.prach_ce_level_0_hopping_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_enable, out.emtc_config.prach_ce_level_1_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_configuration_index, out.emtc_config.prach_ce_level_1_configuration_index); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_frequency_offset, out.emtc_config.prach_ce_level_1_frequency_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt, out.emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_starting_subframe_periodicity, out.emtc_config.prach_ce_level_1_starting_subframe_periodicity); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_hopping_enable, out.emtc_config.prach_ce_level_1_hopping_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_1_hopping_offset, out.emtc_config.prach_ce_level_1_hopping_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_enable, out.emtc_config.prach_ce_level_2_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_configuration_index, out.emtc_config.prach_ce_level_2_configuration_index); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_frequency_offset, out.emtc_config.prach_ce_level_2_frequency_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt, out.emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_starting_subframe_periodicity, out.emtc_config.prach_ce_level_2_starting_subframe_periodicity); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_hopping_enable, out.emtc_config.prach_ce_level_2_hopping_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_2_hopping_offset, out.emtc_config.prach_ce_level_2_hopping_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_enable, out.emtc_config.prach_ce_level_3_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_configuration_index, out.emtc_config.prach_ce_level_3_configuration_index); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_frequency_offset, out.emtc_config.prach_ce_level_3_frequency_offset); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt, out.emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_starting_subframe_periodicity, out.emtc_config.prach_ce_level_3_starting_subframe_periodicity); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_hopping_enable, out.emtc_config.prach_ce_level_3_hopping_enable); + ASSERT_TLV(in.emtc_config.prach_ce_level_3_hopping_offset, out.emtc_config.prach_ce_level_3_hopping_offset); + ASSERT_TLV(in.emtc_config.pucch_interval_ulhoppingconfigcommonmodea, out.emtc_config.pucch_interval_ulhoppingconfigcommonmodea); + ASSERT_TLV(in.emtc_config.pucch_interval_ulhoppingconfigcommonmodeb, out.emtc_config.pucch_interval_ulhoppingconfigcommonmodeb); + + ASSERT_TLV(in.l23_config.data_report_mode, out.l23_config.data_report_mode); + ASSERT_TLV(in.l23_config.sfnsf, out.l23_config.sfnsf); + + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv4.tl.tag, out.nfapi_config.p7_vnf_address_ipv4.tl.tag); + for(idx = 0; idx < NFAPI_IPV4_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv4.address[idx], out.nfapi_config.p7_vnf_address_ipv4.address[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv6.tl.tag, out.nfapi_config.p7_vnf_address_ipv6.tl.tag); + for(idx = 0; idx < NFAPI_IPV6_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_vnf_address_ipv6.address[idx], out.nfapi_config.p7_vnf_address_ipv6.address[idx]); + } + + ASSERT_TLV(in.nfapi_config.p7_vnf_port, out.nfapi_config.p7_vnf_port); + + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv4.tl.tag, out.nfapi_config.p7_pnf_address_ipv4.tl.tag); + for(idx = 0; idx < NFAPI_IPV4_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv4.address[idx], out.nfapi_config.p7_pnf_address_ipv4.address[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv6.tl.tag, out.nfapi_config.p7_pnf_address_ipv6.tl.tag); + for(idx = 0; idx < NFAPI_IPV6_ADDRESS_LENGTH; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.p7_pnf_address_ipv6.address[idx], out.nfapi_config.p7_pnf_address_ipv6.address[idx]); + } + + ASSERT_TLV(in.nfapi_config.p7_pnf_port, out.nfapi_config.p7_pnf_port); + ASSERT_TLV(in.nfapi_config.dl_ue_per_sf, out.nfapi_config.dl_ue_per_sf); + ASSERT_TLV(in.nfapi_config.ul_ue_per_sf, out.nfapi_config.ul_ue_per_sf); + + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.tl.tag, out.nfapi_config.rf_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.number_rf_bands, out.nfapi_config.rf_bands.number_rf_bands); + for(idx = 0; idx < out.nfapi_config.rf_bands.number_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.rf_bands.rf_band[idx], out.nfapi_config.rf_bands.rf_band[idx]); + } + + ASSERT_TLV(in.nfapi_config.timing_window, out.nfapi_config.timing_window); + ASSERT_TLV(in.nfapi_config.timing_info_mode, out.nfapi_config.timing_info_mode); + ASSERT_TLV(in.nfapi_config.timing_info_period, out.nfapi_config.timing_info_period); + ASSERT_TLV(in.nfapi_config.max_transmit_power, out.nfapi_config.max_transmit_power); + ASSERT_TLV(in.nfapi_config.earfcn, out.nfapi_config.earfcn); + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.tl.tag, out.nfapi_config.nmm_gsm_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_gsm_frequency_bands.bands[idx], out.nfapi_config.nmm_gsm_frequency_bands.bands[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.tl.tag, out.nfapi_config.nmm_umts_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_umts_frequency_bands.bands[idx], out.nfapi_config.nmm_umts_frequency_bands.bands[idx]); + } + + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.tl.tag, out.nfapi_config.nmm_lte_frequency_bands.tl.tag); + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands, out.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands); + for(idx = 0; idx < out.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands; ++idx) + { + CU_ASSERT_EQUAL(in.nfapi_config.nmm_lte_frequency_bands.bands[idx], out.nfapi_config.nmm_lte_frequency_bands.bands[idx]); + } + + ASSERT_TLV(in.nfapi_config.nmm_uplink_rssi_supported, out.nfapi_config.nmm_uplink_rssi_supported); +} +void nfapi_test_config_response() +{ + nfapi_config_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_config_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_CONFIG_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_start_request() +{ + nfapi_start_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_start_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_START_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); +} +void nfapi_test_start_response() +{ + nfapi_start_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_start_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_START_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_stop_request() +{ + nfapi_stop_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_stop_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_STOP_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + +} +void nfapi_test_stop_response() +{ + nfapi_stop_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_stop_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_STOP_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); +} +void nfapi_test_measurement_request() +{ +// #define SET_TLV(_TLV, _TAG, _VALUE) { _TLV.tl.tag = _TAG; _TLV.value = _VALUE; } +// #define ASSERT_TLV(IN_TLV, OUT_TLV) { CU_ASSERT_EQUAL(IN_TLV.tl.tag, OUT_TLV.tl.tag); CU_ASSERT_EQUAL(IN_TLV.value, OUT_TLV.value);} + uint16_t num_tlv = 0; + nfapi_measurement_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_measurement_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_MEASUREMENT_REQUEST; + in.header.message_length = 0; + in.header.spare = 0; + + SET_TLV(in.dl_rs_tx_power, NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG, 1); + SET_TLV(in.received_interference_power, NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG, 123); + SET_TLV(in.thermal_noise_power, NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG, 255); + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + + + ASSERT_TLV(in.dl_rs_tx_power, out.dl_rs_tx_power); + ASSERT_TLV(in.received_interference_power, out.received_interference_power); + ASSERT_TLV(in.thermal_noise_power, out.thermal_noise_power); +} +void nfapi_test_measurement_response() +{ + uint16_t num_tlv = 0; + nfapi_measurement_response_t in; + memset(&in, 0, sizeof(in)); + nfapi_measurement_response_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + in.header.message_length = 0; + in.header.spare = 0; + + in.error_code = NFAPI_MSG_OK; + + SET_TLV(in.dl_rs_tx_power_measurement, NFAPI_MEASUREMENT_RESPONSE_DL_RS_POWER_MEASUREMENT_TAG, -400); + + in.received_interference_power_measurement.tl.tag = NFAPI_MEASUREMENT_RESPONSE_RECEIVED_INTERFERENCE_POWER_MEASUREMENT_TAG; + in.received_interference_power_measurement.number_of_resource_blocks = 100; + in.received_interference_power_measurement.received_interference_power[0] = -8767; + + SET_TLV(in.thermal_noise_power_measurement, NFAPI_MEASUREMENT_RESPONSE_THERMAL_NOISE_MEASUREMENT_TAG, -8900); + + int packedMessageLength = nfapi_p5_message_pack(&in, sizeof(in), gTestNfapiMessageTx, MAX_PACKED_MESSAGE_SIZE, 0); + + nfapi_p5_message_unpack(gTestNfapiMessageTx, packedMessageLength, &out, sizeof(out), 0); + + CU_ASSERT_EQUAL(in.header.message_id, out.header.message_id); + CU_ASSERT_EQUAL(in.error_code, out.error_code); + + ASSERT_TLV(in.dl_rs_tx_power_measurement, out.dl_rs_tx_power_measurement); + CU_ASSERT_EQUAL(in.received_interference_power_measurement.tl.tag, out.received_interference_power_measurement.tl.tag); + CU_ASSERT_EQUAL(in.received_interference_power_measurement.number_of_resource_blocks, out.received_interference_power_measurement.number_of_resource_blocks); + // check array + ASSERT_TLV(in.thermal_noise_power_measurement, out.thermal_noise_power_measurement); +} + +void nfapi_test_dl_config_request() +{ + + + uint16_t idx = 0; + nfapi_dl_config_request_t in; + memset(&in, 0, sizeof(in)); + nfapi_dl_config_request_t out; + + in.header.phy_id = NFAPI_PHY_ID_NA; + in.header.message_id = NFAPI_DL_CONFIG_REQUEST; + in.header.message_length = 0; + in.header.m_segment_sequence = 0xDDDD; + in.header.checksum = 0xEEEEEEEE; + + in.sfn_sf = 0x3FFF; + + in.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + in.dl_config_request_body.number_pdcch_ofdm_symbols = 4; + in.dl_config_request_body.number_dci = 255; + in.dl_config_request_body.number_pdu = 0; + in.dl_config_request_body.number_pdsch_rnti = 0; + in.dl_config_request_body.transmission_power_pcfich = 10000; + + in.dl_config_request_body.dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)(malloc(sizeof(nfapi_dl_config_request_pdu_t) * 12)); + + in.dl_config_request_body.dl_config_pdu_list[0].pdu_type = 0; + in.dl_config_request_body.dl_config_pdu_list[0].pdu_size = 123; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG; + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel12.primary_cell_type = rand8(0, 2); + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_flag = rand8(0, 1); + in.dl_config_request_body.dl_config_pdu_list[0].dci_dl_pdu.dci_dl_pdu_rel12.number_ul_dl_configurations = rand8(0, 5); + for(idx = 0; idx pSuite; + int count = 0; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + count++; + t = t->pNext; + } + s = s->pNext; + } + + printf("%d..%d\n", 1, count); + + + + s = CU_get_registry()->pSuite; + count = 1; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + int pass = 1; + CU_FailureRecord* failures = CU_get_failure_list(); + while(failures) + { + if(strcmp(failures->pSuite->pName, s->pName) == 0 && + strcmp(failures->pTest->pName, t->pName) == 0) + { + pass = 0; + failures = 0; + } + else + { + failures = failures->pNext; + } + } + + if(pass) + printf("ok %d - %s:%s\n", count, s->pName, t->pName); + else + printf("not ok %d - %s:%s\n", count, s->pName, t->pName); + + count++; + t = t->pNext; + } + s = s->pNext; + } + + /* + s = CU_get_registry()->pSuite; + while(s) + { + printf("Suite %s\n", s->pName); + CU_pTest t = s->pTest; + while(t) + { + printf(" Test %s\n", t->pName); + i//CU_ErrorCode e = CU_basic_run_test(s, t); + + t = t->pNext; + } + s = s->pNext; + } + */ + + + + //printf("CU_basic_run_tests completed \n"); + //CU_basic_show_failures(CU_get_failure_list()); + //printf("CU_basic_show_failures completed\n\n"); + /* + // Run all tests using the automated interface + CU_automated_run_tests(); + CU_list_tests_to_file(); + + // Run all tests using the console interface + CU_console_run_tests(); + */ + /* Clean up registry and return */ + + + CU_cleanup_registry(); + return CU_get_error(); + +} diff --git a/nfapi/open-nFAPI/pnf/Makefile.am b/nfapi/open-nFAPI/pnf/Makefile.am new file mode 100644 index 0000000000..663d96b6dd --- /dev/null +++ b/nfapi/open-nFAPI/pnf/Makefile.am @@ -0,0 +1,32 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AUTOMAKE_OPTIONS=subdir-objects + +AM_CPPFLAGS = -I$(top_srcdir)/pnf/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -g -Wall -Werror + + +noinst_LIBRARIES = libnfapi_pnf.a + +libnfapi_pnf_a_SOURCES = src/pnf.c\ + src/pnf_interface.c\ + src/pnf_p7.c\ + src/pnf_p7_interface.c + +LDADD = -lsctp + + + diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h new file mode 100644 index 0000000000..ab38c66e09 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/inc/pnf.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _PNF_H_ +#define _PNF_H_ + +#include "nfapi_pnf_interface.h" + +#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192 + +typedef struct { + + nfapi_pnf_config_t _public; + + int p5_sock; + uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + + uint8_t sctp; + + uint8_t terminate; + +} pnf_t; + + +int pnf_connect(pnf_t *pnf); +int pnf_message_pump(pnf_t *pnf); + +int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); +int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); +int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id); + +nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id); + +#endif // _PNF_H_ + diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h new file mode 100644 index 0000000000..3f08d85e6b --- /dev/null +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -0,0 +1,126 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + + +#ifndef _PNF_P7_H_ +#define _PNF_P7_H_ + +#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20) +#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF) +#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF)) + +#include "nfapi_pnf_interface.h" + +#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192 + +typedef struct { + uint16_t dl_conf_ontime; + uint16_t dl_conf_late; + uint16_t ul_conf_ontime; + uint16_t ul_conf_late; + uint16_t hi_dci0_ontime; + uint16_t hi_dci0_late; + uint16_t tx_ontime; + uint16_t tx_late; +} pnf_p7_stats_t; + +typedef struct { + uint8_t* buffer; + uint16_t length; +} pnf_p7_rx_message_segment_t; + +typedef struct pnf_p7_rx_message pnf_p7_rx_message_t; + +typedef struct pnf_p7_rx_message { + uint8_t sequence_number; + uint8_t num_segments_received; + uint8_t num_segments_expected; + + // the spec allows of upto 128 segments, this does seem excessive + pnf_p7_rx_message_segment_t segments[128]; + + uint32_t rx_hr_time; + + pnf_p7_rx_message_t* next; +} pnf_p7_rx_message_t; + +typedef struct { + + pnf_p7_rx_message_t* msg_queue; + +} pnf_p7_rx_reassembly_queue_t; + + +typedef struct { + + nfapi_pnf_p7_config_t _public; + + //private data + int p7_sock; + + uint8_t terminate; + + uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + uint8_t* rx_message_buffer; + uint16_t rx_message_buffer_size; + + pthread_mutex_t mutex; // should we allow the client to specifiy + pthread_mutex_t pack_mutex; // should we allow the client to specifiy + + nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/]; + + uint32_t sequence_number; + uint16_t max_num_segments; + + pnf_p7_rx_reassembly_queue_t reassembly_queue; + + uint8_t* reassemby_buffer; + uint32_t reassemby_buffer_size; + + uint16_t sfn_sf; + uint32_t sf_start_time_hr; + int32_t sfn_sf_shift; + + uint8_t timing_info_period_counter; + uint8_t timing_info_aperiodic_send; // 0:false 1:true + + uint32_t timing_info_ms_counter; // number of ms since last timing info + + uint32_t dl_config_jitter; + uint32_t ul_config_jitter; + uint32_t hi_dci0_jitter; + uint32_t tx_jitter; + + uint32_t tick; + pnf_p7_stats_t stats; + +} pnf_p7_t; + +int pnf_p7_message_pump(pnf_p7_t* pnf_p7); + +int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len); +int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len); + + +int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf); + +pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len); +void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg); +void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta); + +#endif /* _PNF_P7_H_ */ + diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h new file mode 100644 index 0000000000..b25caf2876 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -0,0 +1,803 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _NFAPI_PNF_INTERFACE_H_ +#define _NFAPI_PNF_INTERFACE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "nfapi_interface.h" +#include "debug.h" + +#include + +/*! This enum is used to describe the states of the pnf + */ +typedef enum +{ + NFAPI_PNF_IDLE = 0, + NFAPI_PNF_CONFIGURED, + NFAPI_PNF_RUNNING +} nfapi_pnf_state_e; + +/*! This enum is used to describe the states of a phy instance of a pnf + */ +typedef enum +{ + NFAPI_PNF_PHY_IDLE = 0, + NFAPI_PNF_PHY_CONFIGURED = 1, + NFAPI_PNF_PHY_RUNNING = 2 +} nfapi_pnf_phy_state_e; + +typedef struct nfapi_pnf_phy_config nfapi_pnf_phy_config_t; + +/*! Configuration information for a pnf phy instance + */ +typedef struct nfapi_pnf_phy_config +{ + /*! The PHY id*/ + uint16_t phy_id; + + /*! The state of the PNF PHY instance*/ + nfapi_pnf_phy_state_e state; + + /*! Optional user defined data that will be passed back in the callbacks*/ + void* user_data; + + /*! Pointer for use in a linked list */ + struct nfapi_pnf_phy_config* next; +} nfapi_pnf_phy_config_t; + +typedef struct nfapi_pnf_config nfapi_pnf_config_t; + +/*! Configuration information for the pnf created by calling nfapi_pnf_create + */ +typedef struct nfapi_pnf_config +{ + /*! A user define callback to override the default memory allocation + * \param size The size of the data buffer to allocate + * \return A pointer to a data buffer + */ + void* (*malloc)(size_t size); + + /*! A user define callback to override the default memory deallocation + * \param ptr Pointer to a data buffer to be deallocated + */ + void (*free)(void* ptr); + + /*! A user define callback to handle trace from the pnf + * \param level The trace level + * \param message The trace string + * + * This is a vardic function. + */ + void (*trace)(nfapi_trace_level_t level, const char* message, ...); + + /*! The ip address of the VNF + * + */ + char* vnf_ip_addr; + + /*! The ip port of the VNF + */ + int vnf_p5_port; + + /*! The state of the PNF */ + nfapi_pnf_state_e state; + + /*! List of PHY instances configured for this PNF */ + nfapi_pnf_phy_config_t* phys; + + /*! Configuation option of the p4 p5 encode decode functions */ + nfapi_p4_p5_codec_config_t codec_config; + + /*! Optional user defined data that will be passed back in the callbacks*/ + void* user_data; + + + /*! A callback for the PNF_PARAM.request + * \param config A pointer to the pnf configuration + * \param req A data structure for the decoded PNF_PARAM.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the PNF_PARAM.response after receiving the + * PNF_PARAM.request. This can be done in the call back. + */ + int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req); + + /*! A callback for the PNF_CONFIG.request + * \param config A pointer to the pnf configuration + * \param req A data structure for the decoded PNF_CONFIG.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the PNF_CONFIG.response after receiving the + * PNF_CONFIG.request. This can be done in the call back. + */ + int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req); + + /*! A callback for the PNF_START.request + * \param config A pointer to the pnf configuration + * \param req A data structure for the decoded PNF_CONFIG.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the PNF_START.response after receiving the + * PNF_START.request. This can be done in the call back. + */ + int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req); + + /*! A callback for the PNF_STOP.request + * \param config A pointer to the pnf configuration + * \param req A data structure for the decoded PNF_STOP.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the PNF_STOP.response after receiving the + * PNF_STOP.request. This can be done in the call back. + */ + int (*pnf_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req); + + /*! A callback for the PARAM.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded PARAM.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the PARAM.response after receiving the + * PARAM.request. This can be done in the call back. + */ + int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req); + + /*! A callback for the CONFIG.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded CONFIG.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the CONFIG.response after receiving the + * CONFIG.request. This can be done in the call back. + */ + int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req); + + /*! A callback for the START.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded START.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the START.response after the client has received the + * first subframe indication from FAPI. + */ + int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req); + + /*! A callback for the STOP.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded STOP.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the STOP.response after receiving the + * STOP.request. This can be done in the call back. + */ + int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req); + + /*! A callback for the MEASUREMENT.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded MEASUREMENT.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the MEASUREMENT.response after receiving the + * MEASUREMENT.request. This can be done in the call back. + */ + int (*measurement_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req); + + /*! A callback for the RSSI.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded RSSI.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the RSSI.response after receiving the + * RSSI.request. This can be done in the call back. + */ + int (*rssi_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req); + + /*! A callback for the CELL_SEARCH.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded CELL_SEARCH.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the CELL_SEARCH.response after receiving the + * CELL_SEARCH.request. This can be done in the call back. + */ + int (*cell_search_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req); + + /*! A callback for the BROADCAST_DETECT.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded BROADCAST_DETECT.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the BROADCAST_DETECT.response after receiving the + * BROADCAST_DETECT.request. This can be done in the call back. + */ + int (*broadcast_detect_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req); + + /*! A callback for the SYSTEM_INFORMATION_SCHEDULE.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded SYSTEM_INFORMATION_SCHEDULE.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the SYSTEM_INFORMATION_SCHEDULE.response after receiving the + * SYSTEM_INFORMATION_SCHEDULE.request. This can be done in the call back. + */ + int (*system_information_schedule_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req); + + /*! A callback for the SYSTEM_INFORMATION.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded SYSTEM_INFORMATION.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the SYSTEM_INFORMATION.response after receiving the + * SYSTEM_INFORMATION.request. This can be done in the call back. + */ + int (*system_information_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req); + + /*! A callback for the NMM_STOP.request + * \param config A pointer to the pnf configuration + * \param phy A pointer to the pnf phy configuration + * \param req A data structure for the decoded NMM_STOP.request. This will have + * been allocated on the stack + * \return not currently used + * + * The client is expected to send the NMM_STOP.response after receiving the + * NMM_STOP.request. This can be done in the call back. + */ + int (*nmm_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req); + + /*! A callback for any vendor extension messages recevied + * \param config A pointer to the pnf configuration + * \param msg A pointer to the decode P4/P5 message + * \return not current used + */ + int (*vendor_ext)(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg); + + /*! A callback to allocate vendor extension message + * \param message_id The message id from the decode P4/P5 message header + * \param msg_size A pointer a the size of the allocated message structure. The callee should set this + * \return A pointer to a allocated P4/P5 message structure + */ + nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size); + + /*! A callback to deallocate vendor extension message + * \param header A pointer to an P4/P5 message structure + */ + void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header); + + + +} nfapi_pnf_config_t; + +/*! Create a pnf configuration + * \return A pointer to a pnf configuration struture + * + * This function will create and initialize a pnf instance. It is expected that + * the client will set the callback and parameters need before calling nfapi_pnf_start + * + * 0 will be returned if it fails. + * + * \code + * nfapi_pnf_config_t* config = nfapi_pnf_config_create(void); + * \endcode + */ +nfapi_pnf_config_t* nfapi_pnf_config_create(void); + +/*! Delete a pnf configuration + * \param config A pointer to a pnf configuraiton + * \return 0 is success, -1 for failure + */ +int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config); + +/*! Start the PNF library. + * \param config A pointer to the pnf configuration + * \return 0 is success, -1 for failure + * + * This function will not return until nfapi_pnf_stop is called + * + * \code + * // Create the pnf config + * nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + * + * // Assumed that the vnf_address and vnf_port are provided over the P9 interface + * config->vnf_ip_addr = vnf_address; + * config->vnf_p5_port = vnf_port; + * + * // Set the required callbacks + * config->pnf_param_req = &pnf_param_request; + * ... + * + * // Call start for the PNF to initiate a connection to the VNF + * nfai_pnf_start(config); + * + * \endcode + */ +int nfapi_pnf_start(nfapi_pnf_config_t* config); + +/*! Stop the PNF library. + * \param config A pointer to the pnf configuration + * \return 0 is success, -1 for failure + * + * This function will cause the nfapi_pnf_start function to return + */ +int nfapi_pnf_stop(nfapi_pnf_config_t* config); + +/*! Send the PNF_PARAM.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp); + +/*! Send the PNF_CONFIG.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp); + +/*! Send the PNF_START.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp); + +/*! Send the PNF_STOP.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp); + +/*! Send the PARAM.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp); + +/*! Send the CONFIG.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp); + +/*! Send the START.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp); + +/*! Send the STOP.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp); + +/*! Send the MEASUREMENT.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp); + +/*! Send the RSSI.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp); + +/*! Send the RSSI.indication + * \param config A pointer to a pnf configuraiton + * \param ind A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind); + +/*! Send the CELL_SEARCH.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp); + +/*! Send the CELL_SEARCH.indication + * \param config A pointer to a pnf configuraiton + * \param ind A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind); + +/*! Send the BROADCAST_DETECT.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp); + +/*! Send the BROADCAST_DETECT.indication + * \param config A pointer to a pnf configuraiton + * \param ind A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind); + +/*! Send the SYSTEM_INFORMATION_SCHEDULE.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp); + +/*! Send the SYSTEM_INFORMATION_SCHEDULE.indication + * \param config A pointer to a pnf configuraiton + * \param ind A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind); + +/*! Send the SYSTEM_INFORMATION.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp); + +/*! Send the SYSTEM_INFORMATION.indication + * \param config A pointer to a pnf configuraiton + * \param ind A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind); + +/*! Send the NMM_STOP.response + * \param config A pointer to a pnf configuraiton + * \param resp A pointer to the message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp); + +/*! Send a vendor extension message + * \param config A pointer to a pnf configuraiton + * \param msg A pointer to the vendor extention message structure + * \param msg_len The size of the vendor extention message structure + * \return 0 for success, -1 for failure + * + */ +int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); + +//-------------------------- + +/*! A subframe buffer structure which can be used by the client to + * to configure the dummy information + */ +typedef struct +{ + uint16_t sfn_sf; + + nfapi_dl_config_request_t* dl_config_req; + nfapi_ul_config_request_t* ul_config_req; + nfapi_hi_dci0_request_t* hi_dci0_req; + nfapi_tx_request_t* tx_req; + nfapi_lbt_dl_config_request_t* lbt_dl_config_req; + +} nfapi_pnf_p7_subframe_buffer_t; + +typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t; + +/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function + */ +typedef struct nfapi_pnf_p7_config +{ + /*! A user define callback to override the default memory allocation + * \param size The size of the buffer to allocate + * \return An allocated buffer. 0 in the case of failure + * + * If not set malloc will be used + */ + void* (*malloc)(size_t size); + + /*! A user define callback to override the default memory deallocation + * \param ptr Pointer to a buffer to dellocate + * + * If not set free will be used + */ + void (*free)(void* ptr); + + /*! A user define callback to handle trace from the pnf + * \param level The trace level + * \param message The message string + */ + void (*trace)(nfapi_trace_level_t level, const char* message, ...); + + /*! The PHY id*/ + uint16_t phy_id; + + // remote + /*! The VNF P7 UDP port */ + int remote_p7_port; + /*! The VNF P7 UDP address */ + char* remote_p7_addr; + + // local + /*! The PNF P7 UDP port */ + int local_p7_port; + /*! The PNF P7 UDP address */ + char* local_p7_addr; + + /*! Flag to indicate of the pnf should use the P7 checksum */ + uint8_t checksum_enabled; + + /*! The maxium size of a P7 segement. If a message is large that this it + * will be segemented */ + uint16_t segment_size; + + /*! The dummy subframe buffer structure that should be used in case there + * are no 'valid' subframe messages */ + nfapi_pnf_p7_subframe_buffer_t dummy_subframe; + + /*! Configuration options for the p7 pack unpack functions*/ + nfapi_p7_codec_config_t codec_config; + + /*! Optional userdata that will be passed back in the callbacks*/ + void* user_data; + + // tdb : if these should be public + uint16_t subframe_buffer_size; + uint8_t timing_info_mode_periodic; // 0:false 1:true + uint8_t timing_info_mode_aperiodic; // 0:false 1:true + uint8_t timing_info_period; // 1..225 in subframes + + /*! A callback for the DL_CONFIG.request + * \param config A poiner to the 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); + + /*! 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); + + /*! 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); + + /*! A callback for the TX_REQ.request + * \param config A poiner to the PNF P7 config + * \param req A pointer to the tx request message structure + * \return not currently used + * + * The TX request contains pointers to the downlink PDUs to be sent. In the case that the FAPI interface + * will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0 + * and then use the p7 codec config free function to release the pdu's when appropriate. + */ + int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req); + + /*! A callback for the LBT_DL_CONFIG.request + * \param config A poiner to the PNF P7 config + * \param req A pointer to the lbt dl request message structure + * \return not currently used + */ + int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req); + + /*! A callback for vendor extension messages + * \param config A poiner to the PNF P7 config + * \param msg A pointer to a decode vendor extention message + * \return not currently used + */ + int (*vendor_ext)(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg); + + /*! A callback to allocate vendor extension message + * \param message_id The vendor extention message id from the decode message header + * \param msg_size A pointer to size of the allocate vendor extention message. Set by the callee + * \return A pointer to an allocated vendor extention message structure. 0 if failed + * + * + */ + nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size); + + /*! A callback to deallocate vendor extension message + * \param header A pointer to a p7 vendor extention message + */ + void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header); + + + +} nfapi_pnf_p7_config_t; + +/*! Create and initialise a nfapi_pnf_p7_config structure + * \return A pointer to a PNF P7 config structure + */ +nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(void); + +/*! Delete an nfapi_pnf_p7_config structure + * \param config + */ +int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config); + + +/*! Start the PNF P7 library. + * \param config A pointer to a PNF P7 config + * \return 0 means success, -1 means failure + * + * This function will not return until nfapi_pnf_p7_stop is called. + */ +int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config); + +/*! Stop the PNF P7 library. + * \param config A pointer to a PNF P7 config + * \return 0 means success, -1 means failure + * + * This function will cause the nfapi_pnf_p7_start to return + */ +int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config); + +/*! Subframe indication + * \param config A pointer to a PNF P7 config + * \param phy_id The phy_id for the phy instance + * \param sfn_sf The SFN and SF in the format of FAPI + * \return 0 means success, -1 means failure + * + * The client should call the subframe indication every 1ms. The PNF will + * respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer + * + * If messages are not in the subframe buffer, they dummy subframe messages will be sent + */ +int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf); + +/*! Send the HARQ.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the harq indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind); + +/*! Send the CRC.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the crc indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind); + +/*! Send the RX.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the rx indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind); + +/*! Send the RACH.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the rach indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind); + +/*! Send the SRS.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the srs indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind); + +/*! Send the SR.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the sr indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind); + +/*! Send the CQI.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the cqi indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind); + +/*! Send the LBT_DL.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the lbt dl indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind); + +/*! Send the NB_HARQ.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the lbt dl indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind); + +/*! Send the NRACH.indication + * \param config A pointer to a PNF P7 config + * \param ind A pointer to the lbt dl indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind); + + +/*! Send a vendor exntesion message + * \param config A pointer to a PNF P7 config + * \param msg A pointer to the lbt dl indication message structure + * \return 0 means success, -1 means failure + */ +int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg); + +#if defined(__cplusplus) +} +#endif + +#endif // _NFAPI_PNF_INTERFACE_H_ diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c new file mode 100644 index 0000000000..d0a7fa6fd1 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -0,0 +1,1598 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pnf.h" + +#define MAX_SCTP_STREAMS 16 + +void nfapi_pnf_phy_config_delete_all(nfapi_pnf_config_t* config) +{ + nfapi_pnf_phy_config_t* curr = config->phys; + while(curr != 0) + { + nfapi_pnf_phy_config_t* to_delete = curr; + curr = curr->next; + free(to_delete); + } + + config->phys = 0; +} + +void nfapi_pnf_phy_config_add(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy) +{ + phy->next = config->phys; + config->phys = phy; +} + +nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id) +{ + nfapi_pnf_phy_config_t* curr = config->phys; + while(curr != 0) + { + if(curr->phy_id == phy_id) + return curr; + + curr = curr->next; + } + return 0; +} + +void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_param_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n"); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_pnf_param_request_t), &pnf->_public.codec_config) >= 0) + { + if(pnf->_public.state == NFAPI_PNF_IDLE) + { + if(pnf->_public.pnf_param_req) + { + (pnf->_public.pnf_param_req)(&pnf->_public, &req); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__); + + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_pnf_param_resp(&pnf->_public, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_config_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n"); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) + { + // ensure correct state + if(pnf->_public.state != NFAPI_PNF_RUNNING) + { + // delete the phy records + nfapi_pnf_phy_config_delete_all(&pnf->_public); + + // create the phy records + if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG) + { + int i = 0; + for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t)); + memset(phy, 0, sizeof(nfapi_pnf_phy_config_t)); + + phy->state = NFAPI_PNF_PHY_IDLE; + phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id; + + nfapi_pnf_phy_config_add(&(pnf->_public), phy); + } + } + + if(pnf->_public.pnf_config_req) + { + (pnf->_public.pnf_config_req)(&(pnf->_public), &req); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state); + + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_pnf_config_resp(&(pnf->_public), &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_start_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n"); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) + { + if(pnf->_public.state == NFAPI_PNF_CONFIGURED) + { + if(pnf->_public.pnf_start_req) + { + (pnf->_public.pnf_start_req)(&(pnf->_public), &req); + } + } + else + { + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_pnf_start_resp(&(pnf->_public), &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_stop_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_STOP.request Received\n"); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) + { + if(pnf->_public.state == NFAPI_PNF_RUNNING) + { + if(pnf->_public.pnf_stop_req) + { + (pnf->_public.pnf_stop_req)(&(pnf->_public), &req); + } + } + else + { + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_pnf_stop_resp(&(pnf->_public), &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_param_request_t req; + + nfapi_pnf_config_t* config = &(pnf->_public); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n"); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_IDLE) + { + if(config->param_req) + { + (config->param_req)(config, phy, &req); + } + } + else + { + nfapi_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_param_resp(config, &resp); + } + } + else + { + nfapi_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_param_resp(config, &resp); + } + + } + else + { + nfapi_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_param_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + +void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_config_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->config_req) + { + (config->config_req)(config, phy, &req); + } + } + else + { + nfapi_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_config_resp(config, &resp); + } + } + else + { + nfapi_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_config_resp(config, &resp); + } + } + else + { + nfapi_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_config_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_start_request_t req; + + nfapi_pnf_config_t* config = &(pnf->_public); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->start_req) + { + (config->start_req)(config, phy, &req); + } + } + else + { + nfapi_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_start_resp(config, &resp); + } + } + else + { + nfapi_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_start_resp(config, &resp); + } + } + else + { + nfapi_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_start_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + +void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_stop_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->stop_req) + { + (config->stop_req)(config, phy, &req); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + +void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_measurement_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "MEASUREMENT.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->measurement_req) + { + (config->measurement_req)(config, phy, &req); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_measurement_resp(config, &resp); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_measurement_resp(config, &resp); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_measurement_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_rssi_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_rssi_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "RSSI.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_RUNNING) + { + if(config->rssi_req) + { + (config->rssi_req)(config, phy, &req); + } + } + else + { + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_rssi_resp(config, &resp); + } + } + else + { + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_rssi_resp(config, &resp); + } + } + else + { + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_rssi_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + +void pnf_handle_cell_search_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_cell_search_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "CELL_SEARCH.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_RUNNING) + { + if(config->cell_search_req) + { + (config->cell_search_req)(config, phy, &req); + } + } + else + { + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_cell_search_resp(config, &resp); + } + } + else + { + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_cell_search_resp(config, &resp); + } + } + else + { + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_cell_search_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } + +} + +void pnf_handle_broadcast_detect_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_broadcast_detect_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "BROADCAST_DETECT.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_RUNNING) + { + if(config->broadcast_detect_req) + { + (config->broadcast_detect_req)(config, phy, &req); + } + } + else + { + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_broadcast_detect_resp(config, &resp); + } + } + else + { + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_broadcast_detect_resp(config, &resp); + } + } + else + { + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_broadcast_detect_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + +void pnf_handle_system_information_schedule_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_system_information_schedule_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "SYSTEM_INFORMATION_SCHEDULE.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_RUNNING) + { + if(config->system_information_schedule_req) + { + (config->system_information_schedule_req)(config, phy, &req); + } + } + else + { + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_system_information_schedule_resp(config, &resp); + } + } + else + { + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_system_information_schedule_resp(config, &resp); + } + } + else + { + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_system_information_schedule_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + +void pnf_handle_system_information_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_system_information_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "SYSTEM_INFORMATION.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_RUNNING) + { + if(config->system_information_req) + { + (config->system_information_req)(config, phy, &req); + } + } + else + { + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_system_information_resp(config, &resp); + } + } + else + { + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_system_information_resp(config, &resp); + } + } + else + { + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_system_information_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } + +} + +void pnf_handle_nmm_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nmm_stop_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "NMM_STOP.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->nmm_stop_req) + { + (config->nmm_stop_req)(config, phy, &req); + } + } + else + { + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_nmm_stop_resp(config, &resp); + } + } + else + { + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_nmm_stop_resp(config, &resp); + } + } + else + { + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_nmm_stop_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + + +void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uint16_t message_id) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_config_t* config = &(pnf->_public); + + if(config->allocate_p4_p5_vendor_ext) + { + uint16_t msg_size; + nfapi_p4_p5_message_header_t* msg = config->allocate_p4_p5_vendor_ext(message_id, &msg_size); + + if(msg == 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + return; + } + + + int unpack_result = nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &config->codec_config); + + if(unpack_result == 0) + { + if(config->vendor_ext) + config->vendor_ext(config, msg); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(config->deallocate_p4_p5_vendor_ext) + config->deallocate_p4_p5_vendor_ext(msg); + + } + } +} + + + +void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + nfapi_p4_p5_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + switch (messageHeader.message_id) + { + case NFAPI_PNF_PARAM_REQUEST: + pnf_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_PNF_CONFIG_REQUEST: + pnf_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_PNF_START_REQUEST: + pnf_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_PNF_STOP_REQUEST: + pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_PARAM_REQUEST: + pnf_handle_param_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_CONFIG_REQUEST: + pnf_handle_config_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_START_REQUEST: + pnf_handle_start_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_STOP_REQUEST: + pnf_handle_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_MEASUREMENT_REQUEST: + pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_RSSI_REQUEST: + pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_CELL_SEARCH_REQUEST: + pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_BROADCAST_DETECT_REQUEST: + pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST: + pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_SYSTEM_INFORMATION_REQUEST: + pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NMM_STOP_REQUEST: + pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + default: + { + if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id); + } + } + break; + } +} + +int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) +{ + int packed_len = nfapi_p5_message_pack(msg, msg_len, + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), + &pnf->_public.codec_config); + + if (packed_len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len); + return -1; + } + + return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/); +} + +int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) +{ + int packed_len = nfapi_p4_message_pack(msg, msg_len, + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), + &pnf->_public.codec_config); + + if (packed_len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p4_message_pack failed (%d)\n", packed_len); + return -1; + } + + return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/); +} + + + +int pnf_connect(pnf_t* pnf) +{ + struct sockaddr_in servaddr; + uint8_t socketConnected = 0; + + if(pnf->_public.vnf_ip_addr == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnfIpAddress is null\n"); + return -1; + } + + + (void)memset(&servaddr, 0, sizeof(struct sockaddr_in)); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 PNF connection to VNF at %s:%u\n", pnf->_public.vnf_ip_addr, pnf->_public.vnf_p5_port); + + // todo split the vnf address list. currently only supporting 1 + + struct addrinfo hints, *servinfo; + memset(&hints, 0, sizeof(hints)); + + hints.ai_socktype = SOCK_STREAM; // For SCTP we are only interested in SOCK_STREAM + // todo : allow the client to restrict IPV4 or IPV6 + // todo : randomize which address to connect to? + + char port_str[8]; + snprintf(port_str, sizeof(port_str), "%d", pnf->_public.vnf_p5_port); + if(getaddrinfo(pnf->_public.vnf_ip_addr, port_str, &hints, &servinfo) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to get host (%s) addr info h_errno:%d \n", pnf->_public.vnf_ip_addr, h_errno); + return -1; + } + + struct addrinfo *p = servinfo; + int i = 0; + int connected = 0; + + while(p != NULL && connected == 0) + { + char* family = "Unknown"; + char* address = "Unknown"; + char _addr[128]; + + if(p->ai_family == AF_INET6) + { + family = "IPV6"; + struct sockaddr_in6* addr = (struct sockaddr_in6*)p->ai_addr; + inet_ntop(AF_INET6, &addr->sin6_addr, _addr, sizeof(_addr)); + address = &_addr[0]; + } + else if(p->ai_family == AF_INET) + { + family = "IPV4"; + struct sockaddr_in* addr = (struct sockaddr_in*)p->ai_addr; + address = inet_ntoa(addr->sin_addr); + } + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); + + if (pnf->sctp) + { + // open the SCTP socket + if ((pnf->p5_sock = socket(p->ai_family, SOCK_STREAM, IPPROTO_SCTP)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno); + freeaddrinfo(servinfo); + return -1; + } + int noDelay; + struct sctp_initmsg initMsg; + + (void)memset(&initMsg, 0, sizeof(struct sctp_initmsg)); + + // configure the socket options + NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF Setting the SCTP_INITMSG\n"); + initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + if (setsockopt(pnf->p5_sock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno); + freeaddrinfo(servinfo); + return -1; + } + noDelay = 1; + if (setsockopt(pnf->p5_sock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno); + freeaddrinfo(servinfo); + return -1; + + } + + struct sctp_event_subscribe events; + memset( (void *)&events, 0, sizeof(events) ); + events.sctp_data_io_event = 1; + + if(setsockopt(pnf->p5_sock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno); + freeaddrinfo(servinfo); + return -1; + } + } + else + { + // Create an IP socket point + if ((pnf->p5_sock = socket(p->ai_family, SOCK_STREAM, IPPROTO_IP)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno); + freeaddrinfo(servinfo); + return -1; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created...\n"); + + if (connect(pnf->p5_sock, p->ai_addr, p->ai_addrlen ) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After connect (address:%s port:%d) errno: %d\n", + pnf->_public.vnf_ip_addr, pnf->_public.vnf_p5_port, errno); + + if(errno == EINVAL) + { + freeaddrinfo(servinfo); + return -1; + } + else + { + if(pnf->terminate != 0) + { + freeaddrinfo(servinfo); + return 0; + } + else + { + close(pnf->p5_sock); + sleep(1); + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "connect succeeded...\n"); + + connected = 1; + } + + p = p->ai_next; + } + + freeaddrinfo(servinfo); + + // If we have failed to connect return 0 and it is retry + if(connected == 0) + return 0; + + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "After connect loop\n"); + if (pnf->sctp) + { + socklen_t optLen; + struct sctp_status status; + + (void)memset(&status, 0, sizeof(struct sctp_status)); + + // check the connection status + optLen = (socklen_t) sizeof(struct sctp_status); + if (getsockopt(pnf->p5_sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno); + return -1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Association ID = %d\n", status.sstat_assoc_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "Receiver window size = %d\n", status.sstat_rwnd); + NFAPI_TRACE(NFAPI_TRACE_INFO, "In Streams = %d\n", status.sstat_instrms); + NFAPI_TRACE(NFAPI_TRACE_INFO, "Out Streams = %d\n", status.sstat_outstrms); + + socketConnected = 1; + } + } + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Socket %s\n", socketConnected ? "CONNECTED" : "NOT_CONNECTED"); + return socketConnected; +} + +int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream) +{ + if (pnf->sctp) + { + if (sctp_sendmsg(pnf->p5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno); + return -1; + } + } + else + { + if (write(pnf->p5_sock, msg, len) != len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "read failed errno: %d\n", errno); + return -1; + } + } + return 0; +} + + +int pnf_read_dispatch_message(pnf_t* pnf) +{ + int socket_connected = 1; + + // 1. Peek the message header + // 2. If the message is larger than the stack buffer then create a dynamic buffer + // 3. Read the buffer + // 4. Handle the p5 message + + uint32_t header_buffer_size = NFAPI_HEADER_LENGTH; + uint8_t header_buffer[header_buffer_size]; + + uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure + uint8_t stack_buffer[stack_buffer_size]; + + uint8_t* dynamic_buffer = 0; + + uint8_t* read_buffer = &stack_buffer[0]; + uint32_t message_size = 0; + + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + struct sctp_sndrcvinfo sndrcvinfo; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + { + int flags = MSG_PEEK; + message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, /*(struct sockaddr*)&addr, &addr_len*/ 0, 0, &sndrcvinfo, &flags); + + if(message_size == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno); + return 0; + } + + nfapi_p4_p5_message_header_t header; + int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0); + if(unpack_result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n"); + return 0; + } + message_size = header.message_length; + + // now have the size of the mesage + } + + if(message_size > stack_buffer_size) + { + dynamic_buffer = (uint8_t*)malloc(message_size); + + if(dynamic_buffer == NULL) + { + // todo : add error mesage + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size); + return -1; + } + + read_buffer = dynamic_buffer; + } + + { + int flags = 0; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + if(recvmsg_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno); + } + else + { + if (flags & MSG_NOTIFICATION) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + + // todo - handle the events + } + else + { + /* + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n", + pnf->p5_sock, + inet_ntoa(addr.sin_addr), + ntohs(addr.sin_port), + sndrcvinfo.sinfo_assoc_id, + sndrcvinfo.sinfo_stream, + ntohl(sndrcvinfo.sinfo_ppid), + message_size, + flags); + */ + + // handle now if complete message in one or more segments + if ((flags & 0x80) == 0x80) + { + pnf_handle_p5_message(pnf, read_buffer, message_size); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags); + + // assume socket disconnected + NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n"); + socket_connected = 0; + } + + + } + } + } + + if(dynamic_buffer) + { + free(dynamic_buffer); + } + + return socket_connected; + + +} + + +int pnf_message_pump(pnf_t* pnf) +{ + uint8_t socketConnected = 1; + + while(socketConnected && pnf->terminate == 0) + { + fd_set rfds; + int selectRetval = 0; + + // select on a timeout and then get the message + FD_ZERO(&rfds); + FD_SET(pnf->p5_sock, &rfds); + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout); + + if(selectRetval == 0) + { + // timeout + continue; + } + else if (selectRetval == -1 && (errno == EINTR)) + { + // interrupted by signal + NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno); + continue; + } + else if (selectRetval == -1) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n"); + sleep(1); + continue; + } + + if(FD_ISSET(pnf->p5_sock, &rfds)) + { + socketConnected = pnf_read_dispatch_message(pnf); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n"); + } + } + + // Drop back to idle if we have lost connection + pnf->_public.state = NFAPI_PNF_PHY_IDLE; + + + // close the connection and socket + if (close(pnf->p5_sock) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno); + } + + return 0; + +} + diff --git a/nfapi/open-nFAPI/pnf/src/pnf_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_interface.c new file mode 100644 index 0000000000..7310fc0c66 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c @@ -0,0 +1,432 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include "pnf.h" +#include +#include +#include + +nfapi_pnf_config_t* nfapi_pnf_config_create() +{ + pnf_t* _this = (pnf_t*)malloc(sizeof(pnf_t)); + + if(_this == 0) + return 0; + + memset(_this, 0, sizeof(pnf_t)); + + _this->sctp = 1; // enable sctp + + _this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT; + + _this->_public.malloc = &malloc; + _this->_public.free = &free; + + _this->_public.codec_config.allocate = &malloc; + _this->_public.codec_config.deallocate = &free; + + return &(_this->_public); +} + +void nfapi_pnf_config_destory(nfapi_pnf_config_t* config) +{ + free(config); +} + +int nfapi_pnf_start(nfapi_pnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = config->trace; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + + pnf_t* _this = (pnf_t*)(config); + + while (_this->terminate == 0) + { + int connect_result = pnf_connect(_this); + + if(connect_result > 0) + { + pnf_message_pump(_this); + } + else if(connect_result < 0) + { + return connect_result; + } + + sleep(1); + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__); + + return 0; +} + +int nfapi_pnf_stop(nfapi_pnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + + pnf_t* _this = (pnf_t*)(config); + _this->terminate = 1; + + // todo wait for the pnf to stop before returning + + return 0; +} + +int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_param_response_t)); +} + +int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + if(resp->error_code == NFAPI_MSG_OK) + { + config->state = NFAPI_PNF_CONFIGURED; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t)); +} + +int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + if(resp->error_code == NFAPI_MSG_OK) + { + config->state = NFAPI_PNF_RUNNING; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t)); +} + +int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + if(resp->error_code == NFAPI_MSG_OK) + { + config->state = NFAPI_PNF_CONFIGURED; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t)); +} + +int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t)); +} + +int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id); + + if(phy) + { + if(resp->error_code == NFAPI_MSG_OK) + { + phy->state = NFAPI_PNF_PHY_CONFIGURED; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t)); +} + +int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id); + if(phy) + { + if(resp->error_code == NFAPI_MSG_OK) + { + phy->state = NFAPI_PNF_PHY_RUNNING; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t)); +} + +int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id); + if(phy) + { + if(resp->error_code == NFAPI_MSG_OK) + { + phy->state = NFAPI_PNF_PHY_CONFIGURED; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_stop_response_t)); +} + +int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_measurement_response_t)); +} + + +int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_rssi_response_t)); +} + +int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind) +{ + if (config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_rssi_indication_t)); +} +int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Send CELL_SEARCH.response\n"); + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_cell_search_response_t)); +} +int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind) +{ + if (config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_cell_search_indication_t)); +} +int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_broadcast_detect_response_t)); +} +int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind) +{ + if (config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_broadcast_detect_indication_t)); +} +int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1;; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_schedule_response_t)); +} + +int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind) +{ + if (config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_schedule_indication_t)); +} +int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_response_t)); +} + +int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind) +{ + if (config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_indication_t)); +} +int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_nmm_stop_request_t)); +} + +int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) +{ + // ensure it's valid + if (config == NULL || msg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_pack_and_send_p5_message(_this, msg, msg_len); +} + diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c new file mode 100644 index 0000000000..02b828d382 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -0,0 +1,1769 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pnf_p7.h" + +#define FAPI2_IP_DSCP 0 + +extern uint16_t sf_ahead; +//uint16_t sf_ahead=4; + +void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset) +{ + *frameP = *frameP + ((*subframeP + offset) / 10); + + *subframeP = ((*subframeP + offset) % 10); +} + +void subtract_sf(uint16_t *frameP, uint16_t *subframeP, int offset) +{ + if (*subframeP < offset) + { + *frameP = (*frameP+1024-1)%1024; + } + *subframeP = (*subframeP+10-offset)%10; +} + +uint16_t sfnsf_add_sf(uint16_t sfnsf, int offset) +{ + uint16_t new_sfnsf; + uint16_t sfn = NFAPI_SFNSF2SFN(sfnsf); + uint16_t sf = NFAPI_SFNSF2SF(sfnsf); + + //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf); + add_sf(&sfn, &sf, offset); + + new_sfnsf = sfn<<4|sf; + + //printf("%s() sfn:%u sf:%u offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, sfn, sf, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf)); + + return new_sfnsf; +} + +uint16_t sfnsf_subtract_sf(uint16_t sfnsf, int offset) +{ + uint16_t new_sfnsf; + uint16_t sfn = NFAPI_SFNSF2SFN(sfnsf); + uint16_t sf = NFAPI_SFNSF2SF(sfnsf); + + //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf); + subtract_sf(&sfn, &sf, offset); + + new_sfnsf = sfn<<4|sf; + + //printf("%s() offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf)); + + return new_sfnsf; +} + +uint32_t pnf_get_current_time_hr(void) +{ + struct timeval now; + (void)gettimeofday(&now, NULL); + uint32_t time_hr = TIME2TIMEHR(now); + return time_hr; +} + +void* pnf_p7_malloc(pnf_p7_t* pnf_p7, size_t size) +{ + if(pnf_p7->_public.malloc) + { + return (pnf_p7->_public.malloc)(size); + } + else + { + return calloc(1, size); + } +} +void pnf_p7_free(pnf_p7_t* pnf_p7, void* ptr) +{ + if(pnf_p7->_public.free) + { + return (pnf_p7->_public.free)(ptr); + } + else + { + return free(ptr); + } +} + +// todo : for now these just malloc/free need to move to a memory cache +nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7) +{ + void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_dl_config_request_t)); + //printf("%s() ptr:%p\n", __FUNCTION__, ptr); + return ptr; +} + +void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->dl_config_request_body.dl_config_pdu_list); + } + else + { + free(req->dl_config_request_body.dl_config_pdu_list); + } + req->dl_config_request_body.dl_config_pdu_list=0; + + pnf_p7_free(pnf_p7, req); +} + +nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7) +{ + void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_ul_config_request_t)); + //printf("%s() ptr:%p\n", __FUNCTION__, ptr); + return ptr; +} + +void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->ul_config_request_body.ul_config_pdu_list); + } + else + { + free(req->ul_config_request_body.ul_config_pdu_list); + } + req->ul_config_request_body.ul_config_pdu_list=0; + + pnf_p7_free(pnf_p7, req); +} + +nfapi_hi_dci0_request_t* allocate_nfapi_hi_dci0_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_hi_dci0_request_t)); +} + +void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->hi_dci0_request_body.hi_dci0_pdu_list); + } + else + { + free(req->hi_dci0_request_body.hi_dci0_pdu_list); + } + req->hi_dci0_request_body.hi_dci0_pdu_list=0; + + pnf_p7_free(pnf_p7, req); +} + +nfapi_tx_request_t* allocate_nfapi_tx_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_tx_request_t)); +} + +void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7) +{ + int i = 0; + + //printf("%s() SFN/SF:%d %s req:%p pdu[0]:data:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->tx_request_body.tx_pdu_list[i].segments[0].segment_data); + + for(i = 0; i < req->tx_request_body.number_of_pdus; ++i) + { + void* data = req->tx_request_body.tx_pdu_list[i].segments[0].segment_data; + + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(data); + } + else + { + free(data); + } + data=0; + } + + + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->tx_request_body.tx_pdu_list); + } + else + { + free(req->tx_request_body.tx_pdu_list); + } + req->tx_request_body.tx_pdu_list=0; + + pnf_p7_free(pnf_p7, req); +} + +nfapi_lbt_dl_config_request_t* allocate_nfapi_lbt_dl_config_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_lbt_dl_config_request_t)); +} + +void deallocate_nfapi_lbt_dl_config_request(nfapi_lbt_dl_config_request_t* req, pnf_p7_t* pnf_p7) +{ + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->lbt_dl_config_request_body.lbt_dl_config_req_pdu_list); + } + else + { + free(req->lbt_dl_config_request_body.lbt_dl_config_req_pdu_list); + } + req->lbt_dl_config_request_body.lbt_dl_config_req_pdu_list=0; + + pnf_p7_free(pnf_p7, req); +} + +pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len) +{ + pnf_p7_rx_message_t* msg = 0; + // attempt to find a entry for this segment + pnf_p7_rx_message_t* iterator = queue->msg_queue; + while(iterator != 0) + { + if(iterator->sequence_number == sequence_number) + { + msg = iterator; + break; + } + + iterator = iterator->next; + } + + // if found then copy data to message + if(msg != 0) + { + + msg->segments[segment_number].buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, data_len); + memcpy(msg->segments[segment_number].buffer, data, data_len); + msg->segments[segment_number].length = data_len; + + msg->num_segments_received++; + + // set the segement number if we have the last segment + if(m == 0) + msg->num_segments_expected = segment_number + 1; + } + // else add new rx message entry + else + { + // create a new message + msg = (pnf_p7_rx_message_t*)(pnf_p7_malloc(pnf_p7, sizeof(pnf_p7_rx_message_t))); + memset(msg, 0, sizeof(pnf_p7_rx_message_t)); + + msg->sequence_number = sequence_number; + msg->num_segments_expected = m ? 255 : segment_number + 1; + msg->num_segments_received = 1; + msg->rx_hr_time = rx_hr_time; + + msg->segments[segment_number].buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, data_len); + memcpy(msg->segments[segment_number].buffer, data, data_len); + msg->segments[segment_number].length = data_len; + + // place the message at the head of the queue + msg->next = queue->msg_queue; + queue->msg_queue = msg; + } + + return msg; +} + +void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg) +{ + // remove message if it has the same sequence number + pnf_p7_rx_message_t* iterator = queue->msg_queue; + pnf_p7_rx_message_t* previous = 0; + + while(iterator != 0) + { + if(iterator->sequence_number == msg->sequence_number) + { + if(previous == 0) + { + queue->msg_queue = iterator->next; + } + else + { + previous->next = iterator->next; + } + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Deleting reassembly message\n"); + // delete the message + uint16_t i; + for(i = 0; i < 128; ++i) + { + if(iterator->segments[i].buffer) + pnf_p7_free(pnf_p7, iterator->segments[i].buffer); + } + pnf_p7_free(pnf_p7, iterator); + + break; + } + + previous = iterator; + iterator = iterator->next; + } +} + +void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta) +{ + // remove all messages that are too old + pnf_p7_rx_message_t* iterator = queue->msg_queue; + pnf_p7_rx_message_t* previous = 0; + + while(iterator != 0) + { + if(rx_hr_time - iterator->rx_hr_time > delta) + { + if(previous == 0) + { + queue->msg_queue = iterator->next; + } + else + { + previous->next = iterator->next; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Deleting stale reassembly message (%u %u %d)\n", iterator->rx_hr_time, rx_hr_time, delta); + + pnf_p7_rx_message_t* to_delete = iterator; + iterator = iterator->next; + + // delete the message + uint16_t i; + for(i = 0; i < 128; ++i) + { + if(to_delete->segments[i].buffer) + pnf_p7_free(pnf_p7, to_delete->segments[i].buffer); + } + pnf_p7_free(pnf_p7, to_delete); + + } + else + { + previous = iterator; + iterator = iterator->next; + } + } +} + + +static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) +{ + if(now_hr < sf_start_hr) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + return 0; + } + else + { + uint32_t now_us = TIMEHR_USEC(now_hr); + uint32_t sf_start_us = TIMEHR_USEC(sf_start_hr); + + // if the us have wrapped adjust for it + if(now_hr < sf_start_us) + { + now_us += 1000000; + } + + return now_us - sf_start_us; + } +} + +int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len) +{ + // todo : consider how to do this only once + struct sockaddr_in remote_addr; + memset((char*)&remote_addr, 0, sizeof(struct sockaddr_in)); + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(pnf_p7->_public.remote_p7_port); + //remote_addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.remote_p7_addr); + if(inet_aton(pnf_p7->_public.remote_p7_addr, &remote_addr.sin_addr) == -1) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "inet_aton failed %d\n", errno); + return -1; + } + + socklen_t remote_addr_len = sizeof(struct sockaddr_in); + + int sendto_result; + if ((sendto_result = sendto((int)pnf_p7->p7_sock, (const char*)msg, len, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s %s:%d sendto(%d, %p, %d) %d failed errno: %d\n", __FUNCTION__, pnf_p7->_public.remote_p7_addr, pnf_p7->_public.remote_p7_port, (int)pnf_p7->p7_sock, (const char*)msg, len, remote_addr_len, errno); + return -1; + } + + if(sendto_result != len) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s sendto failed to send the entire message %d %d\n", __FUNCTION__, sendto_result, len); + } + return 0; +} + +int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len) +{ + header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number); + + // Need to guard against different threads calling the encode function at the same time + if(pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + + int len = nfapi_p7_message_pack(header, pnf_p7->tx_message_buffer, sizeof(pnf_p7->tx_message_buffer), &pnf_p7->_public.codec_config); + + if (len < 0) + { + if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len ); + return -1; + } + + if(len > pnf_p7->_public.segment_size) + { + int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; + int seg_body_len = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; + int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); + + int segment = 0; + int offset = NFAPI_P7_HEADER_LENGTH; + uint8_t buffer[pnf_p7->_public.segment_size]; + for(segment = 0; segment < segment_count; ++segment) + { + uint8_t last = 0; + uint16_t size = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH; + if(segment + 1 == segment_count) + { + last = 1; + size = (msg_body_len) - (seg_body_len * segment); + } + + uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH; + + // Update the header with the m and segement + memcpy(&buffer[0], pnf_p7->tx_message_buffer, NFAPI_P7_HEADER_LENGTH); + + // set the segment length + buffer[4] = (segment_size & 0xFF00) >> 8; + buffer[5] = (segment_size & 0xFF); + + // set the m & segment number + buffer[6] = ((!last) << 7) + segment; + + memcpy(&buffer[NFAPI_P7_HEADER_LENGTH], pnf_p7->tx_message_buffer + offset, size); + offset += size; + + if(pnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(buffer, segment_size); + } + + + pnf_p7_send_message(pnf_p7, &buffer[0], segment_size); + } + } + else + { + if(pnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(pnf_p7->tx_message_buffer, len); + } + + // simple case that the message fits in a single segment + pnf_p7_send_message(pnf_p7, pnf_p7->tx_message_buffer, len); + } + + pnf_p7->sequence_number++; + + if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + return 0; +} + +void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7) +{ + nfapi_timing_info_t timing_info; + memset(&timing_info, 0, sizeof(timing_info)); + timing_info.header.message_id = NFAPI_TIMING_INFO; + timing_info.header.phy_id = pnf_p7->_public.phy_id; + + timing_info.last_sfn_sf = pnf_p7->sfn_sf; + timing_info.time_since_last_timing_info = pnf_p7->timing_info_ms_counter; + + timing_info.dl_config_jitter = pnf_p7->dl_config_jitter; + timing_info.tx_request_jitter = pnf_p7->tx_jitter; + timing_info.ul_config_jitter = pnf_p7->ul_config_jitter; + timing_info.hi_dci0_jitter = pnf_p7->hi_dci0_jitter; + + timing_info.dl_config_latest_delay = 0; + timing_info.tx_request_latest_delay = 0; + timing_info.ul_config_latest_delay = 0; + timing_info.hi_dci0_latest_delay = 0; + + timing_info.dl_config_earliest_arrival = 0; + timing_info.tx_request_earliest_arrival = 0; + timing_info.ul_config_earliest_arrival = 0; + timing_info.hi_dci0_earliest_arrival = 0; + + + pnf_p7_pack_and_send_p7_message(pnf_p7, &(timing_info.header), sizeof(timing_info)); + + pnf_p7->timing_info_ms_counter = 0; +} + +void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) +{ + struct timespec t; + clock_gettime( CLOCK_MONOTONIC, &t); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(sfn_sf:%d) t:%ld.%09ld\n", __FUNCTION__, NFAPI_SFNSF2DEC(sfn_sf), t.tv_sec, t.tv_nsec); + + if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) + { + pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf; + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - enter\n"); + (pnf_p7->_public.tx_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.tx_req); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - exit\n"); + } + 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; + //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); + //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); + } + 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); + } + if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) + { + pnf_p7->_public.dummy_subframe.lbt_dl_config_req->sfn_sf = sfn_sf; + NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy lbt - enter\n"); + (pnf_p7->_public.lbt_dl_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.lbt_dl_config_req); + } +} + +int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) +{ + // We could either send an event to the p7 thread have have it run the + // subframe or we could handle it here and lock access to the subframe + // buffers. If we do it on the p7 thread then we run the risk of blocking + // on the udp send. + // + // todo : start a timer to give us more of the 1 ms tick before send back + // the frame + + // todo : consider a more efficent lock mechasium + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + +#if 1 + // save the curren time and sfn_sf + pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); + pnf_p7->sfn_sf = sfn_sf; + + uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); + uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); + + // If the subframe_buffer has been configured + if(pnf_p7->_public.subframe_buffer_size != 0) + { + + // apply the shift to the incoming sfn_sf + if(pnf_p7->sfn_sf_shift != 0) + { + int32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + + int32_t shifted_sfn_sf = sfn_sf_dec += pnf_p7->sfn_sf_shift; + + // adjust for wrap-around + if(shifted_sfn_sf < 0) + shifted_sfn_sf += NFAPI_MAX_SFNSFDEC; + else if(shifted_sfn_sf > NFAPI_MAX_SFNSFDEC) + shifted_sfn_sf -= NFAPI_MAX_SFNSFDEC; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/sf (%d -> %d)\n", pnf_p7->sfn_sf_shift, NFAPI_SFNSF2DEC(sfn_sf), shifted_sfn_sf); + sfn_sf = shifted_sfn_sf; + + // + // DJP - why does the shift not apply to pnf_p7->sfn_sf??? + // + + pnf_p7->sfn_sf_shift = 0; + } + + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + nfapi_pnf_p7_subframe_buffer_t* subframe_buffer = &(pnf_p7->subframe_buffer[buffer_index]); + + uint8_t tx_buffer_index = tx_sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + nfapi_pnf_p7_subframe_buffer_t* tx_subframe_buffer = &(pnf_p7->subframe_buffer[tx_buffer_index]); + + //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); + + if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d subframe_buffer->sfn_sf:%d tx_subframe_buffer->sfn_sf:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] " + "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n", + __FUNCTION__, + pnf_p7->sfn_sf_shift, + NFAPI_SFNSF2DEC(subframe_buffer->sfn_sf), + NFAPI_SFNSF2DEC(tx_subframe_buffer->sfn_sf), + sfn_sf_dec, buffer_index, subframe_buffer->dl_config_req, subframe_buffer->tx_req, + tx_sfn_sf_dec, tx_buffer_index, tx_subframe_buffer->dl_config_req, tx_subframe_buffer->tx_req); + + // if the subframe buffer sfn sf is set then we have atlease 1 message + // from the vnf. + // todo : how to handle the messages we don't have, send dummies for + // now + + //printf("tx_subframe_buffer->sfn_sf:%d sfn_sf_tx:%d\n", tx_subframe_buffer->sfn_sf, sfn_sf_tx); + //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf); + if(tx_subframe_buffer->sfn_sf == sfn_sf_tx) + { + if(tx_subframe_buffer->tx_req != 0) + { + if(pnf_p7->_public.tx_req) + (pnf_p7->_public.tx_req)(&(pnf_p7->_public), tx_subframe_buffer->tx_req); + + //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) + { + pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.tx_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.tx_req); + } + } + + 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); + + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + } + else + { + // send dummy + 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); + } + } + + 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); + + //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + } + else + { + //send dummy + 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); + } + } + + if(tx_subframe_buffer->dl_config_req != 0) + { + deallocate_nfapi_dl_config_request(tx_subframe_buffer->dl_config_req, pnf_p7); + tx_subframe_buffer->dl_config_req = 0; + } + if(tx_subframe_buffer->tx_req != 0) + { + deallocate_nfapi_tx_request(tx_subframe_buffer->tx_req, pnf_p7); + tx_subframe_buffer->tx_req = 0; + } + if(tx_subframe_buffer->hi_dci0_req != 0) + { + deallocate_nfapi_hi_dci0_request(tx_subframe_buffer->hi_dci0_req, pnf_p7); + tx_subframe_buffer->hi_dci0_req = 0; + } + } + else + { + // If we ever need to "send" a dummy ul_config this won't work!!! + send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + if(subframe_buffer->sfn_sf == 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); + + //deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + } + else + { + // send dummy + 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); + } + } + + if(subframe_buffer->lbt_dl_config_req != 0) + { + if(pnf_p7->_public.lbt_dl_config_req) + (pnf_p7->_public.lbt_dl_config_req)(&(pnf_p7->_public), subframe_buffer->lbt_dl_config_req); + + //deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) + { + pnf_p7->_public.dummy_subframe.lbt_dl_config_req->sfn_sf = sfn_sf; + (pnf_p7->_public.lbt_dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.lbt_dl_config_req); + } + + } + + //if(subframe_buffer->dl_config_req != 0) + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + //if(subframe_buffer->tx_req != 0) + //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + if(subframe_buffer->ul_config_req != 0) + { + deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + subframe_buffer->ul_config_req = 0; + + } + //if(subframe_buffer->hi_dci0_req != 0) + //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + if(subframe_buffer->lbt_dl_config_req != 0) + { + deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); + subframe_buffer->lbt_dl_config_req = 0; + } + } // sfn_sf match + + if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0) + { + memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t)); + pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1; + } + + //printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period); + //printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send); + //printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter); + + // send the periodic timing info if configured + if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) + { + pnf_pack_and_send_timing_info(pnf_p7); + + pnf_p7->timing_info_period_counter = 0; + } + else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) + { + pnf_pack_and_send_timing_info(pnf_p7); + + pnf_p7->timing_info_aperiodic_send = 0; + } + else + { + pnf_p7->timing_info_ms_counter++; + } + } + else + { + //send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + + //printf("pnf_p7->tick:%d\n", pnf_p7->tick); + if(pnf_p7->tick == 1000) + { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id, + pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late, + pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late, + pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late, + pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late); + pnf_p7->tick = 0; + memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats)); + } + pnf_p7->tick++; +#endif + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + return 0; +} + + + +// return 1 if in window +// return 0 if out of window +uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) +{ + uint32_t recv_sfn_sf_dec = NFAPI_SFNSF2DEC(sfnsf); + uint32_t current_sfn_sf_dec = NFAPI_SFNSF2DEC(phy->sfn_sf); + + uint8_t in_window = 0; + uint8_t timing_window = phy->_public.subframe_buffer_size; + + if(recv_sfn_sf_dec <= current_sfn_sf_dec) + { + // Need to check for wrap in window + if(((current_sfn_sf_dec + timing_window) % NFAPI_MAX_SFNSFDEC) < current_sfn_sf_dec) + { + if(recv_sfn_sf_dec > ((current_sfn_sf_dec + timing_window) % NFAPI_MAX_SFNSFDEC)) + { + // out of window + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is late %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + } + else + { + // ok + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + in_window = 1; + } + } + else + { + // too late + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in late %d (delta:%d)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (current_sfn_sf_dec - recv_sfn_sf_dec)); + } + + } + else + { + // Need to check it is in window + if((recv_sfn_sf_dec - current_sfn_sf_dec) <= timing_window) + { + // in window + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + in_window = 1; + } + else + { + // too far in the future + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (recv_sfn_sf_dec - current_sfn_sf_dec), timing_window); + } + + } + + return in_window; +} + + +// P7 messages +// +void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n"); + + nfapi_dl_config_request_t* req = allocate_nfapi_dl_config_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_config_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_dl_config_request_t), &(pnf_p7->_public.codec_config)); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if ( + 0 && + (NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 || + NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0 + ) + ) + NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + req->dl_config_request_body.number_pdcch_ofdm_symbols, + req->dl_config_request_body.number_dci, + req->dl_config_request_body.number_pdu, + req->dl_config_request_body.number_pdsch_rnti, + req->dl_config_request_body.transmission_power_pcfich + ); + + if(is_p7_request_in_window(req->sfn_sf, "dl_config_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + // if there is already an dl_config_req make sure we free it. + if(pnf_p7->subframe_buffer[buffer_index].dl_config_req != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_sf:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), buffer_index); + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + deallocate_nfapi_dl_config_request(pnf_p7->subframe_buffer[buffer_index].dl_config_req, pnf_p7); + } + + // saving dl_config_request in subframe buffer + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].dl_config_req = req; + + pnf_p7->stats.dl_conf_ontime++; + + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf); + deallocate_nfapi_dl_config_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.dl_conf_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_config_req"); + deallocate_nfapi_dl_config_request(req, pnf_p7); + } +} + +void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n"); + + nfapi_ul_config_request_t* req = allocate_nfapi_ul_config_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_config_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ul_config_request_t), &(pnf_p7->_public.codec_config)); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "ul_config_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + if(pnf_p7->subframe_buffer[buffer_index].ul_config_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_ul_config_request(pnf_p7->subframe_buffer[buffer_index].ul_config_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].ul_config_req = req; + + pnf_p7->stats.ul_conf_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_config_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SF %d\n", NFAPI_SFNSF2DEC(pnf_p7->sfn_sf), NFAPI_SFNSF2DEC(req->sfn_sf)); + deallocate_nfapi_ul_config_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.ul_conf_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_config_req\n"); + deallocate_nfapi_ul_config_request(req, pnf_p7); + } +} + +void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "HI_DCI0.req Received\n"); + + nfapi_hi_dci0_request_t* req = allocate_nfapi_hi_dci0_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_hi_dci0_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_hi_dci0_request_t), &pnf_p7->_public.codec_config); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "hi_dci0_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + if(pnf_p7->subframe_buffer[buffer_index].hi_dci0_req!= 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing hi_dci0_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_hi_dci0_request(pnf_p7->subframe_buffer[buffer_index].hi_dci0_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].hi_dci0_req = req; + + pnf_p7->stats.hi_dci0_ontime++; + + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing hi_dci0_req SFN/SF %d/%d\n", pMyPhyInfo->sfnSf, SFNSF2SFN(req->sfn_sf), SFNSF2SF(req->sfn_sf)); + deallocate_nfapi_hi_dci0_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.hi_dci0_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack hi_dci0_req\n"); + deallocate_nfapi_hi_dci0_request(req, pnf_p7); + } +} + +void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "TX.req Received\n"); + + nfapi_tx_request_t* req = allocate_nfapi_tx_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_tx_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_tx_request_t), &pnf_p7->_public.codec_config); + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "tx_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->tx_request_body.number_of_pdus); + + if(pnf_p7->subframe_buffer[buffer_index].tx_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing tx_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_tx_request(pnf_p7->subframe_buffer[buffer_index].tx_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].tx_req = req; + + pnf_p7->stats.tx_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() TX_REQUEST Request is outside of window REQ:SFN_SF:%d CURR:SFN_SF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), NFAPI_SFNSF2DEC(pnf_p7->sfn_sf)); + + deallocate_nfapi_tx_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.tx_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + deallocate_nfapi_tx_request(req, pnf_p7); + } +} + +void pnf_handle_lbt_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + nfapi_lbt_dl_config_request_t* req = allocate_nfapi_lbt_dl_config_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_lbt_dl_config_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_lbt_dl_config_request_t), &pnf_p7->_public.codec_config); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "lbt_dl_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + if(pnf_p7->subframe_buffer[buffer_index].lbt_dl_config_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing tx_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_lbt_dl_config_request(pnf_p7->subframe_buffer[buffer_index].lbt_dl_config_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].lbt_dl_config_req = req; + } + else + { + deallocate_nfapi_lbt_dl_config_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + deallocate_nfapi_lbt_dl_config_request(req, pnf_p7); + } + +} + +void pnf_handle_p7_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint16_t message_id) +{ + if(pnf_p7->_public.allocate_p7_vendor_ext) + { + uint16_t msg_size; + nfapi_p7_message_header_t* msg = pnf_p7->_public.allocate_p7_vendor_ext(message_id, &msg_size); + + if(msg == 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &pnf_p7->_public.codec_config); + + if(unpack_result == 0) + { + if(pnf_p7->_public.vendor_ext) + pnf_p7->_public.vendor_ext(&(pnf_p7->_public), msg); + } + + if(pnf_p7->_public.deallocate_p7_vendor_ext) + pnf_p7->_public.deallocate_p7_vendor_ext(msg); + + } + +} + + +uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr) +{ + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + uint32_t t2 = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + + if (0) + { + static uint32_t prev_t2 = 0; + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(now_time_hr:%u sfn_sf:%d sf_start_time_Hr:%u) sf_time_us:%u t2:%u prev_t2:%u diff:%u\n", + __FUNCTION__, + now_time_hr, NFAPI_SFNSF2DEC(sfn_sf), sf_start_time_hr, + sf_time_us, + t2, + prev_t2, + t2-prev_t2); + + prev_t2 = t2; + } + + return t2; +} + +uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr) +{ + uint32_t now_time_hr = pnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + + uint32_t t3 = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + + return t3; +} + +void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + nfapi_dl_node_sync_t dl_node_sync; + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_NODE_SYNC Received\n"); + + if (pRecvMsg == NULL || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return; + } + + // unpack the message + if (nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + return; + } + + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + + if (dl_node_sync.delta_sfn_sf != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Will shift SF timing by %d on next subframe\n", dl_node_sync.delta_sfn_sf); + + pnf_p7->sfn_sf_shift = dl_node_sync.delta_sfn_sf; + } + + nfapi_ul_node_sync_t ul_node_sync; + memset(&ul_node_sync, 0, sizeof(ul_node_sync)); + ul_node_sync.header.message_id = NFAPI_UL_NODE_SYNC; + ul_node_sync.header.phy_id = dl_node_sync.header.phy_id; + ul_node_sync.t1 = dl_node_sync.t1; + ul_node_sync.t2 = calculate_t2(rx_hr_time, pnf_p7->sfn_sf, pnf_p7->sf_start_time_hr); + ul_node_sync.t3 = calculate_t3(pnf_p7->sfn_sf, pnf_p7->sf_start_time_hr); + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + + pnf_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync)); +} + +void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + nfapi_p7_message_header_t header; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + switch (header.message_id) + { + case NFAPI_DL_NODE_SYNC: + pnf_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time); + break; + + case NFAPI_DL_CONFIG_REQUEST: + pnf_handle_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_UL_CONFIG_REQUEST: + pnf_handle_ul_config_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_HI_DCI0_REQUEST: + pnf_handle_hi_dci0_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_TX_REQUEST: + pnf_handle_tx_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + default: + { + if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + pnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, pnf_p7, header.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P7 Unknown message ID %d\n", __FUNCTION__, header.message_id); + } + } + break; + } +} + +void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + nfapi_p7_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, pnf_p7); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence); + uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence); + uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence); + + if(pnf_p7->_public.checksum_enabled) + { + uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen); + if(checksum != messageHeader.checksum) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum); + return; + } + } + + if(m == 0 && segment_num == 0) + { + // we have a complete message + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + pnf_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time); + } + else + { + pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, sequence_num, segment_num, m, pRecvMsg, recvMsgLen); + + if(rx_msg->num_segments_received == rx_msg->num_segments_expected) + { + // send the buffer on + uint16_t i = 0; + uint16_t length = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0); + } + + if(pnf_p7->reassemby_buffer_size < length) + { + pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer); + pnf_p7->reassemby_buffer = 0; + } + + if(pnf_p7->reassemby_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length); + pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length); + + if(pnf_p7->reassemby_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length); + return; + } + + pnf_p7->reassemby_buffer_size = length; + } + + uint16_t offset = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + if(i == 0) + { + memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length); + offset += rx_msg->segments[i].length; + } + else + { + memcpy(pnf_p7->reassemby_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH); + offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH; + } + } + + + pnf_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time); + + + // delete the structure + pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg); + } + } + + pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000); + +} +void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) +{ + int recvfrom_result = 0; + struct sockaddr_in remote_addr; + socklen_t remote_addr_size = sizeof(remote_addr); + + do + { + // peek the header + uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH]; + recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size); + + if(recvfrom_result > 0) + { + // get the segment size + nfapi_p7_message_header_t header; + nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, 34, 0); + + // resize the buffer if we have a large segment + if(header.message_length > pnf_p7->rx_message_buffer_size) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); + pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length); + pnf_p7->rx_message_buffer_size = header.message_length; + } + + // read the segment + recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, header.message_length, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + + now_hr_time = pnf_get_current_time_hr(); //DJP - moved to here - get closer timestamp??? + + if(recvfrom_result > 0) + { + pnf_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time); + } + } + else if(recvfrom_result == 0) + { + // recv zero length message + recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + } + + if(recvfrom_result == -1) + { + if(errno == EAGAIN || errno == EWOULDBLOCK) + { + // return to the select + //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + } + + // need to update the time as we would only use the value from the + // select +#if 0 +// DJP - why do this here and not on return from recv??? + now_hr_time = pnf_get_current_time_hr(); +#endif + } + while(recvfrom_result > 0); +} + +int pnf_p7_message_pump(pnf_p7_t* pnf_p7) +{ + + // initialize the mutex lock + if(pthread_mutex_init(&(pnf_p7->mutex), NULL) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno); + return -1; + } + + if(pthread_mutex_init(&(pnf_p7->pack_mutex), NULL) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno); + return -1; + } + + // create the pnf p7 socket + if ((pnf_p7->p7_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno); + return -1; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 socket created (%d)...\n", pnf_p7->p7_sock); + + // configure the UDP socket options + int reuseaddr_enable = 1; + if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_enable, sizeof(int)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEADDR) failed errno: %d\n", errno); + return -1; + } + +/* + int reuseport_enable = 1; + if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport_enable, sizeof(int)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEPORT) failed errno: %d\n", errno); + return -1; + } +*/ + + int iptos_value = FAPI2_IP_DSCP << 2; + if (setsockopt(pnf_p7->p7_sock, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (IPPROTO_IP, IP_TOS) failed errno: %d\n", errno); + return -1; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(pnf_p7->_public.local_p7_port); + + if(pnf_p7->_public.local_p7_addr == 0) + { + addr.sin_addr.s_addr = INADDR_ANY; + } + else + { + //addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.local_p7_addr); + if(inet_aton(pnf_p7->_public.local_p7_addr, &addr.sin_addr) == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "inet_aton failed\n"); + } + } + + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 binding %d too %s:%d\n", pnf_p7->p7_sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + if (bind(pnf_p7->p7_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 bind error fd:%d errno: %d\n", pnf_p7->p7_sock, errno); + return -1; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 bind succeeded...\n"); + + while(pnf_p7->terminate == 0) + { + fd_set rfds; + int selectRetval = 0; + + // select on a timeout and then get the message + FD_ZERO(&rfds); + FD_SET(pnf_p7->p7_sock, &rfds); + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout); + + uint32_t now_hr_time = pnf_get_current_time_hr(); + + if(selectRetval == 0) + { + // timeout + continue; + } + else if (selectRetval == -1 && (errno == EINTR)) + { + // interrupted by signal + NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 Signal Interrupt %d\n", errno); + continue; + } + else if (selectRetval == -1) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 select() failed\n"); + sleep(1); + continue; + } + + if(FD_ISSET(pnf_p7->p7_sock, &rfds)) + { + pnf_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time); + } + } + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 Terminating..\n"); + + // close the connection and socket + if (close(pnf_p7->p7_sock) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "close failed errno: %d\n", errno); + } + + if(pthread_mutex_destroy(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno); + } + + if(pthread_mutex_destroy(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno); + } + + return 0; +} diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c new file mode 100644 index 0000000000..74de5e5d78 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -0,0 +1,225 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include "pnf_p7.h" +#include +#include + +nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create() +{ + pnf_p7_t* _this = (pnf_p7_t*)calloc(1, sizeof(pnf_p7_t)); + + if(_this == 0) + return 0; + + + // set the default parameters + _this->_public.segment_size = 1400; + _this->max_num_segments = 8; + + _this->_public.subframe_buffer_size = 8; + _this->_public.timing_info_mode_periodic = 1; + _this->_public.timing_info_period = 32; + _this->_public.timing_info_mode_aperiodic = 1; + + _this->_public.checksum_enabled = 1; + + _this->_public.malloc = &malloc; + _this->_public.free = &free; + + _this->_public.codec_config.allocate = &malloc; + _this->_public.codec_config.deallocate = &free; + + return &(_this->_public); +} + +void nfapi_pnf_p7_config_destory(nfapi_pnf_p7_config_t* config) +{ + if(config == 0) + return ; + + free(config); +} + + + +int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = config->trace; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + + pnf_p7_message_pump(_this); + + return 0; +} + +int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + _this->terminate = 1; + + return 0; +} + + +int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf) +{ + // Verify that config is not null + if(config == 0) + return -1; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_subframe_ind(_this, phy_id, sfn_sf); +} + +int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_harq_indication_t)); +} +int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_crc_indication_t)); +} +int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rx_indication_t)); +} +int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rach_indication_t)); +} +int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_srs_indication_t)); +} +int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_sr_indication_t)); +} +int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_cqi_indication_t)); +} +int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_lbt_dl_indication_t)); +} +int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nb_harq_indication_t)); +} +int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind) +{ + if(config == NULL || ind == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nrach_indication_t)); +} +int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg) +{ + if(config == NULL || msg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + return pnf_p7_pack_and_send_p7_message(_this, msg, 0); +} + diff --git a/nfapi/open-nFAPI/pnf/tests/Makefile.am b/nfapi/open-nFAPI/pnf/tests/Makefile.am new file mode 100644 index 0000000000..4dcdea0511 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/tests/Makefile.am @@ -0,0 +1,28 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +#nfapi unit test +AUTOMAKE_OPTIONS=subdir-objects +AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror + +check_PROGRAMS= test_pnf + +test_pnf_SOURCES = pnf_cunit_main.c ../../common/src/debug.c +test_pnf_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit + +LOG_DRIVER = $(top_srcdir)/tap-driver.sh +TESTS=$(check_PROGRAMS) +EXTRA_DIST = $(TESTS) diff --git a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c new file mode 100644 index 0000000000..d2ab031ad4 --- /dev/null +++ b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c @@ -0,0 +1,2365 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "CUnit.h" + +#include "Basic.h" +#include "Automated.h" +//#include "CUnit/Console.h" + +#include "nfapi_interface.h" +#include "nfapi_pnf_interface.h" +#include "nfapi.h" +#include // for printf +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" + +/* Test Suite setup and cleanup functions: */ + +int init_suite(void) { return 0; } +int clean_suite(void) { return 0; } + +#define MAX_PACKED_MESSAGE_SIZE 8192 + +typedef struct phy_info +{ + uint8_t enabled; + uint16_t phy_id; + uint16_t sfn_sf; + + pthread_t thread; + + int pnf_p7_port; + char* pnf_p7_addr; + + int vnf_p7_port; + char* vnf_p7_addr; + + nfapi_pnf_p7_config_t* config; + +} phy_info_t; + +typedef struct pnf_info +{ + uint8_t num_phys; + phy_info_t phys[8]; + +} pnf_info_t; + +phy_info_t* find_phy_info(pnf_info_t* pnf, uint16_t phy_id) +{ + int i = 0; + for(i = 0; i < 8; ++i) + { + if(pnf->phys[i].enabled == 1 && pnf->phys[i].phy_id == phy_id) + { + return &(pnf->phys[i]); + } + } + return 0; +} + + + +/************* Test case functions ****************/ + +void pnf_test_start_no_config(void) +{ + int result = nfapi_pnf_start(0); + CU_ASSERT_EQUAL(result, -1); +} + +void test_trace(nfapi_trace_level_t level, const char* message, ...) +{ + printf("%s", message); +} + + +void* pnf_test_start_thread(void* ptr) +{ + int result = nfapi_pnf_start((nfapi_pnf_config_t*)ptr); + return (void*)(intptr_t)result; +} + +void* pnf_test_start_p7_thread(void* ptr) +{ + int result = nfapi_pnf_p7_start((nfapi_pnf_p7_config_t*)ptr); + return (void*)(intptr_t)result; +} + +void pnf_test_start_no_connection(void) +{ + char* vnf_addr = "127.127.0.1"; + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + sleep(1); + + nfapi_pnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL(result, 0); +} + +void pnf_test_start_no_ip(void) +{ + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + sleep(2); + + nfapi_pnf_stop(config); + + intptr_t result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL((int)result, -1); +} + +void pnf_test_start_invalid_ip(void) +{ + char* vnf_addr = "not.an.ip.address"; + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + sleep(2); + + nfapi_pnf_stop(config); + + intptr_t result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL((int)result, -1); +} + +int create_p5_listen_socket(char* ip, int port) +{ + int p5ListenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; + + // bind to the configured address and port + bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); + + return p5ListenSock; +} +int create_p5_ipv6_listen_socket(char* ip, int port) +{ + struct addrinfo hints, *servinfo; + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; // For SCTP we are only interested in SOCK_STREAM + hints.ai_family= AF_INET6; + + char port_str[8]; + snprintf(port_str, sizeof(port_str), "%d", port); + getaddrinfo(ip, port_str, &hints, &servinfo); + + + int p5ListenSock = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP); + //printf("Socket result %d\n", p5ListenSock); + + // bind to the configured address and port + /*int bind_result = */ + bind(p5ListenSock, servinfo->ai_addr, servinfo->ai_addrlen); + //printf("Bind result %d (errno:%d)\n", bind_result, errno); + + freeaddrinfo(servinfo); + + return p5ListenSock; +} + +/* +int wait_for_pnf_connection(int p5ListenSock) +{ + listen(p5ListenSock, 2); + socklen_t addrSize; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + + return p5Sock; +} +*/ + +int test_param_request_called = 0; +int test_pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req) +{ + printf("test_pnf_param_request called.... ;-)\n"); + + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + + resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + resp.pnf_param_general.nfapi_sync_mode = 2; + resp.pnf_param_general.location_mode = 1; + resp.pnf_param_general.location_coordinates[0] = 123; + resp.pnf_param_general.dl_config_timing = 12; + resp.pnf_param_general.tx_timing = 12; + resp.pnf_param_general.ul_config_timing = 12; + resp.pnf_param_general.hi_dci0_timing = 12; + resp.pnf_param_general.maximum_number_phys = 2; + resp.pnf_param_general.maximum_total_bandwidth = 100; + resp.pnf_param_general.maximum_total_number_dl_layers = 2; + resp.pnf_param_general.maximum_total_number_ul_layers = 2; + resp.pnf_param_general.shared_bands = 0; + resp.pnf_param_general.shared_pa = 0; + resp.pnf_param_general.maximum_total_power = -190; + resp.pnf_param_general.oui[0] = 88; +/* + in.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + in.pnf_phy.number_of_phys = 2; + in.pnf_phy.phy[0].phy_config_index = 0; + in.pnf_phy.phy[0].number_of_rfs = 2; + in.pnf_phy.phy[0].rf_config[0].rf_config_index = 0; + in.pnf_phy.phy[0].number_of_rf_exclusions = 1; + in.pnf_phy.phy[0].rf_config[0].rf_config_index = 1; + in.pnf_phy.phy[0].downlink_channel_bandwidth_supported = 20; + in.pnf_phy.phy[0].uplink_channel_bandwidth_supported = 20; + in.pnf_phy.phy[0].number_of_dl_layers_supported = 2; + in.pnf_phy.phy[0].number_of_ul_layers_supported = 1; + in.pnf_phy.phy[0].maximum_3gpp_release_supported = 3; + in.pnf_phy.phy[0].nmm_modes_supported = 2; + + in.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG; + in.pnf_rf.number_of_rfs = 2; + in.pnf_rf.rf[0].rf_config_index = 0; + in.pnf_rf.rf[0].band = 1; + in.pnf_rf.rf[0].maximum_transmit_power = -100; + in.pnf_rf.rf[0].minimum_transmit_power = -90; + in.pnf_rf.rf[0].number_of_antennas_suppported = 4; + in.pnf_rf.rf[0].minimum_downlink_frequency = 100; + in.pnf_rf.rf[0].maximum_downlink_frequency = 2132; + in.pnf_rf.rf[0].minimum_uplink_frequency = 1231; + in.pnf_rf.rf[0].maximum_uplink_frequency = 123; + + + in.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; + in.pnf_phy_rel10.number_of_phys = 2; + in.pnf_phy_rel10.phy[0].phy_config_index = 0; + in.pnf_phy_rel10.phy[0].transmission_mode_7_supported = 1; + in.pnf_phy_rel10.phy[0].transmission_mode_8_supported = 2; + in.pnf_phy_rel10.phy[0].two_antenna_ports_for_pucch = 3; + in.pnf_phy_rel10.phy[0].transmission_mode_9_supported = 4; + in.pnf_phy_rel10.phy[0].simultaneous_pucch_pusch = 5; + in.pnf_phy_rel10.phy[0].four_layer_tx_with_tm3_and_tm4 = 6; + + in.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG; + in.pnf_phy_rel11.number_of_phys = 2; + in.pnf_phy_rel11.phy[0].phy_config_index = 0; + in.pnf_phy_rel11.phy[0].edpcch_supported = 1; + in.pnf_phy_rel11.phy[0].multi_ack_csi_reporting = 2; + in.pnf_phy_rel11.phy[0].pucch_tx_diversity = 3; + in.pnf_phy_rel11.phy[0].ul_comp_supported = 4; + in.pnf_phy_rel11.phy[0].transmission_mode_5_supported = 5; + + in.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG; + in.pnf_phy_rel12.number_of_phys = 2; + in.pnf_phy_rel12.phy[0].phy_config_index = 0; + in.pnf_phy_rel12.phy[0].csi_subframe_set = 1; + in.pnf_phy_rel12.phy[0].enhanced_4tx_codebook = 2; + in.pnf_phy_rel12.phy[0].drs_supported = 3; + in.pnf_phy_rel12.phy[0].ul_64qam_supported = 4; + in.pnf_phy_rel12.phy[0].transmission_mode_10_supported = 5; + in.pnf_phy_rel12.phy[0].alternative_bts_indices = 6; + + in.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG; + in.pnf_phy_rel13.number_of_phys = 2; + in.pnf_phy_rel13.phy[0].phy_config_index = 0; + in.pnf_phy_rel13.phy[0].pucch_format4_supported = 1; + in.pnf_phy_rel13.phy[0].pucch_format5_supported = 2; + in.pnf_phy_rel13.phy[0].more_than_5_ca_support = 3; + in.pnf_phy_rel13.phy[0].laa_supported = 4; + in.pnf_phy_rel13.phy[0].laa_ending_in_dwpts_supported = 5; + in.pnf_phy_rel13.phy[0].laa_starting_in_second_slot_supported = 6; + in.pnf_phy_rel13.phy[0].beamforming_supported = 7; + in.pnf_phy_rel13.phy[0].csi_rs_enhancement_supported = 8; + in.pnf_phy_rel13.phy[0].drms_enhancement_supported = 9; + in.pnf_phy_rel13.phy[0].srs_enhancement_supported = 10; +*/ + test_param_request_called++; + + nfapi_pnf_pnf_param_resp(config, &resp); + return 0; +} + +int test_config_request_called = 0; +int test_pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req) +{ + printf("test_pnf_config_request called.... ;-)\n"); + + CU_ASSERT_EQUAL(req->pnf_phy_rf_config.tl.tag, NFAPI_PNF_PHY_RF_TAG); + + if(config->user_data != 0) + { + pnf_info_t* pnf = (pnf_info_t*)(config->user_data); + int i = 0; + for(i = 0; i < req->pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + pnf->phys[i].enabled = 1; + pnf->phys[i].phy_id = req->pnf_phy_rf_config.phy_rf_config[i].phy_id; + printf("test_pnf_config_request creating phy %d\n", pnf->phys[i].phy_id); + + } + } + + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_config_resp(config, &resp); + + test_config_request_called++; + return 0; +} +int test_pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req) +{ + printf("test_pnf_start_request called.... ;-)\n"); + + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_start_resp(config, &resp); + return 0; +} +int test_pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req) +{ + printf("test_pnf_stop_request called.... ;-)\n"); + + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_stop_resp(config, &resp); + return 0; +} +int test_param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req) +{ + printf("test_param_request called.... ;-)\n"); + + nfapi_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PARAM_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + + if(config->user_data != 0) + { + phy_info_t* phy_info = find_phy_info((pnf_info_t*)(config->user_data), req->header.phy_id); + + resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + resp.nfapi_config.p7_pnf_port.value = phy_info->pnf_p7_port; + resp.num_tlv++; + + resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + struct sockaddr_in pnf_p7_sockaddr; + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(phy_info->pnf_p7_addr); + memcpy(&(resp.nfapi_config.p7_pnf_address_ipv4.address[0]), &pnf_p7_sockaddr.sin_addr.s_addr, 4); + resp.num_tlv++; + } + + + + + nfapi_pnf_param_resp(config, &resp); + return 0; +} +int test_config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req) +{ + printf("test_config_request called.... ;-)\n"); + + if(config->user_data != 0) + { + phy_info_t* phy_info = find_phy_info((pnf_info_t*)(config->user_data), req->header.phy_id); + + if(req->nfapi_config.p7_vnf_port.tl.tag == NFAPI_NFAPI_P7_VNF_PORT_TAG) + { + phy_info->vnf_p7_port = req->nfapi_config.p7_vnf_port.value; + printf("vnf_p7_port %d\n", phy_info->vnf_p7_port); + } + + if(req->nfapi_config.p7_vnf_address_ipv4.tl.tag == NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG) + { + struct sockaddr_in addr; + memcpy(&addr.sin_addr.s_addr, req->nfapi_config.p7_vnf_address_ipv4.address, 4); + char* ip = inet_ntoa(addr.sin_addr); + phy_info->vnf_p7_addr = ip; + printf("vnf_p7_addr %s\n", phy_info->vnf_p7_addr); + } + + + } + + nfapi_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_config_resp(config, &resp); + return 0; +} +int test_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req) +{ + printf("test_dl_config_req called.... ;-)\n"); + return 0; +} + +int test_ul_config_req(nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req) +{ + printf("test_ul_config_req called.... ;-)\n"); + return 0; +} +int test_hi_dci0_req(nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req) +{ + printf("test_hi_dci0_req called.... ;-)\n"); + return 0; +} +int test_tx_req(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req) +{ + printf("test_tx_req called.... ;-)\n"); + return 0; +} +int test_lbt_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req) +{ + printf("test_lbt_dl_req called.... ;-)\n"); + return 0; +} +int test_start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req) +{ + printf("test_start_request called.... ;-)\n"); + + + if(config->user_data != 0) + { + phy_info_t* phy_info = find_phy_info((pnf_info_t*)(config->user_data), req->header.phy_id); + + phy_info->config = nfapi_pnf_p7_config_create(); + phy_info->config->local_p7_port = phy_info->pnf_p7_port; + + phy_info->config->remote_p7_port = phy_info->vnf_p7_port; + phy_info->config->remote_p7_addr = phy_info->vnf_p7_addr; + + phy_info->config->dl_config_req = &test_dl_config_req; + phy_info->config->ul_config_req = &test_ul_config_req; + phy_info->config->hi_dci0_req = &test_hi_dci0_req; + phy_info->config->tx_req = &test_tx_req; + phy_info->config->lbt_dl_config_req = &test_lbt_dl_config_req; + + //phy_info->config->subframe_buffer_size = 8; + //phy_info->config->timing_info_mode_periodic = 1; + //phy_info->config->timing_info_period = 32; + //phy_info->config->timing_info_mode_aperiodic = 1; + + phy_info->config->segment_size = 1400; + phy_info->config->checksum_enabled = 0; + + + pthread_create(&phy_info->thread, NULL, &pnf_test_start_p7_thread, phy_info->config); + } + + nfapi_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_start_resp(config, &resp); + return 0; +} +int test_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req) +{ + printf("test_stop_request called.... ;-)\n"); + + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_stop_resp(config, &resp); + return 0; +} + +int send_p5_message(int p5Sock, nfapi_p4_p5_message_header_t* msg, unsigned msg_size, struct sockaddr* addr, socklen_t addr_size) +{ + char buffer[256]; + int encoded_size = nfapi_p5_message_pack(msg, msg_size, buffer, sizeof(buffer), 0); + int result = sendto(p5Sock, buffer, encoded_size, 0, addr, addr_size); + return result; +} + +int send_p7_message(int p7Sock, nfapi_p7_message_header_t* msg, unsigned msg_size, struct sockaddr_in* addr, socklen_t addr_size) +{ + char buffer[256]; + int encoded_size = nfapi_p7_message_pack(msg, buffer, sizeof(buffer), 0); + int result = sendto(p7Sock, buffer, encoded_size, 0, (struct sockaddr*)addr, addr_size); + + printf("send_p7_message result %d\n", result); + return result; +} +int send_p7_segmented_message(int p7Sock, nfapi_p7_message_header_t* msg, unsigned msg_size, struct sockaddr_in* addr, socklen_t addr_size) +{ + char buffer[1024 * 10]; + int encoded_size = nfapi_p7_message_pack(msg, buffer, sizeof(buffer), 0); + + uint16_t segment_size = 256; + + if(encoded_size < segment_size) + { + int result = sendto(p7Sock, buffer, encoded_size, 0, (struct sockaddr*)addr, addr_size); + return result; + } + else + { + // printf("Segmenting p7 message %d\n", encoded_size); + + uint8_t segment_count = 0; + uint8_t buffer2[segment_size]; + uint32_t offset = 0; + uint16_t msg_size; + //uint8_t m = 1; + + do{ + + if(segment_count == 0) + { + msg_size = segment_size; + memcpy(&buffer2[0], &buffer[0], msg_size); + // M = 1 + buffer2[6] = (1 << 7) | (segment_count & 0x7F); + + offset = msg_size; + } + else + { + memcpy(&buffer2[0], &buffer[0], NFAPI_P7_HEADER_LENGTH); + + if(encoded_size - offset > segment_size) + { + // M = 1 + buffer2[6] = (1 << 7) | (segment_count & 0x7F); + msg_size = segment_size; + } + else + { + // M = 0 + buffer2[6] = (0 << 7) | (segment_count & 0x7F); + msg_size = encoded_size - offset + NFAPI_P7_HEADER_LENGTH; + } + + + memcpy(&buffer2[NFAPI_P7_HEADER_LENGTH], &buffer[offset], msg_size - NFAPI_P7_HEADER_LENGTH); + + offset += msg_size - NFAPI_P7_HEADER_LENGTH; + } + + uint8_t* p = &buffer2[4]; + push16(msg_size, &p, &buffer2[segment_size]); + + //printf("Segmenting p7 message %d %di %d\n", segment_count, msg_size, offset); + /*int result = */sendto(p7Sock, buffer2, msg_size, 0, (struct sockaddr*)addr, addr_size); + + segment_count++; + + }while(offset < encoded_size); + + } + + return 0; +} +int send_p7_segmented_message_outoforder(int p7Sock, nfapi_p7_message_header_t* msg, unsigned msg_size, struct sockaddr_in* addr, socklen_t addr_size) +{ + char buffer[1024 * 10]; + int encoded_size = nfapi_p7_message_pack(msg, buffer, sizeof(buffer), 0); + + uint16_t segment_size = 256; + + if(encoded_size < segment_size) + { + int result = sendto(p7Sock, buffer, encoded_size, 0, (struct sockaddr*)addr, addr_size); + return result; + } + else + { + // printf("Segmenting p7 message %d\n", encoded_size); + + uint8_t segment_count = 0; + uint8_t buffer2[128][segment_size]; + uint32_t offset = 0; + uint16_t msg_size[128]; + uint8_t i = 0; + + do{ + + if(segment_count == 0) + { + msg_size[i] = segment_size; + memcpy(&buffer2[i][0], &buffer[0], msg_size[i]); + // M = 1 + buffer2[i][6] = (1 << 7) | (segment_count & 0x7F); + + offset = msg_size[i]; + } + else + { + memcpy(&buffer2[i][0], &buffer[0], NFAPI_P7_HEADER_LENGTH); + + if(encoded_size - offset > segment_size) + { + // M = 1 + buffer2[i][6] = (1 << 7) | (segment_count & 0x7F); + msg_size[i] = segment_size; + } + else + { + // M = 0 + buffer2[i][6] = (0 << 7) | (segment_count & 0x7F); + msg_size[i] = encoded_size - offset + NFAPI_P7_HEADER_LENGTH; + } + + + memcpy(&buffer2[i][NFAPI_P7_HEADER_LENGTH], &buffer[offset], msg_size[i] - NFAPI_P7_HEADER_LENGTH); + + offset += msg_size[i] - NFAPI_P7_HEADER_LENGTH; + } + + uint8_t* p = &buffer2[i][4]; + push16(msg_size[i], &p, &buffer2[i][segment_size]); + + + segment_count++; + i++; + + }while(offset < encoded_size); + + // send all odd then send event + uint8_t e = 0; + uint8_t o = 1; + while(o <= i) + { + sendto(p7Sock, &buffer2[o][0], msg_size[o], 0, (struct sockaddr*)addr, addr_size); + o += 2; + } + while(e <= i) + { + sendto(p7Sock, &buffer2[e][0], msg_size[e], 0, (struct sockaddr*)addr, addr_size); + e += 2; + } + + } + + return 0; +} + +int get_p7_segmented_message(int p7Sock, nfapi_p7_message_header_t* msg, unsigned _msg_size, struct sockaddr_in* addr, socklen_t addr_size, uint8_t (buffer2)[][256], uint16_t msg_size[256], uint8_t i) +{ + char buffer[1024 * 10]; + int encoded_size = nfapi_p7_message_pack(msg, buffer, sizeof(buffer), 0); + + uint16_t segment_size = 256; + + printf("get_p7_segmented_message size %d\n", encoded_size); + + if(encoded_size < segment_size) + { + msg_size[i] = encoded_size; + memcpy(&buffer2[i][0], &buffer[0], msg_size[i]); + i++; + } + else + { + uint8_t segment_count = 0; + uint32_t offset = 0; + + do{ + + if(segment_count == 0) + { + msg_size[i] = segment_size; + memcpy(&buffer2[i][0], &buffer[0], msg_size[i]); + // M = 1 + (buffer2[i][6]) = (1 << 7) | (segment_count & 0x7F); + + offset = msg_size[i]; + } + else + { + memcpy(&buffer2[i][0], &buffer[0], NFAPI_P7_HEADER_LENGTH); + + if(encoded_size - offset > segment_size) + { + // M = 1 + (buffer2[i][6]) = (1 << 7) | (segment_count & 0x7F); + msg_size[i] = segment_size; + } + else + { + // M = 0 + (buffer2[i][6]) = (0 << 7) | (segment_count & 0x7F); + msg_size[i] = encoded_size - offset + NFAPI_P7_HEADER_LENGTH; + } + + + memcpy(&buffer2[i][NFAPI_P7_HEADER_LENGTH], &buffer[offset], msg_size[i] - NFAPI_P7_HEADER_LENGTH); + + offset += msg_size[i] - NFAPI_P7_HEADER_LENGTH; + } + + uint8_t* p = &buffer2[i][4]; + push16(msg_size[i], &p, &buffer2[i][segment_size]); + + + segment_count++; + i++; + + }while(offset < encoded_size); + + } + + return i; +} + + +int recv_p5_message(int p5Sock, nfapi_p4_p5_message_header_t* msg, unsigned msg_size) +{ + //struct sockaddr_in addr2; + //socklen_t addr2len; + char buffer2[1024]; + int result2 = recv(p5Sock, buffer2, sizeof(buffer2), 0); //, (struct sockaddr*)&addr2, &addr2len); + + if(result2 == -1) + { + printf("%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + else + { + /*int unpack_result =*/ nfapi_p5_message_unpack(buffer2, result2, msg, msg_size, 0); //, sizeof(resp)); + } + return 0; +} + +int recv_p7_message(int p7Sock, nfapi_p7_message_header_t* msg, unsigned msg_size) +{ + char buffer2[2560]; + int result2 = recvfrom(p7Sock, buffer2, sizeof(buffer2), 0, 0, 0); + + if(result2 == -1) + { + printf("%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + else + { + /*int unpack_result =*/ nfapi_p7_message_unpack(buffer2, result2, msg, msg_size, 0); //, sizeof(resp)); + } + return 0; +} + +int send_pnf_param_request(int p5Sock, struct sockaddr* addr, socklen_t addr_size) +{ + printf("%s\n", __FUNCTION__); + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + req.header.message_length = 0; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); + return 0; +} + +int receive_pnf_param_response(int p5Sock, uint8_t error_code) +{ + nfapi_pnf_param_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + printf("0x%x\n", resp.header.message_id); + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_PNF_PARAM_RESPONSE); + if(resp.header.message_id == NFAPI_PNF_PARAM_RESPONSE) + { + printf("decoded nfapi_pnf_param_response\n"); + CU_ASSERT_EQUAL(resp.error_code, error_code); + if(error_code == NFAPI_MSG_OK) + { + CU_ASSERT_EQUAL(resp.pnf_param_general.tl.tag, NFAPI_PNF_PARAM_GENERAL_TAG); + CU_ASSERT_EQUAL(resp.pnf_param_general.nfapi_sync_mode, 2); + CU_ASSERT_EQUAL(resp.pnf_param_general.location_mode, 1); + } + } + return 0; +} + +int send_pnf_config_request(int p5Sock, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_pnf_config_request_t req; + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + req.header.message_length = 0; + + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 1; + req.pnf_phy_rf_config.phy_rf_config[0].phy_id = 0; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); + return 0; +} + +int receive_pnf_config_response(int p5Sock) +{ + nfapi_pnf_config_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_PNF_CONFIG_RESPONSE); + if(resp.header.message_id == NFAPI_PNF_CONFIG_RESPONSE) + { + printf("decoded nfapi_pnf_config_response\n"); + } + return 0; +} + +void send_pnf_start_request(int p5Sock, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_pnf_start_request_t req; + req.header.message_id = NFAPI_PNF_START_REQUEST; + req.header.message_length = 0; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} + +void receive_pnf_start_response(int p5Sock) +{ + nfapi_pnf_start_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_PNF_START_RESPONSE); + if(resp.header.message_id == NFAPI_PNF_START_RESPONSE) + { + printf("decoded nfapi_pnf_start_response\n"); + } +} + +void send_pnf_stop_request(int p5Sock, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_pnf_stop_request_t req; + req.header.message_id = NFAPI_PNF_STOP_REQUEST; + req.header.message_length = 0; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} + +void receive_pnf_stop_response(int p5Sock) +{ + nfapi_pnf_stop_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_PNF_STOP_RESPONSE); + if(resp.header.message_id == NFAPI_PNF_STOP_RESPONSE) + { + printf("decoded nfapi_pnf_stop_response\n"); + } +} + +void send_param_request(int p5Sock, int phy_id, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = phy_id; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} +void receive_param_response(int p5Sock) +{ + nfapi_pnf_stop_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_PARAM_RESPONSE); + if(resp.header.message_id == NFAPI_PARAM_RESPONSE) + { + printf("decoded nfapi_param_response\n"); + } +} +void send_config_request(int p5Sock, int phy_id, struct sockaddr* addr, socklen_t addr_size, pnf_info_t* pnf_info) +{ + nfapi_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_CONFIG_REQUEST; + req.header.phy_id = phy_id; + + phy_info_t* phy_info = find_phy_info(pnf_info, phy_id); + + req.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req.nfapi_config.p7_vnf_port.value = phy_info->vnf_p7_port; + req.num_tlv++; + + //req.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + //req.num_tlv++; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} +void receive_config_response(int p5Sock) +{ + nfapi_pnf_stop_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_CONFIG_RESPONSE); + if(resp.header.message_id == NFAPI_CONFIG_RESPONSE) + { + printf("decoded nfapi_config_response\n"); + } +} +void send_start_request(int p5Sock, int phy_id, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = phy_id; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} +void receive_start_response(int p5Sock) +{ + nfapi_pnf_start_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_START_RESPONSE); + if(resp.header.message_id == NFAPI_START_RESPONSE) + { + printf("decoded nfapi_start_response\n"); + } +} +void send_stop_request(int p5Sock, int phy_id, struct sockaddr* addr, socklen_t addr_size) +{ + nfapi_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_STOP_REQUEST; + req.header.phy_id = phy_id; + + send_p5_message(p5Sock, &(req.header), sizeof(req), addr, addr_size); +} + +void receive_stop_response(int p5Sock) +{ + nfapi_pnf_stop_response_t resp; + recv_p5_message(p5Sock, &(resp.header), sizeof(resp)); + + CU_ASSERT_EQUAL(resp.header.message_id, NFAPI_STOP_RESPONSE); + if(resp.header.message_id == NFAPI_STOP_RESPONSE) + { + printf("decoded nfapi_stop_response\n"); + } +} + +void send_dl_node_sync(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_dl_node_sync_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_DL_NODE_SYNC; + req.header.phy_id = phy_id; + req.t1 = 1977; + req.delta_sfn_sf = 5000; + + send_p7_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); +} +void receive_ul_node_sync(int p7Sock) +{ + nfapi_ul_node_sync_t sync; + recv_p7_message(p7Sock, &(sync.header), sizeof(sync)); + + CU_ASSERT_EQUAL(sync.header.message_id, NFAPI_UL_NODE_SYNC); + if(sync.header.message_id == NFAPI_UL_NODE_SYNC) + { + printf("decoded nfapi_ul_node_sync t1:%d t2:%d t3:%d\n", + sync.t1, sync.t2, sync.t3); + } +} + +void receive_timing_info(int p7Sock) +{ + nfapi_timing_info_t timing_info; + recv_p7_message(p7Sock, &(timing_info.header), sizeof(timing_info)); + + CU_ASSERT_EQUAL(timing_info.header.message_id, NFAPI_TIMING_INFO); + if(timing_info.header.message_id == NFAPI_TIMING_INFO) + { + printf("decoded nfapi_timing_info\n"); + } + else + { + printf("decoded ?? 0x%x\n", timing_info.header.message_id); + } +} +void send_dl_config_req(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_dl_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + + send_p7_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); +} +void send_ul_config_req(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_ul_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + + send_p7_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); +} +void send_hi_dci0_req(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_hi_dci0_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_HI_DCI0_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + + send_p7_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); +} +void send_tx_req(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_tx_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_TX_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + send_p7_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); +} + +void send_tx_req_1(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_tx_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_TX_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + req.tx_request_body.number_of_pdus = 8; + req.tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)(malloc(sizeof(nfapi_tx_request_t) * 8)); + uint8_t i = 0; + uint8_t test_pdu[1200]; + + for(i = 0; i < 8; i++) + { + req.tx_request_body.tx_pdu_list[i].pdu_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].pdu_index = i; + req.tx_request_body.tx_pdu_list[i].num_segments =1; + req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (void*)&test_pdu; + } + + send_p7_segmented_message(p7Sock, &(req.header), sizeof(req), addr, addr_size); + + free(req.tx_request_body.tx_pdu_list); + +} + +void send_tx_req_2(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + nfapi_tx_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_TX_REQUEST; + req.header.phy_id = phy_id; + req.sfn_sf = sfn_sf; + req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + req.tx_request_body.number_of_pdus = 8; + req.tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)(malloc(sizeof(nfapi_tx_request_t) * 8)); + uint8_t i = 0; + uint8_t test_pdu[1200]; + + for(i = 0; i < 8; i++) + { + req.tx_request_body.tx_pdu_list[i].pdu_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].pdu_index = i; + req.tx_request_body.tx_pdu_list[i].num_segments =1; + req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (void*)&test_pdu; + } + + send_p7_segmented_message_outoforder(p7Sock, &(req.header), sizeof(req), addr, addr_size); + + free(req.tx_request_body.tx_pdu_list); + +} +void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size, uint16_t sfn_sf) +{ + + uint8_t buffer[256][256]; + uint16_t msg_size[256]; + uint16_t count = 0; + + { + nfapi_dl_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + req.header.phy_id = phy_id; + req.header.m_segment_sequence = 34; + req.sfn_sf = sfn_sf; + req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + req.dl_config_request_body.number_pdu = 8; + req.dl_config_request_body.dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)malloc(sizeof(nfapi_dl_config_request_pdu_t) * 8); + + uint8_t i = 0; + for(i = 0; i < 8; i++) + { + nfapi_dl_config_request_pdu_t* pdu = &(req.dl_config_request_body.dl_config_pdu_list[i]); + pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + } + + + count = get_p7_segmented_message(p7Sock, &(req.header), sizeof(req), addr, addr_size, buffer, msg_size, count); + } + + { + nfapi_ul_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + req.header.phy_id = phy_id; + req.header.m_segment_sequence = 35; + req.sfn_sf = sfn_sf; + + count = get_p7_segmented_message(p7Sock, &(req.header), sizeof(req), addr, addr_size, buffer, msg_size, count); + } + + { + nfapi_hi_dci0_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_HI_DCI0_REQUEST; + req.header.phy_id = phy_id; + req.header.m_segment_sequence = 36; + req.sfn_sf = sfn_sf; + count = get_p7_segmented_message(p7Sock, &(req.header), sizeof(req), addr, addr_size, buffer, msg_size, count); + } + + { + nfapi_tx_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_TX_REQUEST; + req.header.phy_id = phy_id; + req.header.m_segment_sequence = 37; + req.sfn_sf = sfn_sf; + req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + req.tx_request_body.number_of_pdus = 8; + req.tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)(malloc(sizeof(nfapi_tx_request_t) * 8)); + uint8_t i = 0; + uint8_t test_pdu[1200]; + + for(i = 0; i < 8; i++) + { + req.tx_request_body.tx_pdu_list[i].pdu_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].pdu_index = i; + req.tx_request_body.tx_pdu_list[i].num_segments =1; + req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = sizeof(test_pdu); + req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (void*)&test_pdu; + } + + count = get_p7_segmented_message(p7Sock, &(req.header), sizeof(req), addr, addr_size, buffer, msg_size, count); + } + + // send all odd then send event + uint8_t e = 0; + uint8_t o = 1; + while(o <= count) + { + if(msg_size[o] == 0) + printf("**** Sending a zero length msg %d\n", o); + sendto(p7Sock, &buffer[o][0], msg_size[o], 0, (struct sockaddr*)addr, addr_size); + o += 2; + } + while(e <= count) + { + if(msg_size[e] == 0) + printf("**** Sending a zero length msg %d\n", e); + + sendto(p7Sock, &buffer[e][0], msg_size[e], 0, (struct sockaddr*)addr, addr_size); + e += 2; + } + //free(req.tx_request_body.tx_pdu_list); +} + +void send_subframe_indication(phy_info_t* phy_info) +{ + nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf); +} + +void send_harq_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_harq_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_HARQ_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_harq_ind((phy_info->config), &ind); +} +void recieve_harq_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_harq_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_HARQ_INDICATION); + if(ind.header.message_id == NFAPI_HARQ_INDICATION) + { + printf("decoded nfapi_harq_indication\n"); + } + else + { + printf("decoded ?? 0x%x\n", ind.header.message_id); + } +} + +void send_crc_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_crc_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_CRC_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_crc_ind((phy_info->config), &ind); + +} +void recieve_crc_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_crc_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_CRC_INDICATION); + if(ind.header.message_id == NFAPI_CRC_INDICATION) + { + printf("decoded nfapi_crc_indication\n"); + } +} + +void send_rx_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_rx_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RX_ULSCH_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_rx_ind((phy_info->config), &ind); +} +void recieve_rx_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_rx_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_RX_ULSCH_INDICATION); + if(ind.header.message_id == NFAPI_RX_ULSCH_INDICATION) + { + printf("decoded nfapi_rx_indication\n"); + } +} + +void send_rach_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_rach_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RACH_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_rach_ind((phy_info->config), &ind); +} +void recieve_rach_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_rach_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_RACH_INDICATION); + if(ind.header.message_id == NFAPI_RACH_INDICATION) + { + printf("decoded nfapi_rach_indication\n"); + } +} + +void send_srs_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_srs_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SRS_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_srs_ind((phy_info->config), &ind); +} +void recieve_srs_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_srs_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_SRS_INDICATION); + if(ind.header.message_id == NFAPI_SRS_INDICATION) + { + printf("decoded nfapi_srs_indication\n"); + } +} + +void send_sr_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_sr_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RX_SR_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_sr_ind((phy_info->config), &ind); +} +void recieve_sr_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_sr_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_RX_SR_INDICATION); + if(ind.header.message_id == NFAPI_RX_SR_INDICATION) + { + printf("decoded nfapi_sr_indication\n"); + } +} + +void send_cqi_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_cqi_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RX_CQI_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_cqi_ind((phy_info->config), &ind); +} +void recieve_cqi_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_cqi_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_RX_CQI_INDICATION); + if(ind.header.message_id == NFAPI_RX_CQI_INDICATION) + { + printf("decoded nfapi_cqi_indication\n"); + } +} + +void send_lbt_dl_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_lbt_dl_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_LBT_DL_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_lbt_dl_ind((phy_info->config), &ind); +} +void recieve_lbt_dl_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_lbt_dl_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_LBT_DL_INDICATION); + if(ind.header.message_id == NFAPI_LBT_DL_INDICATION) + { + printf("decoded nfapi_lbt_dl_indication\n"); + } +} + +void send_nb_harq_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_nb_harq_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_NB_HARQ_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_nb_harq_ind((phy_info->config), &ind); +} +void recieve_nb_harq_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_nb_harq_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_NB_HARQ_INDICATION); + if(ind.header.message_id == NFAPI_NB_HARQ_INDICATION) + { + printf("decoded nfapi_nb_harq_indication\n"); + } +} + +void send_nrach_ind(phy_info_t* phy_info, uint16_t sfn_sf) +{ + nfapi_nrach_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_NRACH_INDICATION; + ind.header.phy_id = phy_info->phy_id; + ind.sfn_sf = sfn_sf; + + nfapi_pnf_p7_nrach_ind((phy_info->config), &ind); +} +void recieve_nrach_ind(int p7Sock, int phy_id, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_nrach_indication_t ind; + recv_p7_message(p7Sock, &(ind.header), sizeof(ind)); + + CU_ASSERT_EQUAL(ind.header.message_id, NFAPI_NRACH_INDICATION); + if(ind.header.message_id == NFAPI_NRACH_INDICATION) + { + printf("decoded nfapi_nrach_indication\n"); + } +} + +void pnf_test_start_connect(void) +{ + pnf_info_t pnf_info; + pnf_info.num_phys = 1; + pnf_info.phys[0].pnf_p7_port = 9345; + pnf_info.phys[0].pnf_p7_addr = "127.0.0.1"; + pnf_info.phys[0].vnf_p7_port = 8875; + pnf_info.phys[0].vnf_p7_addr = "127.0.0.1"; + + char* vnf_addr = "127.0.0.1"; + int vnf_port = 6699; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + printf("p5ListenSock %d %d\n", p5ListenSock, errno); + listen(p5ListenSock, 2); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + config->pnf_start_req = &test_pnf_start_request; + config->pnf_stop_req = &test_pnf_stop_request; + config->param_req = &test_param_request; + config->config_req = &test_config_request; + config->start_req = &test_start_request; + config->stop_req = &test_stop_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr);; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("p5 connection accepted %d %d\n", p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_start_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_start_response(p5Sock); + + send_param_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_param_response(p5Sock); + + + send_config_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize, &pnf_info); + receive_config_response(p5Sock); + + send_start_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_start_response(p5Sock); + + sleep(2); + + int p7Sock = socket(AF_INET, SOCK_DGRAM, 0); + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(pnf_info.phys[0].vnf_p7_port); + addr.sin_addr.s_addr = INADDR_ANY; + + bind(p7Sock, (struct sockaddr*)&addr, sizeof(addr)); + } + + printf("Sending p7 messages too %s:%d\n", pnf_info.phys[0].pnf_p7_addr, pnf_info.phys[0].pnf_p7_port); + + struct sockaddr_in p7_addr; + p7_addr.sin_family = AF_INET; + p7_addr.sin_port = htons(pnf_info.phys[0].pnf_p7_port); + p7_addr.sin_addr.s_addr = inet_addr(pnf_info.phys[0].pnf_p7_addr); + socklen_t p7_addrSize = sizeof(p7_addr); + + send_dl_node_sync(p7Sock, 0, &p7_addr, p7_addrSize); + receive_ul_node_sync(p7Sock); + + +#define SFNSF(_sfn, _sf) ((_sfn << 4) + _sf) + + uint16_t sfn_sf = SFNSF(500, 3); // sfn:500 sf:3 + pnf_info.phys[0].sfn_sf = sfn_sf; + send_subframe_indication(&(pnf_info.phys[0])); + + // should generate dummy messages + + usleep(500); + + sfn_sf = SFNSF(500, 4); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_ul_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_hi_dci0_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_tx_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + + + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + // should send the cached messages + + send_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_crc_ind(&pnf_info.phys[0], sfn_sf); + recieve_crc_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rx_ind(&pnf_info.phys[0], sfn_sf); + recieve_rx_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rach_ind(&pnf_info.phys[0], sfn_sf); + recieve_rach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_srs_ind(&pnf_info.phys[0], sfn_sf); + recieve_srs_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_sr_ind(&pnf_info.phys[0], sfn_sf); + recieve_sr_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_cqi_ind(&pnf_info.phys[0], sfn_sf); + recieve_cqi_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_lbt_dl_ind(&pnf_info.phys[0], sfn_sf); + recieve_lbt_dl_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_nb_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_nb_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_nrach_ind(&pnf_info.phys[0], sfn_sf); + recieve_nrach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + + // send out of window dl_config, should expect the timing info + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, SFNSF(600, 0)); + + sfn_sf = SFNSF(500, 5); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + receive_timing_info(p7Sock); + + send_stop_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_stop_response(p5Sock); + + + + send_pnf_stop_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_stop_response(p5Sock); + + nfapi_pnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + //CU_ASSERT_NOT_EQUAL(*result, -1); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 1); + + close(p5Sock); + close(p5ListenSock); + +} +void pnf_test_start_connect_ipv6(void) +{ + pnf_info_t pnf_info; + pnf_info.num_phys = 1; + pnf_info.phys[0].pnf_p7_port = 9345; + pnf_info.phys[0].pnf_p7_addr = "::1"; + pnf_info.phys[0].vnf_p7_port = 8875; + pnf_info.phys[0].vnf_p7_addr = "::1"; + + char* vnf_addr = "::1"; + int vnf_port = 6698; + + int p5ListenSock = create_p5_ipv6_listen_socket(vnf_addr, vnf_port); + printf("p5ListenSock ipv6 %d %d\n", p5ListenSock, errno); + int listen_result = listen(p5ListenSock, 2); + printf("Listen result %d\n", listen_result); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + config->pnf_start_req = &test_pnf_start_request; + config->pnf_stop_req = &test_pnf_stop_request; + config->param_req = &test_param_request; + config->config_req = &test_config_request; + config->start_req = &test_start_request; + config->stop_req = &test_stop_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + struct sockaddr_in6 addr; + socklen_t addrSize = sizeof(addr);; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("p5 connection accepted %d %d\n", p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_start_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_start_response(p5Sock); + + send_param_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_param_response(p5Sock); +} + +void pnf_test_state_pnf_config_invalid_state() +{ + char* vnf_addr = "127.0.0.1"; + int vnf_port = 4546; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + listen(p5ListenSock, 2); + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr); + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("%s p5Sock %d errno %d\n", __FUNCTION__, p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_INVALID_STATE); + + nfapi_pnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL(result, 0); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 1); + + close(p5Sock); + close(p5ListenSock); + +} + +void pnf_test_state_pnf_param_invalid_state() +{ + pnf_info_t pnf_info; + + char* vnf_addr = "127.0.0.1"; + int vnf_port = 4547; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + listen(p5ListenSock, 2); + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr); + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + nfapi_pnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL(result, 0); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 2); + + close(p5Sock); + close(p5ListenSock); + +} +void pnf_test_p7_segmentation_test_1(void) +{ + pnf_info_t pnf_info; + pnf_info.num_phys = 1; + pnf_info.phys[0].pnf_p7_port = 9348; + pnf_info.phys[0].pnf_p7_addr = "127.0.0.1"; + pnf_info.phys[0].vnf_p7_port = 8878; + pnf_info.phys[0].vnf_p7_addr = "127.0.0.1"; + + char* vnf_addr = "127.0.0.1"; + int vnf_port = 6699; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + printf("p5ListenSock %d %d\n", p5ListenSock, errno); + listen(p5ListenSock, 2); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + config->pnf_start_req = &test_pnf_start_request; + config->pnf_stop_req = &test_pnf_stop_request; + config->param_req = &test_param_request; + config->config_req = &test_config_request; + config->start_req = &test_start_request; + config->stop_req = &test_stop_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr);; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("p5 connection accepted %d %d\n", p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_start_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_start_response(p5Sock); + + send_param_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_param_response(p5Sock); + + + send_config_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize, &pnf_info); + receive_config_response(p5Sock); + + send_start_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_start_response(p5Sock); + + sleep(2); + + int p7Sock = socket(AF_INET, SOCK_DGRAM, 0); + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(pnf_info.phys[0].vnf_p7_port); + addr.sin_addr.s_addr = INADDR_ANY; + + bind(p7Sock, (struct sockaddr*)&addr, sizeof(addr)); + } + + printf("Sending p7 messages too %s:%d\n", pnf_info.phys[0].pnf_p7_addr, pnf_info.phys[0].pnf_p7_port); + + struct sockaddr_in p7_addr; + p7_addr.sin_family = AF_INET; + p7_addr.sin_port = htons(pnf_info.phys[0].pnf_p7_port); + p7_addr.sin_addr.s_addr = inet_addr(pnf_info.phys[0].pnf_p7_addr); + socklen_t p7_addrSize = sizeof(p7_addr); + + send_dl_node_sync(p7Sock, 0, &p7_addr, p7_addrSize); + receive_ul_node_sync(p7Sock); + + +#define SFNSF(_sfn, _sf) ((_sfn << 4) + _sf) + + uint16_t sfn_sf = SFNSF(500, 3); // sfn:500 sf:3 + pnf_info.phys[0].sfn_sf = sfn_sf; + send_subframe_indication(&(pnf_info.phys[0])); + + // should generate dummy messages + + usleep(500); + + sfn_sf = SFNSF(500, 4); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_ul_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_hi_dci0_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_tx_req_1(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + + + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + // should send the cached messages + + send_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_crc_ind(&pnf_info.phys[0], sfn_sf); + recieve_crc_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rx_ind(&pnf_info.phys[0], sfn_sf); + recieve_rx_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rach_ind(&pnf_info.phys[0], sfn_sf); + recieve_rach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_srs_ind(&pnf_info.phys[0], sfn_sf); + recieve_srs_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_sr_ind(&pnf_info.phys[0], sfn_sf); + recieve_sr_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_cqi_ind(&pnf_info.phys[0], sfn_sf); + recieve_cqi_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_lbt_dl_ind(&pnf_info.phys[0], sfn_sf); + recieve_lbt_dl_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_nb_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_nb_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_nrach_ind(&pnf_info.phys[0], sfn_sf); + recieve_nrach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + + // send out of window dl_config, should expect the timing info + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, SFNSF(600, 0)); + + sfn_sf = SFNSF(500, 5); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + receive_timing_info(p7Sock); + + nfapi_pnf_p7_stop(pnf_info.phys[0].config); + int* result; + pthread_join(pnf_info.phys[0].thread, (void**)&result); + close(p7Sock); + + send_stop_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_stop_response(p5Sock); + + send_pnf_stop_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_stop_response(p5Sock); + + nfapi_pnf_stop(config); + + pthread_join(thread, (void**)&result); + //CU_ASSERT_NOT_EQUAL(*result, -1); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 1); + + close(p5Sock); + close(p5ListenSock); + +} +void pnf_test_p7_segmentation_test_2(void) +{ + pnf_info_t pnf_info; + pnf_info.num_phys = 1; + pnf_info.phys[0].pnf_p7_port = 9348; + pnf_info.phys[0].pnf_p7_addr = "127.0.0.1"; + pnf_info.phys[0].vnf_p7_port = 8878; + pnf_info.phys[0].vnf_p7_addr = "127.0.0.1"; + + char* vnf_addr = "127.0.0.1"; + int vnf_port = 6699; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + printf("p5ListenSock %d %d\n", p5ListenSock, errno); + listen(p5ListenSock, 2); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + config->pnf_start_req = &test_pnf_start_request; + config->pnf_stop_req = &test_pnf_stop_request; + config->param_req = &test_param_request; + config->config_req = &test_config_request; + config->start_req = &test_start_request; + config->stop_req = &test_stop_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr);; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("p5 connection accepted %d %d\n", p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_start_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_start_response(p5Sock); + + send_param_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_param_response(p5Sock); + + + send_config_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize, &pnf_info); + receive_config_response(p5Sock); + + send_start_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_start_response(p5Sock); + + sleep(2); + + int p7Sock = socket(AF_INET, SOCK_DGRAM, 0); + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(pnf_info.phys[0].vnf_p7_port); + addr.sin_addr.s_addr = INADDR_ANY; + + bind(p7Sock, (struct sockaddr*)&addr, sizeof(addr)); + } + + printf("Sending p7 messages too %s:%d\n", pnf_info.phys[0].pnf_p7_addr, pnf_info.phys[0].pnf_p7_port); + + struct sockaddr_in p7_addr; + p7_addr.sin_family = AF_INET; + p7_addr.sin_port = htons(pnf_info.phys[0].pnf_p7_port); + p7_addr.sin_addr.s_addr = inet_addr(pnf_info.phys[0].pnf_p7_addr); + socklen_t p7_addrSize = sizeof(p7_addr); + + send_dl_node_sync(p7Sock, 0, &p7_addr, p7_addrSize); + receive_ul_node_sync(p7Sock); + + +#define SFNSF(_sfn, _sf) ((_sfn << 4) + _sf) + + uint16_t sfn_sf = SFNSF(500, 3); // sfn:500 sf:3 + pnf_info.phys[0].sfn_sf = sfn_sf; + send_subframe_indication(&(pnf_info.phys[0])); + + // should generate dummy messages + + usleep(500); + + sfn_sf = SFNSF(500, 4); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_ul_config_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_hi_dci0_req(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + send_tx_req_2(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + + + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + // should send the cached messages + + send_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_crc_ind(&pnf_info.phys[0], sfn_sf); + recieve_crc_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rx_ind(&pnf_info.phys[0], sfn_sf); + recieve_rx_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rach_ind(&pnf_info.phys[0], sfn_sf); + recieve_rach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_srs_ind(&pnf_info.phys[0], sfn_sf); + recieve_srs_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_sr_ind(&pnf_info.phys[0], sfn_sf); + recieve_sr_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_cqi_ind(&pnf_info.phys[0], sfn_sf); + recieve_cqi_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_lbt_dl_ind(&pnf_info.phys[0], sfn_sf); + recieve_lbt_dl_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + // send out of window dl_config, should expect the timing info + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, SFNSF(600, 0)); + + sfn_sf = SFNSF(500, 5); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + receive_timing_info(p7Sock); + + send_stop_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_stop_response(p5Sock); + + nfapi_pnf_p7_stop(pnf_info.phys[0].config); + int* result; + pthread_join(pnf_info.phys[0].thread, (void**)&result); + close(p7Sock); + + + send_pnf_stop_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_stop_response(p5Sock); + + nfapi_pnf_stop(config); + + pthread_join(thread, (void**)&result); + //CU_ASSERT_NOT_EQUAL(*result, -1); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 1); + + close(p5Sock); + close(p5ListenSock); + +} +void pnf_test_p7_segmentation_test_3(void) +{ + pnf_info_t pnf_info; + pnf_info.num_phys = 1; + pnf_info.phys[0].pnf_p7_port = 9348; + pnf_info.phys[0].pnf_p7_addr = "127.0.0.1"; + pnf_info.phys[0].vnf_p7_port = 8878; + pnf_info.phys[0].vnf_p7_addr = "127.0.0.1"; + + char* vnf_addr = "127.0.0.1"; + int vnf_port = 6699; + + int p5ListenSock = create_p5_listen_socket(vnf_addr, vnf_port); + printf("p5ListenSock %d %d\n", p5ListenSock, errno); + listen(p5ListenSock, 2); + + test_param_request_called = 0; + test_config_request_called = 0; + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_addr; + config->vnf_p5_port = vnf_port; + config->pnf_param_req = &test_pnf_param_request; + config->pnf_config_req = &test_pnf_config_request; + config->pnf_start_req = &test_pnf_start_request; + config->pnf_stop_req = &test_pnf_stop_request; + config->param_req = &test_param_request; + config->config_req = &test_config_request; + config->start_req = &test_start_request; + config->stop_req = &test_stop_request; + + config->user_data = &pnf_info; + + pthread_t thread; + pthread_create(&thread, NULL, &pnf_test_start_thread, config); + + struct sockaddr_in addr; + socklen_t addrSize = sizeof(addr);; + int p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + printf("p5 connection accepted %d %d\n", p5Sock, errno); + + send_pnf_param_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_param_response(p5Sock, NFAPI_MSG_OK); + + send_pnf_config_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_config_response(p5Sock); + + send_pnf_start_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_start_response(p5Sock); + + send_param_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_param_response(p5Sock); + + + send_config_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize, &pnf_info); + receive_config_response(p5Sock); + + send_start_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_start_response(p5Sock); + + sleep(2); + + int p7Sock = socket(AF_INET, SOCK_DGRAM, 0); + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(pnf_info.phys[0].vnf_p7_port); + addr.sin_addr.s_addr = INADDR_ANY; + + bind(p7Sock, (struct sockaddr*)&addr, sizeof(addr)); + } + + printf("Sending p7 messages too %s:%d\n", pnf_info.phys[0].pnf_p7_addr, pnf_info.phys[0].pnf_p7_port); + + struct sockaddr_in p7_addr; + p7_addr.sin_family = AF_INET; + p7_addr.sin_port = htons(pnf_info.phys[0].pnf_p7_port); + p7_addr.sin_addr.s_addr = inet_addr(pnf_info.phys[0].pnf_p7_addr); + socklen_t p7_addrSize = sizeof(p7_addr); + + send_dl_node_sync(p7Sock, 0, &p7_addr, p7_addrSize); + receive_ul_node_sync(p7Sock); + + +#define SFNSF(_sfn, _sf) ((_sfn << 4) + _sf) + + uint16_t sfn_sf = SFNSF(500, 3); // sfn:500 sf:3 + pnf_info.phys[0].sfn_sf = sfn_sf; + send_subframe_indication(&(pnf_info.phys[0])); + + // should generate dummy messages + + usleep(500); + + sfn_sf = SFNSF(500, 4); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + + + send_dl_subframe_msgs_interleaved(p7Sock, 0, &p7_addr, p7_addrSize, sfn_sf); + + + usleep(500); + + send_subframe_indication(&(pnf_info.phys[0])); + // should send the cached messages + + send_harq_ind(&pnf_info.phys[0], sfn_sf); + recieve_harq_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_crc_ind(&pnf_info.phys[0], sfn_sf); + recieve_crc_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rx_ind(&pnf_info.phys[0], sfn_sf); + recieve_rx_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_rach_ind(&pnf_info.phys[0], sfn_sf); + recieve_rach_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_srs_ind(&pnf_info.phys[0], sfn_sf); + recieve_srs_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_sr_ind(&pnf_info.phys[0], sfn_sf); + recieve_sr_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_cqi_ind(&pnf_info.phys[0], sfn_sf); + recieve_cqi_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + send_lbt_dl_ind(&pnf_info.phys[0], sfn_sf); + recieve_lbt_dl_ind(p7Sock, 0, &p7_addr, p7_addrSize); + + // send out of window dl_config, should expect the timing info + printf("Sending late dl config req\n"); + send_dl_config_req(p7Sock, 0, &p7_addr, p7_addrSize, SFNSF(600, 0)); + + sfn_sf = SFNSF(500, 5); // sfn:500 sf:4 + pnf_info.phys[0].sfn_sf = sfn_sf; + sleep(2); + + printf("Sending subframe indication\n"); + send_subframe_indication(&(pnf_info.phys[0])); + printf("Waitning for timing info\n"); + receive_timing_info(p7Sock); + + printf("Sending stop request\n"); + send_stop_request(p5Sock, 0, (struct sockaddr*)&addr, addrSize); + receive_stop_response(p5Sock); + + printf("Waiting for P7 thread to stop\n"); + nfapi_pnf_p7_stop(pnf_info.phys[0].config); + int* result; + pthread_join(pnf_info.phys[0].thread, (void**)&result); + close(p7Sock); + + + send_pnf_stop_request(p5Sock, (struct sockaddr*)&addr, addrSize); + receive_pnf_stop_response(p5Sock); + + nfapi_pnf_stop(config); + + pthread_join(thread, (void**)&result); + //CU_ASSERT_NOT_EQUAL(*result, -1); + CU_ASSERT_EQUAL(test_param_request_called, 1); + CU_ASSERT_EQUAL(test_config_request_called, 1); + + close(p5Sock); + close(p5ListenSock); + +} + +/************* Test Runner Code goes here **************/ + +int main ( void ) +{ + CU_pSuite pSuite = NULL; + + /* initialize the CUnit test registry */ + if ( CUE_SUCCESS != CU_initialize_registry() ) + return CU_get_error(); + + /* add a suite to the registry */ + pSuite = CU_add_suite( "pnf_test_suite", init_suite, clean_suite ); + if ( NULL == pSuite ) { + CU_cleanup_registry(); + return CU_get_error(); + } + + /* add the tests to the suite */ + if ( (NULL == CU_add_test(pSuite, "pnf_test_start_no_config", pnf_test_start_no_config)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_no_ip", pnf_test_start_no_ip)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_invalid_ip", pnf_test_start_invalid_ip)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_no_connection", pnf_test_start_no_connection)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_connect", pnf_test_start_connect)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_pnf_config_invalid_state", pnf_test_state_pnf_config_invalid_state)) || + (NULL == CU_add_test(pSuite, "pnf_test_start_pnf_param_invalid_state", pnf_test_state_pnf_param_invalid_state)) || + (NULL == CU_add_test(pSuite, "pnf_test_p7_segmentation_test_1", pnf_test_p7_segmentation_test_1)) || + (NULL == CU_add_test(pSuite, "pnf_test_p7_segmentation_test_2", pnf_test_p7_segmentation_test_2)) || + (NULL == CU_add_test(pSuite, "pnf_test_p7_segmentation_test_3", pnf_test_p7_segmentation_test_3)) + ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + //(NULL == CU_add_test(pSuite, "pnf_test_start_connect_ipv6", pnf_test_start_connect_ipv6)) || + + // Run all tests using the basic interface + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_set_output_filename("pnf_unit_test_results.xml"); + CU_basic_run_tests(); + + CU_pSuite s = CU_get_registry()->pSuite; + int count = 0; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + count++; + t = t->pNext; + } + s = s->pNext; + } + + printf("%d..%d\n", 1, count); + + + + s = CU_get_registry()->pSuite; + count = 1; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + int pass = 1; + CU_FailureRecord* failures = CU_get_failure_list(); + while(failures) + { + if(strcmp(failures->pSuite->pName, s->pName) == 0 && + strcmp(failures->pTest->pName, t->pName) == 0) + { + pass = 0; + failures = 0; + } + else + { + failures = failures->pNext; + } + } + + if(pass) + printf("ok %d - %s:%s\n", count, s->pName, t->pName); + else + printf("not ok %d - %s:%s\n", count, s->pName, t->pName); + + count++; + t = t->pNext; + } + s = s->pNext; + } + + // Clean up registry and return + CU_cleanup_registry(); + return CU_get_error(); + +} diff --git a/nfapi/open-nFAPI/pnf_sim/Makefile.am b/nfapi/open-nFAPI/pnf_sim/Makefile.am new file mode 100644 index 0000000000..c8d9d8ddd4 --- /dev/null +++ b/nfapi/open-nFAPI/pnf_sim/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AUTOMAKE_OPTIONS=subdir-objects +AM_CPPFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -g +AM_CXXFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -std=c++11 $(BOOST_CPPFLAGS) -g +bin_PROGRAMS = pnfsim +pnfsim_SOURCES = src/main.cpp src/fapi_stub.cpp +LDADD= $(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/common/libnfapi_common.a $(top_builddir)/nfapi/libnfapi.a $(top_builddir)/sim_common/libnfapi_sim_common.a -L$(libdir) -lpthread -lrt -lsctp -lz diff --git a/nfapi/open-nFAPI/pnf_sim/inc/fapi_interface.h b/nfapi/open-nFAPI/pnf_sim/inc/fapi_interface.h new file mode 100644 index 0000000000..b1d44eab8b --- /dev/null +++ b/nfapi/open-nFAPI/pnf_sim/inc/fapi_interface.h @@ -0,0 +1,1800 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _FAPI_INTERFACE_H_ +#define _FAPI_INTERFACE_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; + +#define FAPI_PARAM_REQUEST 0x00 +#define FAPI_PARAM_RESPONSE 0x01 +#define FAPI_CONFIG_REQUEST 0x02 +#define FAPI_CONFIG_RESPONSE 0x03 +#define FAPI_START_REQUEST 0x04 +#define FAPI_STOP_REQUEST 0x05 +#define FAPI_STOP_INDICATION 0x06 +#define FAPI_UE_CONFIG_REQUEST 0x07 +#define FAPI_UE_CONFIG_RESPONSE 0x08 +#define FAPI_ERROR_INDICATION 0x09 +#define FAPI_UE_RELEASE_REQUEST 0x0A +#define FAPI_UE_RELEASE_RESPONSE 0x0B +#define FAPI_DL_CONFIG_REQUEST 0x80 +#define FAPI_UL_CONFIG_REQUEST 0x81 +#define FAPI_SUBFRAME_INDICATION 0x82 +#define FAPI_HI_DCI0_REQUEST 0x83 +#define FAPI_TX_REQUEST 0x84 +#define FAPI_HARQ_INDICATION 0x85 +#define FAPI_CRC_INDICATION 0x86 +#define FAPI_RX_ULSCH_INDICATION 0x87 +#define FAPI_RACH_INDICATION 0x88 +#define FAPI_SRS_INDICATION 0x89 +#define FAPI_RX_SR_INDICATION 0x8A +#define FAPI_RX_CQI_INDICATION 0x8B +#define FAPI_LBT_DL_CONFIG_REQUEST 0x8C +#define FAPI_LBT_DL_INDICATION 0x8D +#define FAPI_NB_HARQ_INDICATION 0x8E +#define FAPI_NRACH_INDICATION 0x8F + + + + +#define FAPI_SUBFRAME_DUPLEX_MODE_TAG 0x01 +#define FAPI_SUBFRAME_PCFICH_POWER_OFFSET_TAG 0x02 +#define FAPI_SUBFRAME_PB_TAG 0x03 +#define FAPI_SUBFRAME_DL_CYCLIC_PREFIX_TYPE_TAG 0x04 +#define FAPI_SUBFRAME_UL_CYCLIC_PREFIX_TYPE_TAG 0x05 +#define FAPI_RF_DL_CHANNEL_BANDWIDTH_TAG 0x0A +#define FAPI_RF_UL_CHANNEL_BANDWIDTH_TAG 0x0B +#define FAPI_RF_REFERENCE_SIGNAL_POWER_TAG 0x0C +#define FAPI_RF_TX_ANTENNA_PORTS_TAG 0x0D +#define FAPI_RF_RX_ANTENNA_PORTS_TAG 0x0E +#define FAPI_PHICH_RESOURCE_TAG 0x14 +#define FAPI_PHICH_DURATION_TAG 0x15 +#define FAPI_PHICH_POWER_OFFSET_TAG 0x16 +#define FAPI_SCH_PRIMARY_SYNC_SIGNAL_TAG 0x1E +#define FAPI_SCH_SECONDARY_SYNC_SIGNAL_TAG 0x1F +#define FAPI_SCH_PHYSICAL_CELL_ID_TAG 0x20 +#define FAPI_PRACH_CONFIGURATION_INDEX_TAG 0x28 +#define FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x29 +#define FAPI_PRACH_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG 0x2A +#define FAPI_PRACH_HIGH_SPEED_FLAG_TAG 0x2B +#define FAPI_PRACH_FREQUENCY_OFFSET_TAG 0x2C +#define FAPI_PUSCH_HOPPING_MODE_TAG 0x32 +#define FAPI_PUSCH_HOPPING_OFFSET_TAG 0x33 +#define FAPI_PUSCH_NUMBER_OF_SUBBANDS_TAG 0x34 +#define FAPI_PUCCH_DELTA_PUCCH_SHIFT_TAG 0x3C +#define FAPI_PUCCH_N_CQI_RB_TAG 0x3D +#define FAPI_PUCCH_N_AN_CS_TAG 0x3E +#define FAPI_PUCCH_N1_PUCCH_AN_TAG 0x3F +#define FAPI_SRS_BANDWIDTH_CONFIGURATION_TAG 0x46 +#define FAPI_SRS_MAX_UP_PTS_TAG 0x47 +#define FAPI_SRS_SUBFRAME_CONFIGURATION_TAG 0x48 +#define FAPI_SRS_ACK_NACK_SRS_SIMULTANEOUS_TX_TAG 0x49 +#define FAPI_UL_REF_SIG_UPLINK_RS_HOPPING_TAG 0x50 +#define FAPI_UL_REF_SIG_GROUP_ASSIGNMENT_TAG 0x51 +#define FAPI_UL_REF_SIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG 0x52 +#define FAPI_TDD_SUBFRAME_ASSIGNMENT_TAG 0x5A +#define FAPI_TDD_SPECIAL_SUBFRAME_PATTERNS_TAG 0x5B + +#define FAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG 0x64 +#define FAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG 0x65 +#define FAPI_LAA_CONFIG_PD_THRESHOLD_TAG 0x66 +#define FAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG 0x67 +#define FAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG 0x68 +#define FAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG 0x69 +#define FAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG 0x6A +#define FAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG 0x6B + +#define FAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLED_R13_TAG 0x78 +#define FAPI_EMTC_CONFIG_PRACH_CAT_M_ROOT_SEQUENCY_INDEX_TAG 0x79 +#define FAPI_EMTC_CONFIG_PRACH_CAT_M_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG 0x7A +#define FAPI_EMTC_CONFIG_PRACH_CAT_M_HIGH_SPEED_FLAG_TAG 0x7B +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG 0x7C +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG 0x7D +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG 0x7E +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0x7F +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG 0x80 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG 0x81 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG 0x82 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG 0x83 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG 0x84 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG 0x85 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0x86 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG 0x87 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG 0x88 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG 0x89 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG 0x8A +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG 0x8B +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG 0x8C +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0x8D +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG 0x8E +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG 0x8F +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG 0x90 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG 0x91 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG 0x92 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG 0x93 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0x94 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG 0x95 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG 0x96 +#define FAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG 0x97 +#define FAPI_EMTC_CONFIG_PRACH_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG 0x98 +#define FAPI_EMTC_CONFIG_PRACH_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG 0x99 + +#define FAPI_NB_IOT_OPERATING_MODE_TAG 0xA5 +#define FAPI_NB_IOT_ANCHOR_TAG 0xA6 +#define FAPI_NB_IOT_PRB_INDEX_TAG 0xA7 +#define FAPI_NB_IOT_CONTROL_REGION_SIZE_TAG 0xA8 +#define FAPI_NB_IOT_ASSUMED_CRS_APS_TAG 0xA9 +#define FAPI_NB_IOT_NPRACH_CONFIG_0_ENABLE_TAG 0xAA +#define FAPI_NB_IOT_NPRACH_CONFIG_0_SF_PERIODCITY_TAG 0xAB +#define FAPI_NB_IOT_NPRACH_CONFIG_0_START_TIME_TAG 0xAC +#define FAPI_NB_IOT_NPRACH_CONFIG_0_SUBCARRIER_OFFSET_TAG 0xAD +#define FAPI_NB_IOT_NPRACH_CONFIG_0_NUMBER_OF_SUBCARRIERS_TAG 0xAE +#define FAPI_NB_IOT_NPRACH_CONFIG_0_CP_LENGTH_TAG 0xAD +#define FAPI_NB_IOT_NPRACH_CONFIG_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0xB0 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_ENABLE_TAG 0xB1 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_SF_PERIODCITY_TAG 0xB2 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_START_TIME_TAG 0xB3 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_SUBCARRIER_OFFSET_TAG 0xB4 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_NUMBER_OF_SUBCARRIERS_TAG 0xB5 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_CP_LENGTH_TAG 0xB6 +#define FAPI_NB_IOT_NPRACH_CONFIG_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0xB7 +#define FAPI_NB_IOT_NPRACH_CONFIG_2_ENABLE_TAG 0xB8 +#define FAPI_NB_IOT_NPRACH_CONFIG_2_SF_PERIODCITY_TAG 0xB9 +#define FAPI_NB_IOT_NPRACH_CONFIG_2_START_TIME_TAG 0xBA +#define FAPI_NB_IOT_NPRACH_CONFIG_2_SUBCARRIER_OFFSET_TAG 0xBB +#define FAPI_NB_IOT_NPRACH_CONFIG_2_NUMBER_OF_SUBCARRIERS_TAG 0xBC +#define FAPI_NB_IOT_NPRACH_CONFIG_2_CP_LENGTH_TAG 0xBD +#define FAPI_NB_IOT_NPRACH_CONFIG_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG 0xBE + +#define FAPI_NB_IOT_THREE_TONE_BASE_SEQUENCE_TAG 0xBF +#define FAPI_NB_IOT_SIX_TONE_BASE_SEQUENCE_TAG 0xC0 +#define FAPI_NB_IOT_TWELVE_TONE_BASE_SEQUENCE_TAG 0xC1 +#define FAPI_NB_IOT_THREE_TONE_CYCLIC_SHIFT_TAG 0xC2 +#define FAPI_NB_IOT_SIX_TONE_CYCLIC_SHIFT_TAG 0xC3 +#define FAPI_NB_IOT_DL_GAP_CONFIG_ENABLE_TAG 0xC4 +#define FAPI_NB_IOT_DL_GAP_THRESHOLD_TAG 0xC5 +#define FAPI_NB_IOT_DL_GAP_PERIODICITY_TAG 0xC6 +#define FAPI_NB_IOT_DL_GAP_DURATION_COEFFICIENT_TAG 0xC7 + +//... +#define FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG 0xC8 +#define FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG 0xC9 +#define FAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG 0xCA +#define FAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG 0xCB +#define FAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG 0xCC +#define FAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG 0xCD +#define FAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG 0xCE +#define FAPI_PHY_CAPABILITIES_LAA_SUPPORT_TAG 0xD1 +#define FAPI_PHY_CAPABILITIES_LAA_PD_SENSING_LBT_SUPPORT_TAG 0xD2 +#define FAPI_PHY_CAPABILITIES_LAA_MULTI_CARRIER_LBT_SUPPORT_TAG 0xD3 +#define FAPI_PHY_CAPABILITIES_LAA_PARTIAL_SF_SUPPORT_TAG 0xD4 +#define FAPI_PHY_CAPABILITIES_NB_IOT_SUPPORT_TAG 0xD5 +#define FAPI_PHY_CAPABILITIES_NB_IOT_OPERATING_MODE_CAPABILITY_TAG 0xD6 + +#define FAPI_PHY_CAPABILITIES_DATA_REPORT_MODE_TAG 0xF0 +#define FAPI_PHY_SFN_SF_TAG 0xF1 +#define FAPI_PHY_STATE_TAG 0xFA + +#define FAPI_MSG_OK 0x0 +#define FAPI_MSG_INVALID_STATE 0x1 +#define FAPI_MSG_INVALID_CONFIG 0x2 +#define FAPI_MSG_SFN_OUT_OF_SYNC 0x3 +#define FAPI_MSG_SUBFRAME_ERR 0x4 +#define FAPI_MSG_BCH_MISSING 0x5 +#define FAPI_MSG_INVALID_SFN 0x6 +#define FAPI_MSG_HI_ERR 0x7 +#define FAPI_MSG_TX_ERR 0x8 + +#define FAPI_MSG_LBT_NO_PDU_IN_DL_REQ 0x9 +#define FAPI_MSG_LBT_NO_VALID_CONFIG_REQ_RECIEVED 0xA +#define FAPI_MSG_FAPI_E_LBT_SF_SFN_PASSED_END_SF_SFN 0xB +#define FAPI_MSG_FAPI_E_LBT_OVERLAP 0xC +#define FAPI_MSG_BCH_PRESENT 0xD +#define FAPI_MSG_NBIOT_UNEXPECTED_REQ 0xE + + +// TODO : Work out what the correct maximums should be + +// Number of UL/DL configurations, I, as defined by 36.212 section 5.3.3.1.4 +// todo : work out what the max is +#define FAPI_MAX_UL_DL_CONFIGURATIONS 4 +#define FAPI_MAX_NUM_PHYSICAL_ANTENNAS 4 +#define FAPI_MAX_NUM_SCHEDULED_UES 8 +#define FAPI_MAX_NUM_SUBBANDS 8 +#define FAPI_MAX_ANTENNA_PORT_COUNT 2 + + +typedef struct { + uint8_t message_id; + uint16_t length; +} fapi_header_t; + +typedef struct { + uint8_t tag; + uint8_t length; + uint16_t value; +} fapi_tlv_t; + +typedef struct { + fapi_header_t header; +} fapi_param_req_t; + +typedef struct { + fapi_header_t header; + uint8_t error_code; + uint8_t number_of_tlvs; + fapi_tlv_t tlvs[255]; +} fapi_param_resp_t; + +typedef struct { + fapi_header_t header; + uint8_t number_of_tlvs; + fapi_tlv_t tlvs[255]; +} fapi_config_req_t; + +typedef struct { + fapi_header_t header; + uint8_t error_code; + uint8_t number_of_invalid_tlvs; + uint8_t number_of_missing_tlvs; + fapi_tlv_t tlvs[255]; +} fapi_config_resp_t; + +typedef struct { + fapi_header_t header; +} fapi_start_req_t; + +typedef struct { + fapi_header_t header; +} fapi_stop_req_t; + +typedef struct { + fapi_header_t header; +} fapi_stop_ind_t; + +typedef struct { + uint16_t received_sfn_sf; + uint16_t expected_sfn_sf; +} fapi_sfn_out_of_sync_error_ind_t; + +typedef struct { + uint16_t received_sfn_sf; + uint16_t expected_sfn_sf; +} fapi_invalid_sfn_error_ind_t; + +typedef struct { + uint8_t sub_error_code; + uint8_t direction; + uint16_t rnti; + uint8_t pdu_type; +} fapi_pdu_error_ind_t; + +typedef struct { + uint8_t sub_error_code; + uint8_t phich_lowest_ul_rb_index; +} fapi_hi_error_ind_t; + +typedef struct { + uint8_t sub_error_code; + uint8_t pdu_index; +} fapi_tx_error_ind_t; + +typedef struct { + fapi_header_t header; + uint8_t message_id; + uint8_t error_code; + union + { + fapi_sfn_out_of_sync_error_ind_t out_of_sync_err; + fapi_invalid_sfn_error_ind_t invalid_sfn_err; + fapi_pdu_error_ind_t pdu_err; + fapi_hi_error_ind_t hi_err; + fapi_tx_error_ind_t tx_err; + }; +} fapi_error_ind_t; + +typedef struct { + uint32_t handle; + uint16_t rnti; +} fapi_rx_ue_information_t; + +typedef struct { + uint8_t ul_cqi; + uint8_t channel; +} fapi_ul_cqi_information_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; +} fapi_subframe_ind_t; + +typedef struct { + uint8_t value_0; + uint8_t value_1; +} fapi_harq_ind_rel8_tdd_harq_data_bundling_t; + +typedef struct { + uint8_t value_0; + uint8_t value_1; + uint8_t value_2; + uint8_t value_3; +} fapi_harq_ind_rel8_tdd_harq_data_multiplexing_t; + +typedef struct { + uint8_t value_0; +} fapi_harq_ind_rel8_tdd_harq_data_special_bundling_t; + +typedef struct { + uint8_t mode; + uint8_t number_of_ack_nack; + union{ + fapi_harq_ind_rel8_tdd_harq_data_bundling_t bundling; + fapi_harq_ind_rel8_tdd_harq_data_multiplexing_t multiplex; + fapi_harq_ind_rel8_tdd_harq_data_special_bundling_t special_bundling; + } harq_data; +} fapi_harq_ind_rel8_tdd_pdu_t; + +typedef struct { + uint8_t value_0; +} fapi_harq_ind_rel8_tdd_harq_data_t; + + +typedef struct { + uint8_t mode; + uint8_t number_of_ack_nack; + union{ + fapi_harq_ind_rel8_tdd_harq_data_t bundling; + fapi_harq_ind_rel8_tdd_harq_data_t multiplex; + fapi_harq_ind_rel8_tdd_harq_data_special_bundling_t special_bundling; + fapi_harq_ind_rel8_tdd_harq_data_t channel_selection; + fapi_harq_ind_rel8_tdd_harq_data_t format_3; + } harq_data[21]; +} fapi_harq_ind_rel9_tdd_pdu_t; + +typedef struct { + uint8_t mode; + uint16_t number_of_ack_nack; + union{ + fapi_harq_ind_rel8_tdd_harq_data_t bundling; + fapi_harq_ind_rel8_tdd_harq_data_t multiplex; + fapi_harq_ind_rel8_tdd_harq_data_special_bundling_t special_bundling; + fapi_harq_ind_rel8_tdd_harq_data_t channel_selection; + fapi_harq_ind_rel8_tdd_harq_data_t format_3; + fapi_harq_ind_rel8_tdd_harq_data_t format_4; + fapi_harq_ind_rel8_tdd_harq_data_t format_5; + } harq_data[22]; +} fapi_harq_ind_rel13_tdd_pdu_t; + +typedef struct { + uint8_t harq_tb_1; + uint8_t harq_tb_2; +} fapi_harq_ind_rel8_fdd_pdu_t; + +typedef struct { + uint8_t mode; + uint8_t number_of_ack_nack; + uint8_t harq_tb_n[10]; +} fapi_harq_ind_rel9_fdd_pdu_t; + +typedef struct { + uint8_t mode; + uint16_t number_of_ack_nack; + uint8_t harq_tb_n[22]; +} fapi_harq_ind_rel13_fdd_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + union { + fapi_harq_ind_rel8_tdd_pdu_t rel8_tdd_pdu; + fapi_harq_ind_rel9_tdd_pdu_t rel9_tdd_pdu; + fapi_harq_ind_rel13_tdd_pdu_t rel13_tdd_pdu; + fapi_harq_ind_rel8_fdd_pdu_t rel8_fdd_pdu; + fapi_harq_ind_rel9_fdd_pdu_t rel9_fdd_pdu; + fapi_harq_ind_rel13_fdd_pdu_t rel13_fdd_pdu; + }; + fapi_ul_cqi_information_t ul_cqi_info; +} fapi_harq_ind_pdu_t; + +typedef struct { + uint16_t number_of_harqs; + fapi_harq_ind_pdu_t pdus[32]; +} fapi_harq_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_harq_ind_body_t body; +} fapi_harq_ind_t; + +typedef struct { + uint8_t crc_flag; +} fapi_crc_ind_rel8_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + fapi_crc_ind_rel8_pdu_t rel8_pdu; +} fapi_crc_ind_pdu_t; + +typedef struct { + uint16_t number_of_crcs; + fapi_crc_ind_pdu_t pdus[32]; +} fapi_crc_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_crc_ind_body_t body; +} fapi_crc_ind_t; + +typedef struct { + uint16_t length; + uint16_t data_offset; + uint8_t ul_cqi; + uint16_t timing_advance; +} fapi_rx_ulsch_ind_rel8_pdu_t; + +typedef struct { + uint16_t timing_advance_r9; +} fapi_rx_ulsch_ind_rel9_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + fapi_rx_ulsch_ind_rel8_pdu_t rel8_pdu; + fapi_rx_ulsch_ind_rel9_pdu_t rel9_pdu; +} fapi_rx_ulsch_ind_pdu_t; + +typedef struct { + uint16_t number_of_pdus; + fapi_rx_ulsch_ind_pdu_t pdus[32]; + void* data[32]; +} fapi_rx_ulsch_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_rx_ulsch_ind_body_t body; +} fapi_rx_ulsch_ind_t; + +typedef struct { + uint16_t length; + uint16_t data_offset; + uint8_t ul_cqi; + uint8_t ri; + uint16_t timing_advance; +} fapi_rx_cqi_ind_rel8_pdu_t; + +typedef struct { + uint16_t length; + uint16_t data_offset; + uint8_t ul_cqi; + uint8_t number_of_cc_reported; + uint8_t ri[5]; + uint16_t timing_advance; + uint16_t timing_advance_r9; +} fapi_rx_cqi_ind_rel9_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + fapi_rx_cqi_ind_rel8_pdu_t rel8_pdu; + fapi_rx_cqi_ind_rel9_pdu_t rel9_pdu; + fapi_ul_cqi_information_t ul_cqi_info; +} fapi_rx_cqi_ind_pdu_t; + +typedef struct { + uint16_t number_of_pdus; + fapi_rx_cqi_ind_pdu_t pdus[32]; + uint8_t* data[32]; +} fapi_rx_cqi_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_rx_cqi_ind_body_t body; +} fapi_rx_cqi_ind_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + fapi_ul_cqi_information_t ul_cqi_info; +} fapi_rx_sr_ind_pdu_t; + +typedef struct { + uint16_t number_of_srs; + fapi_rx_sr_ind_pdu_t pdus[32]; +} fapi_rx_sr_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_rx_sr_ind_body_t body; +} fapi_rx_sr_ind_t; + +typedef struct { + uint16_t rnti; + uint8_t preamble; + uint16_t timing_advance; +} fapi_rach_ind_pdu_rel8_t; + +typedef struct { + uint16_t timing_advance_r9; +} fapi_rach_ind_pdu_rel9_t; + +typedef struct { + uint8_t rach_resource_type; +} fapi_rach_ind_pdu_rel13_t; + +typedef struct { + fapi_rach_ind_pdu_rel8_t rel8_pdu; + fapi_rach_ind_pdu_rel9_t rel9_pdu; + fapi_rach_ind_pdu_rel13_t rel13_pdu; +} fapi_rach_ind_pdu_t; + +typedef struct { + uint8_t number_of_preambles; + fapi_rach_ind_pdu_t pdus[32]; +} fapi_rach_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_rach_ind_body_t body; +} fapi_rach_ind_t; + + +typedef struct { + uint16_t doppler_estimation; + uint16_t timing_advance; + uint8_t number_of_resource_blocks; + uint8_t rb_start; + uint8_t snr[100]; +} fapi_srs_ind_rel8_pdu_t; + +typedef struct { + uint16_t timing_advance_r9; +} fapi_srs_ind_rel9_pdu_t; + +typedef struct { + uint8_t uppts_symbol; +} fapi_srs_ind_rel10_tdd_pdu_t; + +typedef struct { + uint16_t ul_rtoa; +} fapi_srs_ind_rel11_pdu_t; + +typedef struct { + uint8_t num_prb_per_subband; + uint8_t number_of_subbands; + uint8_t num_atennas; + struct { + uint8_t subband_index; + uint16_t channel[FAPI_MAX_NUM_PHYSICAL_ANTENNAS]; + } subands[FAPI_MAX_NUM_SUBBANDS]; +} fapi_ttd_channel_measurement_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + fapi_srs_ind_rel8_pdu_t rel8_pdu; + fapi_srs_ind_rel9_pdu_t rel9_pdu; + fapi_srs_ind_rel10_tdd_pdu_t rel10_tdd_pdu; + fapi_srs_ind_rel11_pdu_t rel11_pdu; + fapi_ttd_channel_measurement_t tdd_channel_measurement; +} fapi_srs_ind_pdu_t; + +typedef struct { + uint8_t number_of_ues; + fapi_srs_ind_pdu_t pdus[32]; +} fapi_srs_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_srs_ind_body_t body; +} fapi_srs_ind_t; + + +typedef struct { + uint32_t handle; + uint32_t result; + uint32_t lte_txop_symbols; + uint32_t initial_partial_sf; +} fapi_lbt_dl_pdsch_rsp_rel13_pdu_t; + +typedef struct { + fapi_lbt_dl_pdsch_rsp_rel13_pdu_t rel13_pdu; +} fapi_lbt_dl_pdsch_rsp_pdu_t; + +typedef struct { + uint32_t handle; + uint32_t result; +} fapi_lbt_dl_drs_rsp_rel13_pdu_t; + +typedef struct { + fapi_lbt_dl_drs_rsp_rel13_pdu_t rel13_pdu; +} fapi_lbt_dl_drs_rsp_pdu_t; + +typedef struct { + uint8_t pdu_type; + uint8_t pdu_size; + union { + fapi_lbt_dl_pdsch_rsp_pdu_t lbt_pdsch_rsp_pdu; + fapi_lbt_dl_drs_rsp_pdu_t lbt_drs_rsp_pdu; + }; +} fapi_lbt_dl_ind_pdu_t; + +typedef struct { + uint16_t number_of_pdus; + fapi_lbt_dl_ind_pdu_t pdus[32]; +} fapi_lbt_dl_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_lbt_dl_ind_body_t body; +} fapi_lbt_dl_ind_t; + +typedef struct { + uint8_t harq_tb1; +} fapi_nb_harq_ind_rel13_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + union { + fapi_nb_harq_ind_rel13_pdu_t rel13_pdu; + }; + fapi_ul_cqi_information_t ul_cqi_info; +} fapi_nb_harq_ind_pdu_t; + +typedef struct { + uint16_t number_of_harqs; + fapi_nb_harq_ind_pdu_t pdus[32]; +} fapi_nb_harq_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_nb_harq_ind_body_t body; +} fapi_nb_harq_ind_t; + +typedef struct { + uint16_t rnti; + uint8_t initial_sc; + uint16_t timing_advance; + uint8_t nrach_cs_level; +} fapi_nrach_ind_rel13_pdu_t; + +typedef struct { + fapi_rx_ue_information_t rx_ue_info; + union { + fapi_nrach_ind_rel13_pdu_t rel13_pdu; + }; + fapi_ul_cqi_information_t ul_cqi_info; +} fapi_nrach_ind_pdu_t; + +typedef struct { + uint16_t number_of_initial_scs_detected; + fapi_nrach_ind_pdu_t pdus[32]; +} fapi_nrach_ind_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_nrach_ind_body_t body; +} fapi_nrach_ind_t; + +//------------------------------------------------------------------------------ + +typedef struct { + uint8_t dci_format; + uint8_t cce_index; + uint8_t aggregation_level; + uint16_t rnti; + uint8_t resource_allocation_type; + uint8_t virtual_resource_block_assignment_flag; + uint32_t resource_block_coding; + uint8_t mcs_1; + uint8_t redundancy_version_1; + uint8_t new_data_indicator_1; + uint8_t transport_block_to_codeword_swap_flag; + uint8_t mcs_2; + uint8_t redundancy_version_2; + uint8_t new_data_indictor_2; + uint8_t harq_process; + uint8_t tpmi; + uint8_t pmi; + uint8_t precoding_information; + uint8_t tpc; + uint8_t downlink_assignment_index; + uint8_t n_gap; + uint8_t transport_block_size_index; + uint8_t downlink_power_offset; + uint8_t allocate_prach_flag; + uint8_t preamble_index; + uint8_t prach_mask_index; + uint8_t rnti_type; + uint16_t transmission_power; +} fapi_dl_config_dci_rel8_pdu_t; + +typedef struct { + uint8_t mcch_flag; + uint8_t mcch_change_notification; + uint8_t scrambling_identity; +} fapi_dl_config_dci_rel9_pdu_t; + +typedef struct { + uint8_t cross_carrier_scheduling_flag; + uint8_t carrier_indicator; + uint8_t srs_flag; + uint8_t srs_request; + uint8_t antenna_ports_scrambling_and_layers; + uint8_t total_dci_length_including_padding; + uint8_t n_dl_rb; +} fapi_dl_config_dci_rel10_pdu_t; + +typedef struct { + uint8_t harq_ack_resource_offset; + uint8_t pdsch_re_mapping_quasi_co_location_indicator; +} fapi_dl_config_dci_rel11_pdu_t; + +typedef struct { + uint8_t primary_cell_type; + uint8_t ul_dl_configuration_flag; + uint8_t number_ul_dl_configurations; + uint8_t ul_dl_configuration_indication[FAPI_MAX_UL_DL_CONFIGURATIONS]; +} fapi_dl_config_dci_rel12_pdu_t; + + +typedef struct { + uint8_t subband_index; + uint8_t scheduled_ues; + uint16_t precoding_value[FAPI_MAX_NUM_PHYSICAL_ANTENNAS][FAPI_MAX_NUM_SCHEDULED_UES]; +} fapi_dl_config_dci_dl_tpm_subband_info_t; + +typedef struct { + uint8_t num_prb_per_subband; + uint8_t number_of_subbands; + uint8_t num_antennas; + fapi_dl_config_dci_dl_tpm_subband_info_t subband_info[FAPI_MAX_NUM_SUBBANDS]; +} fapi_dl_config_dci_dl_tpm_t; + +typedef struct { + uint8_t laa_end_partial_sf_flag; + uint8_t laa_end_partial_sf_configuration; + uint8_t initial_lbt_sf; + uint8_t codebook_size_determination; + uint8_t drms_table_flag; + uint8_t tpm_struct_flag; + fapi_dl_config_dci_dl_tpm_t tpm; +} fapi_dl_config_dci_rel13_pdu_t; + +typedef struct { + fapi_dl_config_dci_rel8_pdu_t rel8_pdu; + fapi_dl_config_dci_rel9_pdu_t rel9_pdu; + fapi_dl_config_dci_rel10_pdu_t rel10_pdu; + fapi_dl_config_dci_rel11_pdu_t rel11_pdu; + fapi_dl_config_dci_rel12_pdu_t rel12_pdu; + fapi_dl_config_dci_rel13_pdu_t rel13_pdu; +} fapi_dl_config_dci_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint16_t transmission_power; +} fapi_dl_config_bch_rel8_pdu_t; + +typedef struct { + fapi_dl_config_bch_rel8_pdu_t rel8_pdu; +} fapi_dl_config_bch_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint16_t rnti; + uint8_t resource_allocation_type; + uint32_t resource_block_coding; + uint8_t modulation; + uint16_t transmission_power; + uint16_t mbsfn_area_id; +} fapi_dl_config_mch_rel8_pdu_t; + +typedef struct { + fapi_dl_config_mch_rel8_pdu_t rel8_pdu; +} fapi_dl_config_mch_pdu_t; + +typedef struct { + uint8_t subband_index; + uint8_t num_atennas; + uint16_t bf_value[8]; +} fapi_dl_config_bf_vector_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint16_t rnti; + uint8_t resource_allocation_type; + uint8_t virtual_resource_block_assignment_flag; + uint32_t resource_block_coding; + uint8_t modulation; + uint8_t redundacy_version; + uint8_t transport_blocks; + uint8_t transport_block_codeword_swap_flag; + uint8_t transmission_scheme; + uint8_t number_of_layers; + uint8_t nunber_of_subands; + uint8_t codebook_index[13]; + uint8_t ue_category_capacity; + uint8_t p_a; + uint8_t delta_power_offset_index; + uint8_t n_gap; + uint8_t n_prb; + uint8_t transmission_mode; + uint8_t num_bf_prb_per_subband; + uint8_t num_bf_vecitor; + fapi_dl_config_bf_vector_t bf_vector[8]; +} fapi_dl_config_dlsch_rel8_pdu_t; + +typedef struct { + uint8_t nscid; +} fapi_dl_config_dlsch_rel9_pdu_t; + +typedef struct { + uint8_t csi_rs_flag; + uint8_t csi_rs_resource_config_r10; + uint16_t csi_rs_zero_tx_power_resource_config_bitmap_r10; + uint8_t csi_rs_number_nzp_configuration; + uint8_t csi_rs_resource_config[4]; + uint8_t pdsch_start; +} fapi_dl_config_dlsch_rel10_pdu_t; + +typedef struct { + uint8_t drms_config_flag; + uint16_t drms_scrambling; + uint8_t csi_config_flag; + uint16_t csi_scrambling; + uint8_t pdsch_re_mapping_flag; + uint8_t pdsch_re_mapping_atenna_ports; + uint8_t pdsch_re_mapping_freq_shift; +} fapi_dl_config_dlsch_rel11_pdu_t; + +typedef struct { + uint8_t altcqi_table_r12; + uint8_t maxlayers; + uint8_t n_dl_harq; +} fapi_dl_config_dlsch_rel12_pdu_t; + +typedef struct { + uint8_t dwpts_symbols; + uint8_t initial_lbt_sf; + uint8_t ue_type; + uint8_t pdsch_payload_type; + uint16_t initial_transmission_sf_io; + uint8_t drms_table_flag; +} fapi_dl_config_dlsch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_dlsch_rel8_pdu_t rel8_pdu; + fapi_dl_config_dlsch_rel9_pdu_t rel9_pdu; + fapi_dl_config_dlsch_rel10_pdu_t rel10_pdu; + fapi_dl_config_dlsch_rel11_pdu_t rel11_pdu; + fapi_dl_config_dlsch_rel12_pdu_t rel12_pdu; + fapi_dl_config_dlsch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_dlsch_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint16_t p_rnti; + uint8_t resource_allocation_type; + uint8_t virtual_resource_block_assignment_flag; + uint32_t resource_block_coding; + uint8_t mcs; + uint8_t redudancy_version; + uint8_t number_of_transport_blocks; + uint8_t transport_block_to_codeword_swap_flag; + uint8_t transmission_scheme; + uint8_t number_of_layers; + uint8_t codebook_index; + uint8_t ue_category_capacity; + uint8_t p_a; + uint16_t transmission_power; + uint8_t n_prb; + uint8_t n_gap; +} fapi_dl_config_pch_rel8_pdu_t; + +typedef struct { + uint8_t ue_mode; + uint16_t initial_transmission_sf_io; +} fapi_dl_config_pch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_pch_rel8_pdu_t rel8_pdu; + fapi_dl_config_pch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_pch_pdu_t; + +typedef struct { + uint16_t transmission_power; + uint8_t prs_bandwidth; + uint8_t prs_cyclic_prefix_type; + uint8_t prs_muting; +} fapi_dl_config_prs_rel9_pdu_t; + +typedef struct { + fapi_dl_config_prs_rel9_pdu_t rel9_pdu; +} fapi_dl_config_prs_pdu_t; + +typedef struct { + uint8_t csi_rs_antenna_port_count_r10; + uint8_t csi_rs_resource_config_r10; + uint16_t transmission_power; + uint16_t csi_rs_zero_tx_power_resource_config_bitmap_r10; + uint8_t csi_rs_number_of_nzp_configuration; + uint8_t csi_rs_resource_config[8]; +} fapi_dl_config_csi_rs_rel10_pdu_t; + +typedef struct { + uint8_t csi_rs_class; + uint8_t cdm_type; + uint8_t num_bf_vector; + struct { + uint8_t csi_rs_resource_index; + uint16_t bf_value[FAPI_MAX_ANTENNA_PORT_COUNT]; + } bf_vector[8]; +}fapi_dl_config_csi_rs_rel13_pdu_t; + +typedef struct { + fapi_dl_config_csi_rs_rel10_pdu_t rel10_pdu; + fapi_dl_config_csi_rs_rel13_pdu_t rel13_pdu; +} fapi_dl_config_csi_rs_pdu_t; + +typedef struct { + uint8_t edpcch_resource_assigenment_flag; + uint16_t edpcch_id; + uint8_t epdcch_start_symbol; + uint8_t epdcch_num_prb; + uint8_t epdcch_prb_index[8]; + fapi_dl_config_bf_vector_t bf_vector; +} fapi_dl_config_edpcch_rel11_params_t; + +typedef struct { + uint8_t dwpts_symbols; + uint8_t initial_lbt_sf; +} fapi_dl_config_edpcch_rel13_params_t; + +typedef struct { + fapi_dl_config_dci_rel8_pdu_t rel8_pdu; + fapi_dl_config_dci_rel9_pdu_t rel9_pdu; + fapi_dl_config_dci_rel10_pdu_t rel10_pdu; + fapi_dl_config_dci_rel11_pdu_t rel11_pdu; + fapi_dl_config_dci_rel12_pdu_t rel12_pdu; + fapi_dl_config_dci_rel13_pdu_t rel13_pdu; + fapi_dl_config_edpcch_rel11_params_t rel8_params; + fapi_dl_config_edpcch_rel13_params_t rel13_params; +} fapi_dl_config_edpcch_pdu_t; + +typedef struct { + uint8_t mpdcch_narrow_band; + uint8_t number_of_prb_pairs; + uint8_t resource_block_assignment; + uint8_t mpdcch_tansmission_type; + uint8_t start_symbol; + uint8_t ecce_index; + uint8_t aggregation_level; + uint8_t rnti_type; + uint16_t rnti; + uint8_t ce_mode; + uint16_t drms_scrambling_init; + uint16_t initial_transmission_sf_io; + uint16_t transmission_power; + uint8_t dci_format; + uint16_t resource_block_coding; + uint8_t mcs; + uint8_t pdsch_reptition_levels; + uint8_t redundancy_version; + uint8_t new_data_indicator; + uint8_t harq_process; + uint8_t tpmi_length; + uint8_t tpmi; + uint8_t pmi_flag; + uint8_t pmi; + uint8_t harq_resource_offset; + uint8_t dci_subframe_repetition_number; + uint8_t tpc; + uint8_t downlink_assignment_index_length; + uint8_t downlink_assignment_index; + uint8_t allocate_prach_flag; + uint8_t preamble_index; + uint8_t prach_mask_index; + uint8_t starting_ce_level; + uint8_t srs_request; + uint8_t antenna_ports_and_scrambling_identity_flag; + uint8_t antenna_ports_and_scrambling_identity; + uint8_t frequency_hopping_enabled_flag; + uint8_t paging_direct_indication_differentiation_flag; + uint8_t direct_indication; + uint8_t total_dci_length_including_padding; + uint8_t number_of_tx_antenna_ports; + uint16_t precoding_value[8]; +} fapi_dl_config_mdpcch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_mdpcch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_mdpcch_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint16_t transmission_power; + uint16_t hyper_sfn_2_lsbs; +} fapi_dl_config_nbch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_nbch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_nbch_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint8_t ncce_index; + uint8_t aggregation_level; + uint8_t start_symbol; + uint8_t rnti_type; + uint16_t rnti; + uint8_t scrambling_reinitialization_batch_index; + uint8_t nrs_antenna_ports_assumed_by_the_ue; + uint8_t dci_format; + uint8_t scheduling_delay; + uint8_t resource_assignment; + uint8_t repetition_number; + uint8_t mcs; + uint8_t new_data_indicator; + uint8_t harq_ack_resource; + uint8_t npdcch_order_indication; + uint8_t starting_number_of_nprach_repetitions; + uint8_t subcarrier_indication_of_nprach; + uint8_t paging_direct_indication_differentation_flag; + uint8_t direct_indication; + uint8_t dci_subframe_repetition_number; + uint8_t total_dci_length_including_padding; +} fapi_dl_config_npdcch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_npdcch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_npdcch_pdu_t; + +typedef struct { + uint16_t length; + uint16_t pdu_index; + uint8_t start_symbol; + uint8_t rnti_type; + uint16_t rnti; + uint16_t resource_assignment; + uint16_t repetition_number; + uint8_t modulation; + uint8_t number_of_subframes_for_resource_assignment; + uint8_t scrambling_sequence_initialization_cinit; + uint16_t sf_idx; + uint8_t nrs_antenna_ports_assumed_by_the_ue; +} fapi_dl_config_ndlsch_rel13_pdu_t; + +typedef struct { + fapi_dl_config_ndlsch_rel13_pdu_t rel13_pdu; +} fapi_dl_config_ndlsch_pdu_t; + +typedef struct { + uint8_t pdu_type; + uint8_t pdu_size; + union + { + fapi_dl_config_dci_pdu_t dci_dl_pdu; + fapi_dl_config_bch_pdu_t bch_pdu; + fapi_dl_config_mch_pdu_t mch_pdu; + fapi_dl_config_dlsch_pdu_t dlsch_pdu; + fapi_dl_config_pch_pdu_t pch_pdu; + fapi_dl_config_prs_pdu_t prs_pdu; + fapi_dl_config_csi_rs_pdu_t csirs_pdu; + fapi_dl_config_edpcch_pdu_t edpcch_pdu; + fapi_dl_config_mdpcch_pdu_t mdpcch_pdu; + fapi_dl_config_nbch_pdu_t nbch_pdu; + fapi_dl_config_npdcch_pdu_t npdcch_pdu; + fapi_dl_config_ndlsch_pdu_t ndlsch_pdu; + }; +} fapi_dl_config_req_pdu_t; + +typedef struct { + uint8_t number_of_pdcch_ofdm_symbols; + uint8_t number_of_dcis; + uint16_t number_of_pdus; + uint8_t number_of_pdsch_rntis; + uint16_t transmission_power_for_pcfich; + fapi_dl_config_req_pdu_t pdus[32]; +} fapi_dl_config_req_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + uint16_t length; + fapi_dl_config_req_body_t body; +} fapi_dl_config_req_t; + +typedef struct { + uint32_t handle; + uint16_t size; + uint16_t rnti; + uint8_t resource_block_start; + uint8_t number_of_resource_blocks; + uint8_t modulation_type; + uint8_t cyclic_shift_2_for_drms; + uint8_t frequency_hopping_enabled_flag; + uint8_t frequency_hopping_bits; + uint8_t new_data_indication; + uint8_t redundancy_version; + uint8_t harq_process_number; + uint8_t ul_tx_mode; + uint8_t current_tx_nb; + uint8_t n_srs; +} fapi_ul_config_req_ulsch_rel8_pdu_t; + +typedef struct { + uint8_t resource_allocation_type; + uint32_t resource_block_coding; + uint8_t transport_blocks; + uint8_t transmission_scheme; + uint8_t number_of_layers; + uint8_t codebook_index; + uint8_t disable_sequence_hopping_flag; +} fapi_ul_config_req_ulsch_rel10_pdu_t; + +typedef struct { + uint8_t virtual_cell_id_enabled_flag; + uint16_t npusch_identity; + uint8_t dmrs_config_flag; + uint16_t ndmrs_csh_identity; +} fapi_ul_config_req_ulsch_rel11_pdu_t; + +typedef struct { + uint8_t ue_type; + uint16_t total_number_of_repetitions; + uint16_t repetition_number; + uint16_t initial_transmission_sf_io; + uint8_t empty_symbols_due_to_re_tunning; +} fapi_ul_config_req_ulsch_rel13_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_rel8_pdu_t rel8_pdu; + fapi_ul_config_req_ulsch_rel10_pdu_t rel10_pdu; + fapi_ul_config_req_ulsch_rel11_pdu_t rel11_pdu; + fapi_ul_config_req_ulsch_rel13_pdu_t rel13_pdu; +} fapi_ul_config_req_ulsch_pdu_t; + +typedef struct { + uint8_t dl_cqi_pmi_size_rank_1; + uint8_t dl_cqi_pmi_size_rank_greater_1; + uint8_t ri_size; + uint8_t delta_offset_cqi; + uint8_t delta_offset_ri; +} fapi_ul_config_cqi_ri_rel8_information_t; + +typedef struct { + uint8_t dl_cqi_pmi_ri_size; + uint8_t control_type; +} fapi_ul_config_periodic_cqi_pmi_ri_report_t; + +typedef struct { + uint8_t number_of_cc; + struct { + uint8_t ri_size; + uint8_t dl_cqi_pmi_size; + } cc[5]; +} fapi_ul_config_aperiodic_cqi_pmi_ri_report_t; + +typedef struct { + uint8_t report_type; + uint8_t delta_offset_cqi; + uint8_t delta_offset_ri; + union { + fapi_ul_config_periodic_cqi_pmi_ri_report_t periodic_cqi_pmi_ri_report; + fapi_ul_config_aperiodic_cqi_pmi_ri_report_t aperiodic_cqi_pmi_ri_report; + }; +} fapi_ul_config_cqi_ri_rel9_information_t; + +typedef struct { + uint16_t dl_cqi_pmi_ri_size_2; +} fapi_ul_config_periodic_cqi_pmi_ri_report_re13_t; + +typedef struct { +} fapi_ul_config_aperiodic_cqi_pmi_ri_report_re13_t; + + +typedef struct { + union { + fapi_ul_config_periodic_cqi_pmi_ri_report_re13_t periodic_cqi_pmi_ri_report; + fapi_ul_config_aperiodic_cqi_pmi_ri_report_re13_t aperiodic_cqi_pmi_ri_report; + }; +} fapi_ul_config_cqi_ri_rel13_information_t; + +typedef struct { + fapi_ul_config_cqi_ri_rel8_information_t rel8_info; + fapi_ul_config_cqi_ri_rel9_information_t rel9_cqi_ri_info; + fapi_ul_config_cqi_ri_rel13_information_t rel13_cqi_ri_info; +} fapi_ul_config_cqi_ri_information_t; + +typedef struct { + uint8_t n_srs_initial; + uint8_t initial_number_of_resource_blocks; +} fapi_ul_config_init_tx_rel8_params_t; + +typedef struct { + fapi_ul_config_init_tx_rel8_params_t rel8_params; +} fapi_ul_config_init_tx_params_t; + +typedef struct { + uint8_t harq_size; + uint8_t delta_offset_harq; + uint8_t ack_nack_mode; +} fapi_ul_config_harq_rel10_information_t; + +typedef struct { + uint16_t harq_size_2; + uint8_t delta_offset_harq_2; +} fapi_ul_config_harq_rel13_information_t; + +typedef struct { + fapi_ul_config_harq_rel10_information_t rel10_info; + fapi_ul_config_harq_rel13_information_t rel13_info; +} fapi_ul_config_harq_information_t; + +typedef struct { + uint32_t handle; + uint16_t rnti; +} fapi_ul_config_req_ue_rel8_info_t; + +typedef struct { + uint8_t virtual_cell_id_enabled_flag; + uint16_t npusch_identity; +} fapi_ul_config_req_ue_rel11_info_t; + +typedef struct { + uint8_t ue_type; + uint8_t empty_symbols; + uint16_t total_number_of_repetitions; + uint16_t repetition_number; +} fapi_ul_config_req_ue_rel13_info_t; + +typedef struct { + fapi_ul_config_req_ue_rel8_info_t rel8_info; + fapi_ul_config_req_ue_rel11_info_t rel11_info; + fapi_ul_config_req_ue_rel13_info_t rel13_info; +} fapi_ul_config_req_ue_info_t; + +typedef struct { + uint16_t pucch_index; + uint8_t dl_cqi_pmi_size; +} fapi_ul_config_req_cqi_rel8_info_t; + +typedef struct { + uint8_t number_of_pucch_resource; + uint16_t pucch_index_p1; +} fapi_ul_config_req_cqi_rel10_info_t; + +typedef struct { + uint8_t csi_mode; + uint16_t dl_cqi_pmi_size_2; + uint8_t starting_prb; + uint8_t n_prb; + uint8_t cdm_index; + uint8_t n_srs; +} fapi_ul_config_req_cqi_rel13_info_t; + +typedef struct { + fapi_ul_config_req_cqi_rel8_info_t rel8_info; + fapi_ul_config_req_cqi_rel10_info_t rel10_info; + fapi_ul_config_req_cqi_rel13_info_t rel13_info; +} fapi_ul_config_req_cqi_info_t; + +typedef struct { + uint16_t pucch_index; +} fapi_ul_config_req_sr_rel8_info_t; + +typedef struct { + uint8_t number_of_pucch_resources; + uint16_t pucch_index_p1; +} fapi_ul_config_req_sr_rel10_info_t; + +typedef struct { + fapi_ul_config_req_sr_rel8_info_t rel8_info; + fapi_ul_config_req_sr_rel10_info_t rel10_info; +} fapi_ul_config_req_sr_info_t; + +typedef struct { + uint8_t harq_size; + uint8_t ack_nack_mode; + uint8_t number_of_pucch_resources; + uint16_t n_pucch_1_0; + uint16_t n_pucch_1_1; + uint16_t n_pucch_1_2; + uint16_t n_pucch_1_3; +} fapi_ul_config_req_harq_rel10_tdd_info_t; + +typedef struct { + uint16_t n_pucch_1_0; + uint8_t harq_size; +} fapi_ul_config_req_harq_rel8_fdd_info_t; + +typedef struct { + uint8_t harq_size; + uint8_t ack_nack_mode; + uint8_t number_of_pucch_resources; + uint16_t n_pucch_1_0; + uint16_t n_pucch_1_1; + uint16_t n_pucch_1_2; + uint16_t n_pucch_1_3; +} fapi_ul_config_req_harq_rel9_fdd_info_t; + +typedef struct { + uint8_t num_ant_ports; + uint16_t n_pucch_2_0; + uint16_t n_pucch_2_1; + uint16_t n_pucch_2_2; + uint16_t n_pucch_2_3; +} fapi_ul_config_req_harq_rel11_fdd_tdd_info_t; + +typedef struct { + uint16_t harq_size_2; + uint8_t starting_prb; + uint8_t n_prb; + uint8_t cdm_index; + uint8_t n_srs; +} fapi_ul_config_req_harq_rel13_fdd_tdd_info_t; + +typedef struct { + fapi_ul_config_req_harq_rel10_tdd_info_t rel10_tdd_info; + fapi_ul_config_req_harq_rel8_fdd_info_t rel8_fdd_info; + fapi_ul_config_req_harq_rel9_fdd_info_t rel9_fdd_info; + fapi_ul_config_req_harq_rel11_fdd_tdd_info_t rel11_fdd_tdd_info; + fapi_ul_config_req_harq_rel13_fdd_tdd_info_t rel13_fdd_tdd_info; +} fapi_ul_config_req_harq_info_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_cqi_ri_information_t cqi_ri_info; + fapi_ul_config_init_tx_params_t init_tx_params; +} fapi_ul_config_req_ulsch_cqi_ri_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_harq_information_t harq_info; + fapi_ul_config_init_tx_params_t init_tx_params; +} fapi_ul_config_req_ulsch_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_cqi_ri_information_t cqi_ri_info; + fapi_ul_config_harq_information_t harq_info; + fapi_ul_config_init_tx_params_t init_tx_params; +} fapi_ul_config_req_ulsch_cqi_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_cqi_info_t cqi_info; +} fapi_ul_config_req_uci_cqi_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_sr_info_t sr_info; +} fapi_ul_config_req_uci_sr_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_harq_info_t harq_info; +} fapi_ul_config_req_uci_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_sr_info_t sr_info; + fapi_ul_config_req_harq_info_t harq_info; +} fapi_ul_config_req_uci_sr_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_cqi_info_t cqi_info; + fapi_ul_config_req_harq_info_t harq_info; +} fapi_ul_config_req_uci_cqi_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_cqi_info_t cqi_info; + fapi_ul_config_req_sr_info_t sr_info; +} fapi_ul_config_req_uci_cqi_sr_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; + fapi_ul_config_req_cqi_info_t cqi_info; + fapi_ul_config_req_sr_info_t sr_info; + fapi_ul_config_req_harq_info_t harq_info; +} fapi_ul_config_req_uci_cqi_sr_harq_pdu_t; + +typedef struct { + uint32_t handle; + uint16_t size; + uint16_t rnti; + uint8_t srs_bandwidth; + uint8_t frqeuency_domain_position; + uint8_t srs_hopping_bandwidth; + uint8_t transmission_comb; + uint16_t srs_config_index; + uint8_t sounding_reference_cyclic_shift; +} fapi_ul_config_req_srs_rel8_pdu_t; + +typedef struct { + uint8_t antenna_port; +} fapi_ul_config_req_srs_rel10_pdu_t; + +typedef struct { + uint8_t number_of_combs; +} fapi_ul_config_req_srs_rel13_pdu_t; + +typedef struct { + fapi_ul_config_req_srs_rel8_pdu_t rel8_pdu; + fapi_ul_config_req_srs_rel10_pdu_t rel10_pdu; + fapi_ul_config_req_srs_rel13_pdu_t rel13_pdu; +} fapi_ul_config_req_srs_pdu_t; + +typedef struct { + fapi_ul_config_req_ue_info_t ue_info; +} fapi_ul_config_req_harq_buffer_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_req_cqi_info_t csi_information; +} fapi_ul_config_req_ulsch_uci_csi_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_req_harq_info_t harq_information; +} fapi_ul_config_req_ulsch_uci_harq_pdu_t; + +typedef struct { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_req_cqi_info_t csi_information; + fapi_ul_config_req_harq_info_t harq_information; +} fapi_ul_config_req_ulsch_csi_uci_harq_pdu_t; + +typedef struct { + uint8_t harq_ack_resource; +} fapi_ul_config_req_nb_harq_rel13_info_t; + +typedef struct { + fapi_ul_config_req_nb_harq_rel13_info_t nb_harq_pdu_rel13; +} fapi_ul_config_req_nb_harq_info_t; + +typedef struct { + uint8_t nulsch_format; + uint32_t handle; + uint16_t size; + uint16_t rnti; + uint8_t subcarrier_indication; + uint8_t resource_assignment; + uint8_t mcs; + uint8_t redudancy_version; + uint8_t repetition_number; + uint8_t new_data_indication; + uint8_t n_srs; + uint16_t scrambling_sequence_initialization_cinit; + uint16_t sf_idx; + fapi_ul_config_req_ue_info_t ue_information; + fapi_ul_config_req_nb_harq_info_t nb_harq_information; +} fapi_ul_config_req_nulsch_rel13_pdu_t; + +typedef struct { + fapi_ul_config_req_nulsch_rel13_pdu_t nulsch_pdu_rel13; +} fapi_ul_config_req_nulsch_pdu_t; + +typedef struct { + uint8_t nprach_config_0; + uint8_t nprach_config_1; + uint8_t nprach_config_2; +} fapi_ul_config_req_nrach_rel13_pdu_t; + +typedef struct { + fapi_ul_config_req_nrach_rel13_pdu_t nrach_pdu_rel13; +} fapi_ul_config_req_nrach_pdu_t; + +typedef struct { + uint8_t pdu_type; + uint8_t pdu_size; + union + { + fapi_ul_config_req_ulsch_pdu_t ulsch_pdu; + fapi_ul_config_req_ulsch_cqi_ri_pdu_t ulsch_cqi_ri_pdu; + fapi_ul_config_req_ulsch_harq_pdu_t ulsch_harq_pdu; + fapi_ul_config_req_ulsch_cqi_harq_pdu_t ulsch_cqi_harq_pdu; + fapi_ul_config_req_uci_cqi_pdu_t uci_cqi_pdu; + fapi_ul_config_req_uci_sr_pdu_t uci_sr_pdu; + fapi_ul_config_req_uci_harq_pdu_t uci_harq_pdu; + fapi_ul_config_req_uci_sr_harq_pdu_t uci_sr_harq_pdu; + fapi_ul_config_req_uci_cqi_harq_pdu_t uci_cqi_harq_pdu; + fapi_ul_config_req_uci_cqi_sr_pdu_t uci_cqi_sr_pdu; + fapi_ul_config_req_uci_cqi_sr_harq_pdu_t uci_cqi_sr_harq_pdu; + fapi_ul_config_req_srs_pdu_t srs_pdu; + fapi_ul_config_req_harq_buffer_pdu_t harq_buffer_pdu; + fapi_ul_config_req_ulsch_uci_csi_pdu_t ulsch_uci_csi_pdu; + fapi_ul_config_req_ulsch_uci_harq_pdu_t ulsch_uci_harq_pdu; + fapi_ul_config_req_ulsch_csi_uci_harq_pdu_t ulsch_csi_uci_harq_pdu; + fapi_ul_config_req_nulsch_pdu_t nulsch_pdu; + fapi_ul_config_req_nrach_pdu_t nrach_pdu; + }; +} fapi_ul_config_req_pdu_t; + +typedef struct { + uint8_t number_of_pdus; + uint8_t rach_prach_frequency_resources; + uint8_t srs_present; + fapi_ul_config_req_pdu_t* pdus; +} fapi_ul_config_req_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + uint16_t length; + fapi_ul_config_req_body_t body; +} fapi_ul_config_req_t; + +typedef struct { + uint8_t dci_format; + uint8_t cce_index; + uint8_t aggregation_level; + uint8_t rnti; + uint8_t resource_block_start; + uint8_t number_of_resource_blocks; + uint8_t mcs_1; + uint8_t cyclic_shift_2_for_drms; + uint8_t frequency_hopping_enabled_flag; + uint8_t frequency_hopping_flags; + uint8_t new_data_indication_1; + uint8_t ue_tx_antenna_selection; + uint8_t tpc; + uint8_t cqi_csi_request; + uint8_t ul_index; + uint8_t dl_assignment_index; + uint32_t tpc_bitmap; + uint16_t transmission_power; +} fapi_hi_dci0_req_dci0_rel8_pdu_t; + +typedef struct { + uint8_t cross_carrier_scheduling_flag; + uint8_t carrier_indicator; + uint8_t size_of_cqi_csi_feild; + uint8_t srs_flag; + uint8_t srs_request; + uint8_t resource_allocation_flag; + uint8_t resource_allocation_type; + uint32_t resource_block_coding; + uint8_t mcs_2; + uint8_t new_data_indication_2; + uint8_t number_of_antenna_ports; + uint8_t tpmi; + uint8_t total_dci_length_including_padding; + uint8_t n_ul_rb; +} fapi_hi_dci0_req_dci0_rel10_pdu_t; + +typedef struct { + uint8_t pscch_resource; + uint8_t time_resource_pattern; +} fapi_hi_dci0_req_dci0_rel12_pdu_t; + +typedef struct { + fapi_hi_dci0_req_dci0_rel8_pdu_t rel8_pdu; + fapi_hi_dci0_req_dci0_rel10_pdu_t rel10_pdu; + fapi_hi_dci0_req_dci0_rel12_pdu_t rel12_pdu; +} fapi_hi_dci0_req_dci0_pdu_t; + +typedef struct { + uint8_t resource_block_start; + uint8_t cyclic_shift_2_for_drms; + uint8_t hi_value; + uint8_t i_phich; + uint16_t transmission_power; +} fapi_hi_dci0_req_hi_rel8_pdu_t; + +typedef struct { + uint8_t flag_tb2; + uint8_t hi_value_2; +} fapi_hi_dci0_req_hi_rel10_pdu_t; + +typedef struct { + fapi_hi_dci0_req_hi_rel8_pdu_t rel8_pdu; + fapi_hi_dci0_req_hi_rel10_pdu_t rel10_pdu; +} fapi_hi_dci0_req_hi_pdu_t; + +typedef struct { + fapi_dl_config_dci_rel8_pdu_t edpcch_dci_pdu_rel8; + fapi_dl_config_dci_rel10_pdu_t edpcch_dci_pdu_rel10; + fapi_dl_config_edpcch_rel11_params_t edpcch_parameters_rel11; +} fapi_hi_dci0_req_epdcch_dci_ul_pdu_t; + +typedef struct { + uint8_t mpdcch_narrowband; + uint8_t number_of_prb_pairs; + uint8_t resource_block_assignment; + uint8_t mpdcch_transmission_type; + uint8_t start_symbol; + uint8_t ecce_index; + uint8_t aggreagation_level; + uint8_t rnti_type; + uint16_t rnti; + uint8_t ce_mode; + uint16_t drms_scrambling_init; + uint16_t initial_transmission_sf_io; + uint16_t transmission_power; + uint8_t dci_format; + uint8_t resource_block_start; + uint8_t number_of_resource_blocks; + uint8_t mcs; + uint8_t pusch_repetition_levels; + uint8_t frequency_hopping_flag; + uint8_t new_data_indication; + uint8_t harq_process; + uint8_t redudency_version; + uint8_t tpc; + uint8_t csi_request; + uint8_t ul_inex; + uint8_t dai_presence_flag; + uint8_t dl_assignment_index; + uint8_t srs_request; + uint8_t dci_subframe_repetition_number; + uint32_t tcp_bitmap; + uint8_t total_dci_length_include_padding; + uint8_t number_of_tx_antenna_ports; + uint16_t precoding_value[FAPI_MAX_ANTENNA_PORT_COUNT]; +} fapi_hi_dci0_req_mpdcch_dci_ul_rel13_pdu_t; + +typedef struct { + fapi_hi_dci0_req_mpdcch_dci_ul_rel13_pdu_t mpdcch_dci_pdu_rel13; +} fapi_hi_dci0_req_mpdcch_dci_ul_pdu_t; + +typedef struct { + uint8_t ncce_index; + uint8_t aggregation_level; + uint8_t start_symbol; + uint16_t rnti; + uint8_t scrambling_reinitialization_batch_index; + uint8_t nrs_antenna_ports_assumed_by_the_ue; + uint8_t subcarrier_indication; + uint8_t resource_assignment; + uint8_t scheduling_delay; + uint8_t mcs; + uint8_t redudancy_version; + uint8_t repetition_number; + uint8_t new_data_indicator; + uint8_t dci_subframe_repetition_number; +} fapi_hi_dci0_req_npdcch_dci_ul_rel13_pdu_t; + +typedef struct { + fapi_hi_dci0_req_npdcch_dci_ul_rel13_pdu_t npdcch_dci_pdu_rel13; +} fapi_hi_dci0_req_npdcch_dci_ul_pdu_t; + +typedef struct { + uint8_t pdu_type; + uint8_t pdu_size; + union + { + fapi_hi_dci0_req_hi_pdu_t hi_pdu; + fapi_hi_dci0_req_dci0_pdu_t dci0_pdu; + fapi_hi_dci0_req_epdcch_dci_ul_pdu_t edpcch_dci_ul_pdu; + fapi_hi_dci0_req_mpdcch_dci_ul_pdu_t mdpcch_dci_ul_pdu; + fapi_hi_dci0_req_npdcch_dci_ul_pdu_t ndpcch_dci_ul_pdu; + }; +} fapi_hi_dci0_req_pdu_t; + +typedef struct { + uint16_t sfn_sf; + uint8_t number_of_dci; + uint8_t number_of_hi; + fapi_hi_dci0_req_pdu_t* pdus; +} fapi_hi_dci0_req_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_hi_dci0_req_body_t body; +} fapi_hi_dci0_req_t; + +typedef struct { + uint16_t tag; + uint16_t length; + uint32_t* value; +} fapi_tx_req_pdu_tlv_t; + +typedef struct { + uint16_t pdu_length; + uint16_t pdu_index; + uint32_t num_tlv; + fapi_tx_req_pdu_tlv_t tlvs[32]; +} fapi_tx_req_pdu_t; + +typedef struct { + uint16_t number_of_pdus; + fapi_tx_req_pdu_t* pdus; +} fapi_tx_req_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + fapi_tx_req_body_t body; +} fapi_tx_req_t; + +typedef struct { + uint32_t handle; + uint32_t mp_cca; + uint32_t n_cca; + uint32_t offset; + uint32_t lte_txop_sf; + uint16_t txop_sfn_sf_end; + uint32_t lbt_mode; +} fapi_lbt_pdsch_req_rel13_pdu_t; + +typedef struct { + fapi_lbt_pdsch_req_rel13_pdu_t rel13_pdu; +} fapi_lbt_pdsch_req_pdu_t; + +typedef struct { + uint32_t handle; + uint32_t offset; + uint16_t sfn_sf_end; + uint32_t lbt_mode; +} fapi_lbt_drs_req_rel13_pdu_t; + +typedef struct { + fapi_lbt_drs_req_rel13_pdu_t rel13_pdu; +} fapi_lbt_drs_req_pdu_t; + +typedef struct { + uint8_t pdu_type; + uint8_t pdu_size; + union { + fapi_lbt_pdsch_req_pdu_t lbt_pdsch_req_pdu; + fapi_lbt_drs_req_pdu_t lbt_drs_req_pdu; + }; +} fapi_lbt_dl_config_req_pdu_t; + +typedef struct { + uint16_t number_of_pdus; + fapi_lbt_dl_config_req_pdu_t pdus[32]; +} fapi_lbt_dl_config_req_body_t; + +typedef struct { + fapi_header_t header; + uint16_t sfn_sf; + uint16_t length; + fapi_lbt_dl_config_req_body_t body; +} fapi_lbt_dl_config_req_t; + +//------------------------------------------------------------------------------ + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/nfapi/open-nFAPI/pnf_sim/inc/fapi_stub.h b/nfapi/open-nFAPI/pnf_sim/inc/fapi_stub.h new file mode 100644 index 0000000000..10df46e7ab --- /dev/null +++ b/nfapi/open-nFAPI/pnf_sim/inc/fapi_stub.h @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _FAPI_STUB_H_ +#define _FAPI_STUB_H_ + +#include "fapi_interface.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct fapi fapi_t; + +typedef struct fapi { + void* user_data; +} fapi_t; + +typedef struct { + int (*fapi_param_response)(fapi_t* fapi, fapi_param_resp_t* resp); + int (*fapi_config_response)(fapi_t* fapi, fapi_config_resp_t* resp); + + int (*fapi_subframe_ind)(fapi_t* fapi, fapi_subframe_ind_t* ind); + + int (*fapi_harq_ind)(fapi_t* fapi, fapi_harq_ind_t* ind); + int (*fapi_crc_ind)(fapi_t* fapi, fapi_crc_ind_t* ind); + int (*fapi_rx_ulsch_ind)(fapi_t* fapi, fapi_rx_ulsch_ind_t* ind); + int (*fapi_rx_cqi_ind)(fapi_t* fapi, fapi_rx_cqi_ind_t* ind); + int (*fapi_rx_sr_ind)(fapi_t* fapi, fapi_rx_sr_ind_t* ind); + int (*fapi_rach_ind)(fapi_t* fapi, fapi_rach_ind_t* ind); + int (*fapi_srs_ind)(fapi_t* fapi, fapi_srs_ind_t* ind); + + int (*fapi_lbt_dl_ind)(fapi_t* fapi, fapi_lbt_dl_ind_t* ind); + int (*fapi_nb_harq_ind)(fapi_t* fapi, fapi_nb_harq_ind_t* ind); + int (*fapi_nrach_ind)(fapi_t* fapi, fapi_nrach_ind_t* ind); + +} fapi_cb_t; + +typedef struct { + + uint16_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; +} fapi_config_t; + +fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config); + +void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port); + +int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req); +int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req); +int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req); + +int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req); +int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req); +int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req); +int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp new file mode 100644 index 0000000000..df0ca12305 --- /dev/null +++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp @@ -0,0 +1,642 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "fapi_stub.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct phy_pdu +{ + phy_pdu() : buffer_len(1500), buffer(0), len(0) + { + buffer = (char*) malloc(buffer_len); + } + + virtual ~phy_pdu() + { + free(buffer); + } + + + unsigned buffer_len; + char* buffer; + unsigned len; +}; + +class fapi_private +{ + std::mutex mutex; + std::queue rx_buffer; + + std::queue free_store; + public: + + fapi_private() + : byte_count(0), tick(0), first_dl_config(false) + { + } + + phy_pdu* allocate_phy_pdu() + { + phy_pdu* pdu = 0; + mutex.lock(); + if(free_store.empty()) + { + pdu = new phy_pdu(); + } + else + { + pdu = free_store.front(); + free_store.pop(); + } + mutex.unlock(); + return pdu; + } + + void release_phy_pdu(phy_pdu* pdu) + { + mutex.lock(); + free_store.push(pdu); + mutex.unlock(); + } + + bool rx_buffer_empty() + { + bool empty; + mutex.lock(); + empty = rx_buffer.empty(); + mutex.unlock(); + + return empty; + } + + + void push_rx_buffer(phy_pdu* buff) + { + mutex.lock(); + rx_buffer.push(buff); + mutex.unlock(); + } + + phy_pdu* pop_rx_buffer() + { + phy_pdu* buff = 0; + mutex.lock(); + if(!rx_buffer.empty()) + { + buff = rx_buffer.front(); + rx_buffer.pop(); + } + mutex.unlock(); + return buff; + } + + uint32_t byte_count; + uint32_t tick; + bool first_dl_config; + +}; + +extern "C" +{ + typedef struct fapi_internal + { + fapi_t _public; + + fapi_cb_t callbacks; + + uint8_t state; + fapi_config_t config; + + int rx_sock; + int tx_sock; + struct sockaddr_in tx_addr; + + uint32_t tx_byte_count; + uint32_t tick; + + fapi_private* fapi; + + } fapi_internal_t; +} + +extern void set_thread_priority(int); +/* +{ + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = 79; + sched_setscheduler(0, SCHED_RR, &schedParam); + + pthread_attr_setschedpolicy(&ptAttr, SCHED_RR); + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + pthread_attr_setschedparam(&ptAttr, &thread_params); +} +*/ + +void send_uplink_indications(fapi_internal_t* instance, uint16_t sfn_sf) +{ + fapi_harq_ind_t harq_ind; + (instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind); + + fapi_crc_ind_t crc_ind; + crc_ind.header.message_id = FAPI_CRC_INDICATION; + crc_ind.header.length = 0; //??; + crc_ind.sfn_sf = sfn_sf; + crc_ind.body.number_of_crcs = 1; + crc_ind.body.pdus[0].rx_ue_info.handle = 0; //?? + crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //?? + crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1; + + (instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind); + + if(!instance->fapi->rx_buffer_empty()) + { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + + + phy_pdu* buff = 0; + int i = 0; + std::list free_list; + do + { + buff = instance->fapi->pop_rx_buffer(); + if(buff != 0) + { + if(buff->len == 0) + { + printf("[FAPI] Buffer length = 0\n"); + } + + rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF; + rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242; + + rx_ind.body.pdus[i].rel8_pdu.length = buff->len; + //rx_ind.pdus[i].rel8_pdu.data_offset; + //rx_ind.pdus[i].rel8_pdu.ul_cqi; + //rx_ind.pdus[i].rel8_pdu.timing_advance; + + rx_ind.body.data[i] = buff->buffer; + + rx_ind.body.number_of_pdus++; + i++; + + instance->fapi->byte_count += buff->len; + + free_list.push_back(buff); + } + }while(buff != 0 && i < 8); + + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + + for(phy_pdu* pdu : free_list) + { + instance->fapi->release_phy_pdu(pdu); + //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); + } + } + else + { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + } + + + fapi_rx_cqi_ind_t cqi_ind; + cqi_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind); + + fapi_rx_sr_ind_t sr_ind; + sr_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind); + + fapi_rach_ind_t rach_ind; + rach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind); + + fapi_srs_ind_t srs_ind; + srs_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind); + /* + nfapi_lbt_dl_indication_t lbt_ind; + memset(&lbt_ind, 0, sizeof(lbt_ind)); + lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION; + lbt_ind.header.phy_id = config->phy_id; + lbt_ind.sfn_sf = sfn_sf; + nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind); + + vendor_ext_p7_ind ve_p7_ind; + memset(&ve_p7_ind, 0, sizeof(ve_p7_ind)); + ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND; + ve_p7_ind.header.phy_id = config->phy_id; + ve_p7_ind.error_code = NFAPI_MSG_OK; + nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header)); + */ + + fapi_nb_harq_ind_t nb_harq_ind; + nb_harq_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind); + + fapi_nrach_ind_t nrach_ind; + nrach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind); + +} + +void* fapi_thread_start(void* ptr) +{ + set_thread_priority(81); + + fapi_internal_t* instance = (fapi_internal_t*)ptr; + uint16_t sfn_sf_dec = 0; + uint32_t last_tv_usec = 0; + uint32_t last_tv_sec = 0; + + uint32_t millisec; + uint32_t last_millisec = -1; + uint16_t catchup = 0; + + while(1) + { + // get the time + struct timeval sf_start; + (void)gettimeofday(&sf_start, NULL); + + uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF)); + // increment the sfn/sf - for the next subframe + sfn_sf_dec++; + if(sfn_sf_dec > 10239) + sfn_sf_dec = 0; + + + fapi_subframe_ind_t ind; + ind.sfn_sf = sfn_sf; + + if(instance->fapi->first_dl_config) + send_uplink_indications(instance, sfn_sf); + + if(instance->tick == 1000) + { + if(instance->tx_byte_count > 0) + { + printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); + instance->tx_byte_count = 0; + } + + instance->tick = 0; + } + + instance->tick++; + + (instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind); + + { + phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0); + if(len > 0) + { + pdu->len = len; + instance->fapi->push_rx_buffer(pdu); + } + else + { + instance->fapi->release_phy_pdu(pdu); + } + } + + + if(catchup) + { + catchup--; + } + else + { + struct timespec now_ts; + struct timespec sleep_ts; + struct timespec sleep_rem_ts; + + // get the current time + clock_gettime(CLOCK_MONOTONIC, &now_ts); + + + // determine how long to sleep before the start of the next 1ms + sleep_ts.tv_sec = 0; + sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000); + + int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts); + + if(nanosleep_result != 0) + printf("*** nanosleep failed or was interrupted\n"); + + + clock_gettime(CLOCK_MONOTONIC, &now_ts); + millisec = now_ts.tv_nsec / 1e6; + + if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) + { + printf("*** missing millisec %d %d\n", last_millisec, millisec); + catchup = millisec - last_millisec - 1; + } + + last_millisec = millisec; + } + } +} + +extern "C" +{ + fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config) + { + fapi_internal_t* instance = (fapi_internal*)calloc(1, sizeof(fapi_internal_t)); + instance->callbacks = *callbacks; + instance->config = *config; + instance->state = 0; + + instance->fapi = new fapi_private(); + + return (fapi_t*)instance; + } + + void fapi_destroy(fapi_t* fapi) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + delete instance->fapi; + free(instance); + } + + void* fapi_rx_thread_start(void* ptr) + { + set_thread_priority(60); + + fapi_internal_t* instance = (fapi_internal_t*)ptr; + + while(1) + { + phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); + if(len > 0) + { + pdu->len = len; + instance->fapi->push_rx_buffer(pdu); + } + else + { + instance->fapi->release_phy_pdu(pdu); + } + + } + } + + void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + printf("[FAPI] Rx Data from %d\n", rx_port); + printf("[FAPI] Tx Data to %s:%d\n", tx_address, tx_port); + + instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(instance->rx_sock < 0) + { + printf("[FAPI] Failed to create socket\n"); + return; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(rx_port); + addr.sin_addr.s_addr = INADDR_ANY; + + int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); + + if(bind_result == -1) + { + printf("[FAPI] Failed to bind to port %d\n", rx_port); + close(instance->rx_sock); + return ; + } + + instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); + instance->tx_addr.sin_family = AF_INET; + instance->tx_addr.sin_port = htons(tx_port); + instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); + + } + + + void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value) + { + tlvs[count].tag = tag; + tlvs[count].value = value; + tlvs[count].length = len; + + } + + int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + fapi_param_resp_t resp; + resp.header.message_id = FAPI_PARAM_RESPONSE; + + resp.error_code = FAPI_MSG_OK; + + resp.number_of_tlvs = 0; + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state); + + + if(instance->state == 0) + { + if(instance->config.duplex_mode == 0) + { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + } + else if(instance->config.duplex_mode == 1) + { + // -- FDD + // Downlink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support); + // Uplink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support); + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + } + } + else + { + if(instance->config.duplex_mode == 0) + { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // TDD Frame Structure Config + // Data Report Mode + } + else if(instance->config.duplex_mode == 1) + { + // FDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // Data Report Mode + } + } + + + //todo fill + (instance->callbacks.fapi_param_response)(fapi, &resp); + + return 0; + } + + int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + fapi_config_resp_t resp; + resp.header.message_id = FAPI_CONFIG_RESPONSE; + resp.error_code = FAPI_MSG_OK; + + (instance->callbacks.fapi_config_response)(fapi, &resp); + return 0; + } + + int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + pthread_t fapi_thread; + pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance); + + return 0; + } + + int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + instance->fapi->first_dl_config = true; + return 0; + } + int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + return 0; + } + int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + return 0; + } + int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req) + { + fapi_internal_t* instance = (fapi_internal_t*)fapi; + + for(int i = 0; i < req->body.number_of_pdus; ++i) + { + uint16_t len = req->body.pdus[i].pdu_length; + uint32_t* data = req->body.pdus[i].tlvs[0].value; + //printf("[FAPI] sfnsf:%d len:%d\n", req->sfn_sf,len); + // + instance->tx_byte_count += len; + + int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr)); + + if(sendto_result == -1) + { + // error + } + } + + return 0; + } +} + diff --git a/nfapi/open-nFAPI/pnf_sim/src/main.cpp b/nfapi/open-nFAPI/pnf_sim/src/main.cpp new file mode 100644 index 0000000000..e2622cf3c3 --- /dev/null +++ b/nfapi/open-nFAPI/pnf_sim/src/main.cpp @@ -0,0 +1,2285 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include "debug.h" +#include "nfapi_pnf_interface.h" +#include "nfapi.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include + +#include "fapi_stub.h" +#include "pool.h" + + +#include +#include +#include +#include +#include +#include +#include + +#define NUM_P5_PHY 2 + +uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; + +static uint32_t rand_range(uint32_t min, uint32_t max) +{ + return ((rand() % (max + 1 - min)) + min); +} + + + +extern "C" nfapi_pnf_param_response_t g_pnf_param_resp; + +extern "C" { + + +void* pnf_allocate(size_t size) +{ + return (void*)memory_pool::allocate(size); +} + +void pnf_deallocate(void* ptr) +{ + memory_pool::deallocate((uint8_t*)ptr); +} + + +int read_xml(const char *xml_file); + +}; + +class udp_data +{ + public: + bool enabled; + uint32_t rx_port; + uint32_t tx_port; + std::string tx_addr; +}; + +class phy_info +{ + public: + + phy_info() + : first_subframe_ind(0), fapi(0), + dl_ues_per_subframe(0), ul_ues_per_subframe(0), + timing_window(0), timing_info_mode(0), timing_info_period(0) + { + index = 0; + id = 0; + + local_port = 0; + remote_addr = 0; + remote_port = 0; + + duplex_mode = 0; + dl_channel_bw_support = 0; + ul_channel_bw_support = 0; + num_dl_layers_supported = 0; + num_ul_layers_supported = 0; + release_supported = 0; + nmm_modes_supported = 0; + } + + uint16_t index; + uint16_t id; + std::vector rfs; + std::vector excluded_rfs; + + udp_data udp; + + std::string local_addr; + int local_port; + + char* remote_addr; + int remote_port; + + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; + + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; + + uint8_t first_subframe_ind; + + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; + + fapi_t* fapi; + +}; + +class rf_info +{ + public: + uint16_t index; + uint16_t band; + int16_t max_transmit_power; + int16_t min_transmit_power; + uint8_t num_antennas_supported; + uint32_t min_downlink_frequency; + uint32_t max_downlink_frequency; + uint32_t max_uplink_frequency; + uint32_t min_uplink_frequency; +}; + + +class pnf_info +{ + public: + + pnf_info() + : release(13), wireshark_test_mode(0), + max_total_power(0), oui(0) + + { + release = 0; + + sync_mode = 0; + location_mode = 0; + dl_config_timing = 0; + ul_config_timing = 0; + tx_timing = 0; + hi_dci0_timing = 0; + + max_phys = 0; + max_total_bw = 0; + max_total_dl_layers = 0; + max_total_ul_layers = 0; + shared_bands = 0; + shared_pa = 0; + + } + + int release; + std::vector phys; + std::vector rfs; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; + +}; + +struct pnf_phy_user_data_t +{ + uint16_t phy_id; + nfapi_pnf_config_t* config; + phy_info* phy; + nfapi_pnf_p7_config_t* p7_config; +}; + +int read_pnf_xml(pnf_info& pnf, const char* xml_file) +{ + try + { + std::ifstream input(xml_file); + + using boost::property_tree::ptree; + ptree pt; + + read_xml(input, pt); + + pnf.wireshark_test_mode = pt.get("pnf.wireshark_test_mode", 0); + + + pnf.sync_mode = pt.get("pnf.sync_mode"); + pnf.location_mode= pt.get("pnf.location_mode"); + //pnf.sync_mode = pt.get("pnf.location_coordinates"); + + pnf.dl_config_timing= pt.get("pnf.dl_config_timing"); + pnf.ul_config_timing = pt.get("pnf.ul_config_timing"); + pnf.tx_timing = pt.get("pnf.tx_timing"); + pnf.hi_dci0_timing = pt.get("pnf.hi_dci0_timing"); + + pnf.max_phys = pt.get("pnf.max_phys"); + pnf.max_total_bw = pt.get("pnf.max_total_bandwidth"); + pnf.max_total_dl_layers = pt.get("pnf.max_total_num_dl_layers"); + pnf.max_total_ul_layers = pt.get("pnf.max_total_num_ul_layers"); + + pnf.shared_bands = pt.get("pnf.shared_bands"); + pnf.shared_pa = pt.get("pnf.shared_pas"); + + pnf.max_total_power = pt.get("pnf.maximum_total_power"); + + //"oui"); + + for(const auto& v : pt.get_child("pnf.phys")) + { + if(v.first == "phy") + { + phy_info phy; + + + + phy.index = v.second.get("index"); + phy.local_port = v.second.get("port"); + phy.local_addr = v.second.get("address"); + phy.duplex_mode = v.second.get("duplex_mode"); + + phy.dl_channel_bw_support = v.second.get("downlink_channel_bandwidth_support"); + phy.ul_channel_bw_support = v.second.get("uplink_channel_bandwidth_support"); + phy.num_dl_layers_supported = v.second.get("number_of_dl_layers"); + phy.num_ul_layers_supported = v.second.get("number_of_ul_layers"); + phy.release_supported = v.second.get("3gpp_release_supported"); + phy.nmm_modes_supported = v.second.get("nmm_modes_supported"); + + for(const auto& v2 : v.second.get_child("rfs")) + { + if(v2.first == "index") + phy.rfs.push_back(v2.second.get_value()); + } + for(const auto& v2 : v.second.get_child("excluded_rfs")) + { + if(v2.first == "index") + phy.excluded_rfs.push_back(v2.second.get_value()); + } + + boost::optional d = v.second.get_child_optional("data.udp"); + if(d.is_initialized()) + { + phy.udp.enabled = true; + phy.udp.rx_port = d.get().get("rx_port"); + phy.udp.tx_port = d.get().get("tx_port"); + phy.udp.tx_addr = d.get().get("tx_addr"); + } + else + { + phy.udp.enabled = false; + } + + phy.dl_ues_per_subframe = v.second.get("dl_ues_per_subframe"); + phy.ul_ues_per_subframe = v.second.get("ul_ues_per_subframe"); + + pnf.phys.push_back(phy); + } + } + for(const auto& v : pt.get_child("pnf.rfs")) + { + if(v.first == "rf") + { + rf_info rf; + + rf.index = v.second.get("index"); + rf.band = v.second.get("band"); + rf.max_transmit_power = v.second.get("max_transmit_power"); + rf.min_transmit_power = v.second.get("min_transmit_power"); + rf.num_antennas_supported = v.second.get("num_antennas_supported"); + rf.min_downlink_frequency = v.second.get("min_downlink_frequency"); + rf.max_downlink_frequency = v.second.get("max_downlink_frequency"); + rf.min_uplink_frequency = v.second.get("max_uplink_frequency"); + rf.max_uplink_frequency = v.second.get("min_uplink_frequency"); + + pnf.rfs.push_back(rf); + } + } + } + catch(std::exception& e) + { + printf("%s", e.what()); + return -1; + } + catch(boost::exception& e) + { + printf("%s", boost::diagnostic_information(e).c_str()); + return -1; + } + + return 0; +} + + + +void pnf_sim_trace(nfapi_trace_level_t level, const char* message, ...) +{ + va_list args; + va_start(args, message); + vprintf(message, args); + va_end(args); +} + +void set_thread_priority(int priority) +{ + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) + { + printf("failed to set SCHED_RR\n"); + } + + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) + { + printf("failed to set pthread SCHED_RR %d\n", errno); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) + { + printf("failed to set sched param\n"); + } +} + + +void* pnf_p7_thread_start(void* ptr) +{ + set_thread_priority(79); + + nfapi_pnf_p7_config_t* config = (nfapi_pnf_p7_config_t*)ptr; + nfapi_pnf_p7_start(config); + + return 0; +} + + + +int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req) +{ + printf("[PNF_SIM] pnf param request\n"); + + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + + pnf_info* pnf = (pnf_info*)(config->user_data); + + resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode; + resp.pnf_param_general.location_mode = pnf->location_mode; + //uint8_t location_coordinates[NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH]; + resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing; + resp.pnf_param_general.tx_timing = pnf->tx_timing; + resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing; + resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing; + resp.pnf_param_general.maximum_number_phys = pnf->max_phys; + resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw; + resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers; + resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers; + resp.pnf_param_general.shared_bands = pnf->shared_bands; + resp.pnf_param_general.shared_pa = pnf->shared_pa; + resp.pnf_param_general.maximum_total_power = pnf->max_total_power; + //uint8_t oui[NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH]; + + resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + resp.pnf_phy.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support; + resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support; + resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + + resp.pnf_phy.phy[i].number_of_rfs = pnf->phys[i].rfs.size(); + for(int j = 0; j < pnf->phys[i].rfs.size(); ++j) + { + resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + resp.pnf_phy.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size(); + for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j) + { + resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + } + + + resp.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG; + resp.pnf_rf.number_of_rfs = pnf->rfs.size(); + + for(int i = 0; i < pnf->rfs.size(); ++i) + { + resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; + resp.pnf_rf.rf[i].band = pnf->rfs[i].band; + resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; + resp.pnf_rf.rf[i].minimum_transmit_power = pnf->rfs[i].min_transmit_power; + resp.pnf_rf.rf[i].number_of_antennas_suppported = pnf->rfs[i].num_antennas_supported; + resp.pnf_rf.rf[i].minimum_downlink_frequency = pnf->rfs[i].min_downlink_frequency; + resp.pnf_rf.rf[i].maximum_downlink_frequency = pnf->rfs[i].max_downlink_frequency; + resp.pnf_rf.rf[i].minimum_uplink_frequency = pnf->rfs[i].min_uplink_frequency; + resp.pnf_rf.rf[i].maximum_uplink_frequency = pnf->rfs[i].max_uplink_frequency; + } + + if(pnf->release >= 10) + { + resp.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; + resp.pnf_phy_rel10.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel10.phy[i].transmission_mode_7_supported = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_8_supported = 1; + resp.pnf_phy_rel10.phy[i].two_antenna_ports_for_pucch = 0; + resp.pnf_phy_rel10.phy[i].transmission_mode_9_supported = 1; + resp.pnf_phy_rel10.phy[i].simultaneous_pucch_pusch = 0; + resp.pnf_phy_rel10.phy[i].four_layer_tx_with_tm3_and_tm4 = 1; + + } + } + + if(pnf->release >= 11) + { + resp.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG; + resp.pnf_phy_rel11.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel11.phy[i].edpcch_supported = 0; + resp.pnf_phy_rel11.phy[i].multi_ack_csi_reporting = 1; + resp.pnf_phy_rel11.phy[i].pucch_tx_diversity = 0; + resp.pnf_phy_rel11.phy[i].ul_comp_supported = 1; + resp.pnf_phy_rel11.phy[i].transmission_mode_5_supported = 0; + } + } + + if(pnf->release >= 12) + { + resp.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG; + resp.pnf_phy_rel12.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel12.phy[i].csi_subframe_set = 0; + resp.pnf_phy_rel12.phy[i].enhanced_4tx_codebook = 2; // yes this is invalid + resp.pnf_phy_rel12.phy[i].drs_supported = 0; + resp.pnf_phy_rel12.phy[i].ul_64qam_supported = 1; + resp.pnf_phy_rel12.phy[i].transmission_mode_10_supported = 0; + resp.pnf_phy_rel12.phy[i].alternative_bts_indices = 1; + } + } + + if(pnf->release >= 13) + { + resp.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG; + resp.pnf_phy_rel13.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel13.phy[i].pucch_format4_supported = 0; + resp.pnf_phy_rel13.phy[i].pucch_format5_supported = 1; + resp.pnf_phy_rel13.phy[i].more_than_5_ca_support = 0; + resp.pnf_phy_rel13.phy[i].laa_supported = 1; + resp.pnf_phy_rel13.phy[i].laa_ending_in_dwpts_supported = 0; + resp.pnf_phy_rel13.phy[i].laa_starting_in_second_slot_supported = 1; + resp.pnf_phy_rel13.phy[i].beamforming_supported = 0; + resp.pnf_phy_rel13.phy[i].csi_rs_enhancement_supported = 1; + resp.pnf_phy_rel13.phy[i].drms_enhancement_supported = 0; + resp.pnf_phy_rel13.phy[i].srs_enhancement_supported = 1; + } + + resp.pnf_phy_rel13_nb_iot.tl.tag = NFAPI_PNF_PHY_REL13_NB_IOT_TAG; + resp.pnf_phy_rel13_nb_iot.number_of_phys = pnf->phys.size(); + + for(int i = 0; i < pnf->phys.size(); ++i) + { + resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = pnf->phys[i].rfs.size(); + for(int j = 0; j < pnf->phys[i].rfs.size(); ++j) + { + resp.pnf_phy_rel13_nb_iot.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size(); + for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j) + { + resp.pnf_phy_rel13_nb_iot.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy_rel13_nb_iot.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + + } + } + + + nfapi_pnf_pnf_param_resp(config, &resp); + + return 0; +} + +int pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req) +{ + printf("[PNF_SIM] pnf config request\n"); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + for(int i = 0; i < req->pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.index == req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index; }); + + if(found != pnf->phys.end()) + { + phy_info& phy = (*found); + phy.id = req->pnf_phy_rf_config.phy_rf_config[i].phy_id; + printf("[PNF_SIM] pnf config request assigned phy_id %d to phy_config_index %d\n", phy.id, req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index); + } + else + { + // did not find the phy + printf("[PNF_SIM] pnf config request did not find phy_config_index %d\n", req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index); + } + + } + + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_config_resp(config, &resp); + + return 0; +} + +int fapi_param_response(fapi_t* fapi, fapi_param_resp_t* resp) +{ + printf("[PNF_SIM] fapi param response\n"); + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_param_response_t nfapi_resp; + + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE; + nfapi_resp.header.phy_id = data->phy_id; + nfapi_resp.error_code = resp->error_code; + + for(int i = 0; i < resp->number_of_tlvs; ++i) + { + switch(resp->tlvs[i].tag) + { + case FAPI_PHY_STATE_TAG: + nfapi_resp.l1_status.phy_state.tl.tag = NFAPI_L1_STATUS_PHY_STATE_TAG; + nfapi_resp.l1_status.phy_state.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + break; + + case FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG: + nfapi_resp.phy_capabilities.dl_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG; + nfapi_resp.phy_capabilities.dl_bandwidth_support.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + break; + + case FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG: + nfapi_resp.phy_capabilities.ul_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG; + nfapi_resp.phy_capabilities.ul_bandwidth_support.value = resp->tlvs[i].value; + nfapi_resp.num_tlv++; + break; + } + } + + if(1) + { + // just code to populate all the tlv for testing with wireshark + // todo : these should be move up so that they are populated by fapi + + nfapi_resp.phy_capabilities.dl_modulation_support.tl.tag = NFAPI_PHY_CAPABILITIES_DL_MODULATION_SUPPORT_TAG; + nfapi_resp.phy_capabilities.dl_modulation_support.value = rand_range(0, 0x0F); + nfapi_resp.num_tlv++; + nfapi_resp.phy_capabilities.ul_modulation_support.tl.tag = NFAPI_PHY_CAPABILITIES_UL_MODULATION_SUPPORT_TAG; + nfapi_resp.phy_capabilities.ul_modulation_support.value = rand_range(0, 0x07); + nfapi_resp.num_tlv++; + nfapi_resp.phy_capabilities.phy_antenna_capability.tl.tag = NFAPI_PHY_CAPABILITIES_PHY_ANTENNA_CAPABILITY_TAG; + nfapi_resp.phy_capabilities.phy_antenna_capability.value = phy_antenna_capability_values[rand_range(0, 4)]; + nfapi_resp.num_tlv++; + nfapi_resp.phy_capabilities.release_capability.tl.tag = NFAPI_PHY_CAPABILITIES_RELEASE_CAPABILITY_TAG; + nfapi_resp.phy_capabilities.release_capability.value = rand_range(0, 0x3F); + nfapi_resp.num_tlv++; + nfapi_resp.phy_capabilities.mbsfn_capability.tl.tag = NFAPI_PHY_CAPABILITIES_MBSFN_CAPABILITY_TAG; + nfapi_resp.phy_capabilities.mbsfn_capability.value = rand_range(0, 1); + nfapi_resp.num_tlv++; + + + nfapi_resp.laa_capability.laa_support.tl.tag = NFAPI_LAA_CAPABILITY_LAA_SUPPORT_TAG; + nfapi_resp.laa_capability.laa_support.value = rand_range(0, 1); + nfapi_resp.num_tlv++; + nfapi_resp.laa_capability.pd_sensing_lbt_support.tl.tag = NFAPI_LAA_CAPABILITY_PD_SENSING_LBT_SUPPORT_TAG; + nfapi_resp.laa_capability.pd_sensing_lbt_support.value = rand_range(0, 1); + nfapi_resp.num_tlv++; + nfapi_resp.laa_capability.multi_carrier_lbt_support.tl.tag = NFAPI_LAA_CAPABILITY_MULTI_CARRIER_LBT_SUPPORT_TAG; + nfapi_resp.laa_capability.multi_carrier_lbt_support.value = rand_range(0, 0x0F); + nfapi_resp.num_tlv++; + nfapi_resp.laa_capability.partial_sf_support.tl.tag = NFAPI_LAA_CAPABILITY_PARTIAL_SF_SUPPORT_TAG; + nfapi_resp.laa_capability.partial_sf_support.value = rand_range(0, 1); + nfapi_resp.num_tlv++; + + nfapi_resp.nb_iot_capability.nb_iot_support.tl.tag = NFAPI_LAA_CAPABILITY_NB_IOT_SUPPORT_TAG; + nfapi_resp.nb_iot_capability.nb_iot_support.value = rand_range(0, 2); + nfapi_resp.num_tlv++; + nfapi_resp.nb_iot_capability.nb_iot_operating_mode_capability.tl.tag = NFAPI_LAA_CAPABILITY_NB_IOT_OPERATING_MODE_CAPABILITY_TAG; + nfapi_resp.nb_iot_capability.nb_iot_operating_mode_capability.value = rand_range(0, 1); + nfapi_resp.num_tlv++; + + nfapi_resp.subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.l23_config.data_report_mode.tl.tag = NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.l23_config.sfnsf.tl.tag = NFAPI_L23_CONFIG_SFNSF_TAG; + nfapi_resp.num_tlv++; + } + + + { + //if(phy->state == NFAPI_PNF_PHY_IDLE) + //if(nfapi_resp.l1_status.phy_state.value == NFAPI_PNF_PHY_IDLE) + { + // -- NFAPI + // Downlink UEs per Subframe + nfapi_resp.nfapi_config.dl_ue_per_sf.tl.tag = NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.nfapi_config.dl_ue_per_sf.value = data->phy->dl_ues_per_subframe; + nfapi_resp.num_tlv++; + // Uplink UEs per Subframe + nfapi_resp.nfapi_config.ul_ue_per_sf.tl.tag = NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.nfapi_config.ul_ue_per_sf.value = data->phy->ul_ues_per_subframe; + nfapi_resp.num_tlv++; + // nFAPI RF Bands + nfapi_resp.nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + nfapi_resp.nfapi_config.rf_bands.number_rf_bands = 2; + nfapi_resp.nfapi_config.rf_bands.rf_band[0] = 23; + nfapi_resp.nfapi_config.rf_bands.rf_band[1] = 7; + + // P7 PNF Address IPv4 + nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + struct sockaddr_in pnf_p7_sockaddr; + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(data->phy->local_addr.c_str()); + memcpy(&(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address[0]), &pnf_p7_sockaddr.sin_addr.s_addr, 4); + nfapi_resp.num_tlv++; + // P7 PNF Address IPv6 + // P7 PNF Port + nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + nfapi_resp.nfapi_config.p7_pnf_port.value = data->phy->local_port; + nfapi_resp.num_tlv++; + // NMM GSM Frequency Bands + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM UMTS Frequency Bands + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_umts_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM LTE Frequency Bands + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG; + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands = 1; + nfapi_resp.nfapi_config.nmm_lte_frequency_bands.bands[0] = 23; + nfapi_resp.num_tlv++; + // NMM Uplink RSSI supported + nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.tl.tag = NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG; + nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.value = 1; + nfapi_resp.num_tlv++; + + } + } + + + + nfapi_pnf_param_resp(data->config, &nfapi_resp); + + return 0; +} + +int fapi_config_response(fapi_t* fapi, fapi_config_resp_t* resp) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_config_response_t nfapi_resp; + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_CONFIG_RESPONSE; + nfapi_resp.header.phy_id = data->phy_id; + nfapi_resp.error_code = resp->error_code; + nfapi_pnf_config_resp(data->config, &nfapi_resp); + + return 0; +} + +int fapi_subframe_ind(fapi_t* fapi, fapi_subframe_ind_t* resp) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + if(data->phy->first_subframe_ind == 0) + { + printf("Sending nfapi_pnf_start_resp phy_id:%d\n", data->phy_id); + nfapi_start_response_t start_resp; + memset(&start_resp, 0, sizeof(start_resp)); + start_resp.header.message_id = NFAPI_START_RESPONSE; + start_resp.header.phy_id = data->phy_id; + start_resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_start_resp(data->config, &start_resp); + + data->phy->first_subframe_ind = 1; + + if(data->phy->udp.enabled) + { + fapi_start_data(fapi, + data->phy->udp.rx_port, + data->phy->udp.tx_addr.c_str(), + data->phy->udp.tx_port); + } + + } + + + nfapi_pnf_p7_subframe_ind(data->p7_config, data->phy_id, resp->sfn_sf); + + return 0; + +} + +int fapi_harq_ind(fapi_t* fapi, fapi_harq_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_harq_indication_t harq_ind; + memset(&harq_ind, 0, sizeof(harq_ind)); + harq_ind.header.message_id = NFAPI_HARQ_INDICATION; + harq_ind.header.phy_id = data->p7_config->phy_id; + harq_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + harq_ind.harq_indication_body.number_of_harqs = 1; + + nfapi_harq_indication_pdu_t pdus[harq_ind.harq_indication_body.number_of_harqs]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[0].rx_ue_information.handle = rand_range(0, 9999); + pdus[0].rx_ue_information.rnti = rand_range(1, 65535); + + + + pdus[0].harq_indication_tdd_rel8.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL8_TAG; + pdus[0].harq_indication_tdd_rel8.mode = rand_range(0, 4); + pdus[0].harq_indication_tdd_rel8.number_of_ack_nack = rand_range(1, 4); + + switch(pdus[0].harq_indication_tdd_rel8.mode) + { + case 0: + { + pdus[0].harq_indication_tdd_rel8.harq_data.bundling.value_0 = rand_range(1, 7); + pdus[0].harq_indication_tdd_rel8.harq_data.bundling.value_1 = rand_range(1, 7); + } + break; + case 1: + { + pdus[0].harq_indication_tdd_rel8.harq_data.multiplex.value_0 = rand_range(1, 7); + pdus[0].harq_indication_tdd_rel8.harq_data.multiplex.value_1 = rand_range(1, 7); + pdus[0].harq_indication_tdd_rel8.harq_data.multiplex.value_2 = rand_range(1, 7); + pdus[0].harq_indication_tdd_rel8.harq_data.multiplex.value_3 = rand_range(1, 7); + } + break; + case 2: + { + pdus[0].harq_indication_tdd_rel8.harq_data.special_bundling.value_0 = rand_range(1, 7); + } + break; + }; + + + pdus[0].harq_indication_tdd_rel9.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL9_TAG; + pdus[0].harq_indication_tdd_rel9.mode = rand_range(0, 4); + pdus[0].harq_indication_tdd_rel9.number_of_ack_nack = 1; + + switch(pdus[0].harq_indication_tdd_rel9.mode) + { + case 0: + { + pdus[0].harq_indication_tdd_rel9.harq_data[0].bundling.value_0 = rand_range(1, 7); + } + break; + case 1: + { + pdus[0].harq_indication_tdd_rel9.harq_data[0].multiplex.value_0 = rand_range(1, 7); + } + break; + case 2: + { + pdus[0].harq_indication_tdd_rel9.harq_data[0].special_bundling.value_0 = rand_range(1, 7); + } + break; + case 3: + { + pdus[0].harq_indication_tdd_rel9.harq_data[0].channel_selection.value_0 = rand_range(1, 7); + } + break; + case 4: + { + pdus[0].harq_indication_tdd_rel9.harq_data[0].format_3.value_0 = rand_range(1, 7); + } + break; + }; + + + + pdus[0].harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdus[0].harq_indication_tdd_rel13.mode = rand_range(0, 6); + pdus[0].harq_indication_tdd_rel13.number_of_ack_nack = 1; + + switch(pdus[0].harq_indication_tdd_rel13.mode) + { + case 0: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = rand_range(1, 7); + } + break; + case 1: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = rand_range(1, 7); + } + break; + case 2: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].special_bundling.value_0 = rand_range(1, 7); + } + break; + case 3: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].channel_selection.value_0 = rand_range(1, 7); + } + break; + case 4: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].format_3.value_0 = rand_range(1, 7); + } + break; + case 5: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].format_4.value_0 = rand_range(1, 7); + } + break; + case 6: + { + pdus[0].harq_indication_tdd_rel13.harq_data[0].format_5.value_0 = rand_range(1, 7); + } + break; + }; + + pdus[0].harq_indication_fdd_rel8.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL8_TAG; + pdus[0].harq_indication_fdd_rel8.harq_tb1 = rand_range(1, 7); + pdus[0].harq_indication_fdd_rel8.harq_tb2 = rand_range(1, 7); + + pdus[0].harq_indication_fdd_rel9.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL9_TAG; + pdus[0].harq_indication_fdd_rel9.mode = rand_range(0, 2); + pdus[0].harq_indication_fdd_rel9.number_of_ack_nack = 2; + pdus[0].harq_indication_fdd_rel9.harq_tb_n[0] = rand_range(1, 7); + pdus[0].harq_indication_fdd_rel9.harq_tb_n[1] = rand_range(1, 7); + + pdus[0].harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; + pdus[0].harq_indication_fdd_rel13.mode = rand_range(0, 2); + pdus[0].harq_indication_fdd_rel13.number_of_ack_nack = 2; + pdus[0].harq_indication_fdd_rel13.harq_tb_n[0] = rand_range(1, 7); + pdus[0].harq_indication_fdd_rel13.harq_tb_n[1] = rand_range(1, 7); + + pdus[0].ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + pdus[0].ul_cqi_information.ul_cqi = rand_range(0,255); + pdus[0].ul_cqi_information.channel = rand_range(0, 1); + + harq_ind.harq_indication_body.harq_pdu_list = pdus; + + nfapi_pnf_p7_harq_ind(data->p7_config, &harq_ind); + } + else + { + + harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + harq_ind.harq_indication_body.number_of_harqs = 8; + + nfapi_harq_indication_pdu_t pdus[8]; + memset(&pdus, 0, sizeof(pdus)); + + for(int i = 0; i < 8; ++i) + { + pdus[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[i].rx_ue_information.handle = 0xFF; + pdus[i].rx_ue_information.rnti = i; + + pdus[i].harq_indication_fdd_rel8.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL8_TAG; + pdus[i].harq_indication_fdd_rel8.harq_tb1 = 1; + pdus[i].harq_indication_fdd_rel8.harq_tb2 = 2; + } + + harq_ind.harq_indication_body.harq_pdu_list = pdus; + + nfapi_pnf_p7_harq_ind(data->p7_config, &harq_ind); + } + + return 0; +} + +int fapi_crc_ind(fapi_t* fapi, fapi_crc_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_crc_indication_t crc_ind; + memset(&crc_ind, 0, sizeof(crc_ind)); + crc_ind.header.message_id = NFAPI_CRC_INDICATION; + crc_ind.header.phy_id = data->p7_config->phy_id; + crc_ind.sfn_sf = ind->sfn_sf; + + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; + crc_ind.crc_indication_body.number_of_crcs = 1; + + nfapi_crc_indication_pdu_t pdus[crc_ind.crc_indication_body.number_of_crcs]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[0].rx_ue_information.handle = rand_range(0, 9999); + pdus[0].rx_ue_information.rnti = rand_range(1, 65535); + + pdus[0].crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + pdus[0].crc_indication_rel8.crc_flag = rand_range(0, 1); + + crc_ind.crc_indication_body.crc_pdu_list = pdus; + nfapi_pnf_p7_crc_ind(data->p7_config, &crc_ind); + } + else + { + crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; + crc_ind.crc_indication_body.number_of_crcs = ind->body.number_of_crcs; + + crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(sizeof(nfapi_crc_indication_pdu_t) * ind->body.number_of_crcs); + + for(int i = 0; i < ind->body.number_of_crcs; ++i) + { + crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.handle = ind->body.pdus[i].rx_ue_info.handle; + crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti = ind->body.pdus[i].rx_ue_info.rnti; + crc_ind.crc_indication_body.crc_pdu_list[i].crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; + crc_ind.crc_indication_body.crc_pdu_list[i].crc_indication_rel8.crc_flag = ind->body.pdus[i].rel8_pdu.crc_flag; + } + + nfapi_pnf_p7_crc_ind(data->p7_config, &crc_ind); + + free(crc_ind.crc_indication_body.crc_pdu_list); + } + + return 0; +} +int fapi_rx_ulsch_ind(fapi_t* fapi, fapi_rx_ulsch_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_rx_indication_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = NFAPI_RX_ULSCH_INDICATION; + rx_ind.header.phy_id = data->p7_config->phy_id; + rx_ind.sfn_sf = ind->sfn_sf; + + if(1)//((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + rx_ind.rx_indication_body.number_of_pdus = 1; + + uint8_t rx_data[1024]; + + nfapi_rx_indication_pdu_t pdus[rx_ind.rx_indication_body.number_of_pdus]; + memset(&pdus, 0, sizeof(pdus)); + + strcpy((char*)rx_data, (char*)"123456789"); + + for(int i = 0; i < rx_ind.rx_indication_body.number_of_pdus;++i) + { + + pdus[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[i].rx_ue_information.handle = rand_range(0, 9999); + pdus[i].rx_ue_information.rnti = rand_range(1, 65535); + + pdus[i].rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + pdus[i].rx_indication_rel8.length = 10;//rand_range(0, 1024); + pdus[i].rx_indication_rel8.offset = 0;//djp - 1; + pdus[i].rx_indication_rel8.ul_cqi = rand_range(0, 255); + pdus[i].rx_indication_rel8.timing_advance = rand_range(0, 63); + + //pdus[i].rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; + //pdus[i].rx_indication_rel9.timing_advance_r9 = rand_range(0, 7690); + + pdus[i].data = &rx_data[0]; + } + + rx_ind.rx_indication_body.rx_pdu_list = pdus; + + nfapi_pnf_p7_rx_ind(data->p7_config, &rx_ind); + } + else + { + + rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + rx_ind.rx_indication_body.number_of_pdus = ind->body.number_of_pdus; + + rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(sizeof(nfapi_rx_indication_pdu_t) * ind->body.number_of_pdus); + + for(int i = 0; i < ind->body.number_of_pdus; ++i) + { + rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.handle = ind->body.pdus[i].rx_ue_info.handle; + rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length = ind->body.pdus[i].rel8_pdu.length; + rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.offset = 1; + rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel9.tl.tag = 0; + rx_ind.rx_indication_body.rx_pdu_list[i].data = (uint8_t*)ind->body.data[i]; + + } + + nfapi_pnf_p7_rx_ind(data->p7_config, &rx_ind); + + free(rx_ind.rx_indication_body.rx_pdu_list); + } + + return 0; + +} +int fapi_rx_cqi_ind(fapi_t* fapi, fapi_rx_cqi_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_cqi_indication_t cqi_ind; + memset(&cqi_ind, 0, sizeof(cqi_ind)); + cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION; + cqi_ind.header.phy_id = data->p7_config->phy_id; + cqi_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; + cqi_ind.cqi_indication_body.number_of_cqis = 3; + + nfapi_cqi_indication_pdu_t cqi_pdu_list[cqi_ind.cqi_indication_body.number_of_cqis]; + memset(&cqi_pdu_list, 0, sizeof(cqi_pdu_list)); + nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[cqi_ind.cqi_indication_body.number_of_cqis]; + //memset(&cqi_raw_pdu_list, 0, sizeof(cqi_raw_pdu_list)); + + + for(int i = 0; i < cqi_ind.cqi_indication_body.number_of_cqis; ++i) + { + cqi_pdu_list[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + cqi_pdu_list[i].rx_ue_information.handle = rand_range(0, 9999); + cqi_pdu_list[i].rx_ue_information.rnti = rand_range(1, 65535); + + uint8_t rel8_or_9 = rand_range(0, 1); + + if(rel8_or_9) + { + cqi_pdu_list[i].cqi_indication_rel8.tl.tag = NFAPI_CQI_INDICATION_REL8_TAG; + cqi_pdu_list[i].cqi_indication_rel8.length = 8; //rand_range(1, 12); + cqi_pdu_list[i].cqi_indication_rel8.data_offset = 1; //rand_range(0, 1); + cqi_pdu_list[i].cqi_indication_rel8.ul_cqi = 0; + cqi_pdu_list[i].cqi_indication_rel8.ri = rand_range(0, 4); + cqi_pdu_list[i].cqi_indication_rel8.timing_advance = rand_range(0, 63); + } + else + { + cqi_pdu_list[i].cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG; + cqi_pdu_list[i].cqi_indication_rel9.length = 8; //rand_range(1, 12); + cqi_pdu_list[i].cqi_indication_rel9.data_offset = 1; //rand_range(0, 1); + cqi_pdu_list[i].cqi_indication_rel9.ul_cqi = 0; //rand_range(0, 1); + cqi_pdu_list[i].cqi_indication_rel9.number_of_cc_reported = 1; + cqi_pdu_list[i].cqi_indication_rel9.ri[0] = rand_range(0, 8); + cqi_pdu_list[i].cqi_indication_rel9.timing_advance = rand_range(0, 63); + cqi_pdu_list[i].cqi_indication_rel9.timing_advance_r9 = rand_range(0, 7690); + } + + cqi_pdu_list[i].ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + cqi_pdu_list[i].ul_cqi_information.ul_cqi = rand_range(0,255); + cqi_pdu_list[i].ul_cqi_information.channel = rand_range(0, 1); + } + + cqi_ind.cqi_indication_body.cqi_pdu_list = cqi_pdu_list; + cqi_ind.cqi_indication_body.cqi_raw_pdu_list = cqi_raw_pdu_list; + + nfapi_pnf_p7_cqi_ind(data->p7_config, &cqi_ind); + } + else + { + nfapi_pnf_p7_cqi_ind(data->p7_config, &cqi_ind); + } + + return 0; +} +int fapi_rx_sr_ind(fapi_t* fapi, fapi_rx_sr_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_sr_indication_t sr_ind; + memset(&sr_ind, 0, sizeof(sr_ind)); + sr_ind.header.message_id = NFAPI_RX_SR_INDICATION; + sr_ind.header.phy_id = data->p7_config->phy_id; + sr_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + sr_ind.sr_indication_body.tl.tag = NFAPI_SR_INDICATION_BODY_TAG; + sr_ind.sr_indication_body.number_of_srs = 1; + + nfapi_sr_indication_pdu_t pdus[sr_ind.sr_indication_body.number_of_srs]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[0].rx_ue_information.handle = rand_range(0, 9999); + pdus[0].rx_ue_information.rnti = rand_range(1, 65535); + + pdus[0].ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + pdus[0].ul_cqi_information.ul_cqi = rand_range(0,255); + pdus[0].ul_cqi_information.channel = rand_range(0, 1); + + sr_ind.sr_indication_body.sr_pdu_list = pdus; + + nfapi_pnf_p7_sr_ind(data->p7_config, &sr_ind); + } + else + { + nfapi_pnf_p7_sr_ind(data->p7_config, &sr_ind); + } + + return 0; +} + +int fapi_rach_ind(fapi_t* fapi, fapi_rach_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_rach_indication_t rach_ind; + memset(&rach_ind, 0, sizeof(rach_ind)); + rach_ind.header.message_id = NFAPI_RACH_INDICATION; + rach_ind.header.phy_id = data->p7_config->phy_id; + rach_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + rach_ind.rach_indication_body.number_of_preambles = 1; + + nfapi_preamble_pdu_t pdus[rach_ind.rach_indication_body.number_of_preambles]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; + pdus[0].preamble_rel8.rnti = rand_range(1, 65535); + pdus[0].preamble_rel8.preamble = rand_range(0, 63); + pdus[0].preamble_rel8.timing_advance = rand_range(0, 1282); + pdus[0].preamble_rel9.tl.tag = NFAPI_PREAMBLE_REL9_TAG; + pdus[0].preamble_rel9.timing_advance_r9 = rand_range(0, 7690); + pdus[0].preamble_rel13.tl.tag = NFAPI_PREAMBLE_REL13_TAG; + pdus[0].preamble_rel13.rach_resource_type = rand_range(0, 4); + + rach_ind.rach_indication_body.preamble_list = pdus; + nfapi_pnf_p7_rach_ind(data->p7_config, &rach_ind); + } + else + { + nfapi_pnf_p7_rach_ind(data->p7_config, &rach_ind); + } + + return 0; +} + +int fapi_srs_ind(fapi_t* fapi, fapi_srs_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_srs_indication_t srs_ind; + memset(&srs_ind, 0, sizeof(srs_ind)); + srs_ind.header.message_id = NFAPI_SRS_INDICATION; + srs_ind.header.phy_id = data->p7_config->phy_id; + srs_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + srs_ind.srs_indication_body.tl.tag = NFAPI_SRS_INDICATION_BODY_TAG; + srs_ind.srs_indication_body.number_of_ues = 1; + + nfapi_srs_indication_pdu_t pdus[srs_ind.srs_indication_body.number_of_ues]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[0].rx_ue_information.handle = rand_range(0, 9999); + pdus[0].rx_ue_information.rnti = rand_range(1, 65535); + + pdus[0].srs_indication_fdd_rel8.tl.tag = NFAPI_SRS_INDICATION_FDD_REL8_TAG; + pdus[0].srs_indication_fdd_rel8.doppler_estimation = rand_range(0, 255); + pdus[0].srs_indication_fdd_rel8.timing_advance = rand_range(0, 63); + pdus[0].srs_indication_fdd_rel8.number_of_resource_blocks = 2; //rand_range(0, 255); + pdus[0].srs_indication_fdd_rel8.rb_start = rand_range(0, 245); + pdus[0].srs_indication_fdd_rel8.snr[0] = rand_range(0, 255); + pdus[0].srs_indication_fdd_rel8.snr[1] = rand_range(0, 255); + + pdus[0].srs_indication_fdd_rel9.tl.tag = NFAPI_SRS_INDICATION_FDD_REL9_TAG; + pdus[0].srs_indication_fdd_rel9.timing_advance_r9 = rand_range(0, 7690); + + pdus[0].srs_indication_tdd_rel10.tl.tag = NFAPI_SRS_INDICATION_TDD_REL10_TAG; + pdus[0].srs_indication_tdd_rel10.uppts_symbol = rand_range(0, 1); + + pdus[0].srs_indication_fdd_rel11.tl.tag = NFAPI_SRS_INDICATION_FDD_REL11_TAG; + pdus[0].srs_indication_fdd_rel11.ul_rtoa; + + pdus[0].tdd_channel_measurement.tl.tag = NFAPI_TDD_CHANNEL_MEASUREMENT_TAG; + pdus[0].tdd_channel_measurement.num_prb_per_subband = rand_range(0, 255); + pdus[0].tdd_channel_measurement.number_of_subbands = 1; + pdus[0].tdd_channel_measurement.num_atennas = 2; + pdus[0].tdd_channel_measurement.subands[0].subband_index = rand_range(0, 255); + pdus[0].tdd_channel_measurement.subands[0].channel[0] = rand_range(0, 9999); + pdus[0].tdd_channel_measurement.subands[0].channel[1] = rand_range(0, 9999); + + srs_ind.srs_indication_body.srs_pdu_list = pdus; + nfapi_pnf_p7_srs_ind(data->p7_config, &srs_ind); + } + else + { + nfapi_pnf_p7_srs_ind(data->p7_config, &srs_ind); + } + + return 0; +} + +int fapi_lbt_dl_ind(fapi_t* fapi, fapi_lbt_dl_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_lbt_dl_indication_t lbt_dl_ind; + memset(&lbt_dl_ind, 0, sizeof(lbt_dl_ind)); + lbt_dl_ind.header.message_id = NFAPI_LBT_DL_INDICATION; + lbt_dl_ind.header.phy_id = data->p7_config->phy_id; + lbt_dl_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + lbt_dl_ind.lbt_dl_indication_body.tl.tag = NFAPI_LBT_DL_INDICATION_BODY_TAG; + lbt_dl_ind.lbt_dl_indication_body.number_of_pdus = 2; + + nfapi_lbt_dl_indication_pdu_t pdus[lbt_dl_ind.lbt_dl_indication_body.number_of_pdus]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].pdu_type = 0; // LBT_PDSCH_RSP PDU + pdus[0].pdu_size = 0; + pdus[0].lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13.tl.tag = NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG; + pdus[0].lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13.handle = 0xABCD; + pdus[0].lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13.result = rand_range(0, 1); + pdus[0].lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13.lte_txop_symbols = rand_range(0, 0xFFFF); + pdus[0].lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13.initial_partial_sf = rand_range(0, 1); + + pdus[1].pdu_type = 1; // LBT_DRS_RSP PDU + pdus[1].pdu_size = 0; + pdus[1].lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13.tl.tag = NFAPI_LBT_DRS_RSP_PDU_REL13_TAG; + pdus[1].lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13.handle = 0xABCD; + pdus[1].lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13.result = rand_range(0, 1); + + lbt_dl_ind.lbt_dl_indication_body.lbt_indication_pdu_list = pdus; + nfapi_pnf_p7_lbt_dl_ind(data->p7_config, &lbt_dl_ind); + } + else + { + nfapi_pnf_p7_lbt_dl_ind(data->p7_config, &lbt_dl_ind); + } + + return 0; +} + +int fapi_nb_harq_ind(fapi_t* fapi, fapi_nb_harq_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_nb_harq_indication_t nb_harq_ind; + memset(&nb_harq_ind, 0, sizeof(nb_harq_ind)); + nb_harq_ind.header.message_id = NFAPI_NB_HARQ_INDICATION; + nb_harq_ind.header.phy_id = data->p7_config->phy_id; + nb_harq_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + + nb_harq_ind.nb_harq_indication_body.tl.tag = NFAPI_NB_HARQ_INDICATION_BODY_TAG; + nb_harq_ind.nb_harq_indication_body.number_of_harqs = 1; + + nfapi_nb_harq_indication_pdu_t pdus[nb_harq_ind.nb_harq_indication_body.number_of_harqs]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + pdus[0].rx_ue_information.handle = rand_range(0, 0xFFFF); + pdus[0].rx_ue_information.rnti = rand_range(0, 65535); + + pdus[0].nb_harq_indication_fdd_rel13.tl.tag = NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG; + pdus[0].nb_harq_indication_fdd_rel13.harq_tb1 = rand_range(1, 7); + + pdus[0].ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + pdus[0].ul_cqi_information.ul_cqi = rand_range(0, 255); + pdus[0].ul_cqi_information.channel = rand_range(0, 1); + + nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list = pdus; + nfapi_pnf_p7_nb_harq_ind(data->p7_config, &nb_harq_ind); + } + else + { + nfapi_pnf_p7_nb_harq_ind(data->p7_config, &nb_harq_ind); + } + + return 0; +} + +int fapi_nrach_ind(fapi_t* fapi, fapi_nrach_ind_t* ind) +{ + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data); + + nfapi_nrach_indication_t nrach_ind; + memset(&nrach_ind, 0, sizeof(nrach_ind)); + nrach_ind.header.message_id = NFAPI_NRACH_INDICATION; + nrach_ind.header.phy_id = data->p7_config->phy_id; + nrach_ind.sfn_sf = ind->sfn_sf; + + if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + nrach_ind.nrach_indication_body.tl.tag = NFAPI_NRACH_INDICATION_BODY_TAG; + nrach_ind.nrach_indication_body.number_of_initial_scs_detected = 1; + + nfapi_nrach_indication_pdu_t pdus[nrach_ind.nrach_indication_body.number_of_initial_scs_detected]; + memset(&pdus, 0, sizeof(pdus)); + + pdus[0].nrach_indication_rel13.tl.tag = NFAPI_NRACH_INDICATION_REL13_TAG; + pdus[0].nrach_indication_rel13.rnti = rand_range(1, 65535); + pdus[0].nrach_indication_rel13.initial_sc = rand_range(0, 47); + pdus[0].nrach_indication_rel13.timing_advance = rand_range(0, 3840); + pdus[0].nrach_indication_rel13.nrach_ce_level = rand_range(0, 2); + + nrach_ind.nrach_indication_body.nrach_pdu_list = pdus; + + nfapi_pnf_p7_nrach_ind(data->p7_config, &nrach_ind); + } + else + { + nfapi_pnf_p7_nrach_ind(data->p7_config, &nrach_ind); + } + + return 0; +} + +int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req) +{ + + pnf_info* pnf = (pnf_info*)(config->user_data); + + // start all phys that have been configured + for(phy_info& phy : pnf->phys) + { + if(phy.id != 0) + { + //auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + // { return item.id == req->header.phy_id; }); +// +// if(found != pnf->phys.end()) +// { +// phy_info& phy = (*found); + + fapi_cb_t cb; + cb.fapi_param_response = &fapi_param_response; + cb.fapi_config_response = &fapi_config_response; + cb.fapi_subframe_ind = &fapi_subframe_ind; + cb.fapi_harq_ind = fapi_harq_ind; + cb.fapi_crc_ind = fapi_crc_ind; + cb.fapi_rx_ulsch_ind = fapi_rx_ulsch_ind; + cb.fapi_rx_cqi_ind = fapi_rx_cqi_ind; + cb.fapi_rx_sr_ind = fapi_rx_sr_ind; + cb.fapi_rach_ind = fapi_rach_ind; + cb.fapi_srs_ind = fapi_srs_ind; + + cb.fapi_lbt_dl_ind = fapi_lbt_dl_ind; + cb.fapi_nb_harq_ind = fapi_nb_harq_ind; + cb.fapi_nrach_ind = fapi_nrach_ind; + + + + fapi_config_t c; + c.duplex_mode = phy.duplex_mode; + c.dl_channel_bw_support = phy.dl_channel_bw_support; + c.ul_channel_bw_support = phy.ul_channel_bw_support; + + phy.fapi = fapi_create(&cb, &c); + printf("[PNF_SIM] staring fapi %p phy_id:%d\n", phy.fapi, phy.id); + + pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)malloc(sizeof(pnf_phy_user_data_t)); + data->phy_id = phy.id; + data->config = config; + data->phy = &phy; + + phy.fapi->user_data = data; + } + + } + + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_start_resp(config, &resp); + + return 0; +} + +int pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req) +{ + printf("[PNF_SIM] pnf stop request\n"); + + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_pnf_stop_resp(config, &resp); + + return 0; +} + +int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req) +{ + printf("[PNF_SIM] param request phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) + { + phy_info& phy_info = (*found); + + fapi_param_req_t fapi_req; + fapi_req.header.message_id = req->header.message_id; + fapi_req.header.length = 0; + + // convert nfapi to fapi + + fapi_param_request(phy_info.fapi, &fapi_req); + + } + else + { + // did not find the phy + } + + + printf("[PNF_SIM] param request .. exit\n"); + + + return 0; +} + +int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req) +{ + printf("[PNF_SIM] config request phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) + { + phy_info& phy_info = (*found); + + + if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG) + { + phy_info.timing_window = req->nfapi_config.timing_window.value; + } + + if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NFAPI_TIMING_INFO_MODE_TAG) + { + printf("timing info mode provided\n"); + phy_info.timing_info_mode = req->nfapi_config.timing_info_mode.value; + } + else + { + phy_info.timing_info_mode = 0; + printf("NO timing info mode provided\n"); + } + + if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG) + { + printf("timing info period provided\n"); + phy_info.timing_info_period = req->nfapi_config.timing_info_period.value; + } + else + { + phy_info.timing_info_period = 0; + } + + phy_info.remote_port = req->nfapi_config.p7_vnf_port.value; + + struct sockaddr_in vnf_p7_sockaddr; + memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); + phy_info.remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); + + printf("[PNF_SIM] %d vnf p7 %s:%d timing %d %d %d\n", phy_info.id, phy_info.remote_addr, phy_info.remote_port, + phy_info.timing_window, phy_info.timing_info_mode, phy_info.timing_info_period); + + fapi_config_req_t fapi_req; + fapi_config_request(phy_info.fapi, &fapi_req); + } + + return 0; +} + +nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P7_VENDOR_EXT_REQ) + { + (*msg_size) = sizeof(vendor_ext_p7_req); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_req)); + } + + return 0; +} + +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) +{ + free(header); +} + +int phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) +{ + //printf("[PNF_SIM] dl config request\n"); + + if(req->vendor_extension) + free(req->vendor_extension); + + phy_info* phy = (phy_info*)(pnf_p7->user_data); + + fapi_dl_config_req_t fapi_req; + // convert + fapi_dl_config_request(phy->fapi, &fapi_req); + + return 0; +} +int phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) +{ + //printf("[PNF_SIM] ul config request\n"); + phy_info* phy = (phy_info*)(pnf_p7->user_data); + + fapi_ul_config_req_t fapi_req; + // convert + fapi_ul_config_request(phy->fapi, &fapi_req); + + return 0; +} +int phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) +{ + //printf("[PNF_SIM] hi dci0 request\n"); + phy_info* phy = (phy_info*)(pnf_p7->user_data); + + fapi_hi_dci0_req_t fapi_req; + // convert + fapi_hi_dci0_request(phy->fapi, &fapi_req); + return 0; +} +int phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) +{ + //printf("[PNF_SIM] tx request\n"); + phy_info* phy = (phy_info*)(pnf_p7->user_data); + + fapi_tx_req_t fapi_req; + fapi_req.header.message_id = FAPI_TX_REQUEST; + fapi_req.sfn_sf = req->sfn_sf; + fapi_req.body.number_of_pdus = req->tx_request_body.number_of_pdus; + + fapi_tx_req_pdu_t pdus[8]; + fapi_req.body.pdus = &pdus[0]; + + for(int i = 0; i < fapi_req.body.number_of_pdus; ++i) + { + fapi_req.body.pdus[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length; + fapi_req.body.pdus[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index; + fapi_req.body.pdus[i].num_tlv = 1; + fapi_req.body.pdus[i].tlvs[0].value = (uint32_t*)req->tx_request_body.tx_pdu_list[i].segments[0].segment_data; + + //if the pnf wants to retain the pointer then req->tx_request_body.tx_pdu_list[i].segments[0].segment_data should be set to 0 + + + } + + fapi_tx_request(phy->fapi, &fapi_req); +/* + if(fapi_req.body.number_of_pdus > 0) + { + for(int i = 0; i < fapi_req.body.number_of_pdus; ++i) + { + //printf("freeing tx pdu %p\n", fapi_req.body.pdus[i].tlvs[0].value); + if(0) + { + free(fapi_req.body.pdus[i].tlvs[0].value); + } + else + { + pnf_deallocate(fapi_req.body.pdus[i].tlvs[0].value); + } + } + } +*/ + + return 0; +} +int phy_lbt_dl_config_req(nfapi_pnf_p7_config_t*, nfapi_lbt_dl_config_request_t* req) +{ + //printf("[PNF_SIM] lbt dl config request\n"); + return 0; +} + +int phy_vendor_ext(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg) +{ + if(msg->message_id == P7_VENDOR_EXT_REQ) + { + vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; + //printf("[PNF_SIM] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2); + } + else + { + printf("[PNF_SIM] unknown vendor ext\n"); + } + return 0; +} + + + +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codex) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) + { + vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)(header); + if(!push16(ind->error_code, ppWritePackedMsg, end)) + return 0; + + return 1; + } + return -1; +} + +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* codec) +{ + if(header->message_id == P7_VENDOR_EXT_REQ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))) + return 0; + return 1; + } + return -1; +} + +int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t* end, void** ve, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_1_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_1)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int phy_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config) +{ + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} + +int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n"); + + switch(tl->tag) + { + case VENDOR_EXT_TLV_2_TAG: + *ve = malloc(sizeof(vendor_ext_tlv_2)); + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2*)(*ve))->dummy, end)) + return 0; + + return 1; + break; + } + + return -1; +} + +int pnf_sim_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + //printf("%s\n", __FUNCTION__); + (void)ve; + (void)ppWritePackedMsg; + return -1; +} +int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req) +{ + printf("[PNF_SIM] start request phy_id:%d\n", req->header.phy_id); + + pnf_info* pnf = (pnf_info*)(config->user_data); + + auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item) + { return item.id == req->header.phy_id; }); + + if(found != pnf->phys.end()) + { + phy_info& phy_info = (*found); + + + nfapi_pnf_p7_config_t* p7_config = nfapi_pnf_p7_config_create(); + + p7_config->phy_id = phy->phy_id; + + p7_config->remote_p7_port = phy_info.remote_port; + p7_config->remote_p7_addr = phy_info.remote_addr; + p7_config->local_p7_port = phy_info.local_port; + p7_config->local_p7_addr = (char*)phy_info.local_addr.c_str(); + p7_config->user_data = &phy_info; + + p7_config->malloc = &pnf_allocate; + p7_config->free = &pnf_deallocate; + p7_config->codec_config.allocate = &pnf_allocate; + p7_config->codec_config.deallocate = &pnf_deallocate; + + p7_config->trace = &pnf_sim_trace; + + phy->user_data = p7_config; + + p7_config->subframe_buffer_size = phy_info.timing_window; + if(phy_info.timing_info_mode & 0x1) + { + p7_config->timing_info_mode_periodic = 1; + p7_config->timing_info_period = phy_info.timing_info_period; + } + + if(phy_info.timing_info_mode & 0x2) + { + p7_config->timing_info_mode_aperiodic = 1; + } + + p7_config->dl_config_req = &phy_dl_config_req; + p7_config->ul_config_req = &phy_ul_config_req; + p7_config->hi_dci0_req = &phy_hi_dci0_req; + p7_config->tx_req = &phy_tx_req; + p7_config->lbt_dl_config_req = &phy_lbt_dl_config_req; + + p7_config->vendor_ext = &phy_vendor_ext; + + p7_config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + + p7_config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extention_tlv; + + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); + + + ((pnf_phy_user_data_t*)(phy_info.fapi->user_data))->p7_config = p7_config; + + fapi_start_req_t fapi_req; + fapi_start_request(phy_info.fapi, &fapi_req); + + } + + return 0; +} + +int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req) +{ + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_measurement_resp(config, &resp); + return 0; +} +int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req) +{ + nfapi_rssi_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_RSSI_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_rssi_resp(config, &resp); + + nfapi_rssi_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_RSSI_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + ind.rssi_indication_body.tl.tag = NFAPI_RSSI_INDICATION_TAG; + ind.rssi_indication_body.number_of_rssi = 1; + ind.rssi_indication_body.rssi[0] = -42; + nfapi_pnf_rssi_ind(config, &ind); + return 0; +} +int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req) +{ + nfapi_cell_search_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_cell_search_resp(config, &resp); + + nfapi_cell_search_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_CELL_SEARCH_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_cell_search_indication.tl.tag = NFAPI_LTE_CELL_SEARCH_INDICATION_TAG; + ind.lte_cell_search_indication.number_of_lte_cells_found = 1; + ind.lte_cell_search_indication.lte_found_cells[0].pci = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrp = 123; + ind.lte_cell_search_indication.lte_found_cells[0].rsrq = 123; + ind.lte_cell_search_indication.lte_found_cells[0].frequency_offset = 123; + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; + ind.utran_cell_search_indication.number_of_utran_cells_found = 1; + ind.utran_cell_search_indication.utran_found_cells[0].psc = 89; + ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89; + ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89; + ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89; + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; + ind.geran_cell_search_indication.number_of_gsm_cells_found = 1; + ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23; + ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230; + + } + break; + } + + ind.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + ind.pnf_cell_search_state.length = 3; + + nfapi_pnf_cell_search_ind(config, &ind); + return 0; +} +int broadcast_detect_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req) +{ + nfapi_broadcast_detect_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_broadcast_detect_resp(config, &resp); + + nfapi_broadcast_detect_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; + ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1; + ind.lte_broadcast_detect_indication.mib_length = 4; + //ind.lte_broadcast_detect_indication.mib... + ind.lte_broadcast_detect_indication.sfn_offset = 77; + + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; + ind.utran_broadcast_detect_indication.mib_length = 4; + //ind.utran_broadcast_detect_indication.mib... + ind.utran_broadcast_detect_indication.sfn_offset; + + } + break; + } + + ind.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + ind.pnf_cell_broadcast_state.length = 3; + + nfapi_pnf_broadcast_detect_ind(config, &ind); + return 0; +} +int system_information_schedule_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req) +{ + nfapi_system_information_schedule_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_schedule_resp(config, &resp); + + nfapi_system_information_schedule_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 3; + ind.lte_system_information_indication.sib_length = 5; + //ind.lte_system_information_indication.sib... + + nfapi_pnf_system_information_schedule_ind(config, &ind); + return 0; +} +int system_information_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req) +{ + nfapi_system_information_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_system_information_resp(config, &resp); + + nfapi_system_information_indication_t ind; + memset(&ind, 0, sizeof(ind)); + ind.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; + ind.header.phy_id = req->header.phy_id; + ind.error_code = NFAPI_P4_MSG_OK; + + switch(req->rat_type) + { + case NFAPI_RAT_TYPE_LTE: + { + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 1; + ind.lte_system_information_indication.sib_length = 3; + //ind.lte_system_information_indication.sib... + } + break; + case NFAPI_RAT_TYPE_UTRAN: + { + ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.utran_system_information_indication.sib_length = 3; + //ind.utran_system_information_indication.sib... + + } + break; + case NFAPI_RAT_TYPE_GERAN: + { + ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.geran_system_information_indication.si_length = 3; + //ind.geran_system_information_indication.si... + + } + break; + } + + + nfapi_pnf_system_information_ind(config, &ind); + + return 0; +} +int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req) +{ + nfapi_nmm_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_P4_MSG_OK; + nfapi_pnf_nmm_stop_resp(config, &resp); + return 0; +} + +int vendor_ext(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF_SIM] P5 %s %p\n", __FUNCTION__, msg); + + switch(msg->message_id) + { + case P5_VENDOR_EXT_REQ: + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)msg; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF_SIM] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2); + // send back the P5_VENDOR_EXT_RSP + vendor_ext_p5_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); + rsp.header.message_id = P5_VENDOR_EXT_RSP; + rsp.error_code = NFAPI_MSG_OK; + nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp)); + } + break; + } + + return 0; +} + +nfapi_p4_p5_message_header_t* pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P5_VENDOR_EXT_REQ) + { + (*msg_size) = sizeof(vendor_ext_p5_req); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_req)); + } + + return 0; +} + +void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) +{ + free(header); +} + + +int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) + { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)(header); + return (!push16(rsp->error_code, ppWritePackedMsg, end)); + } + return 0; +} + +int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && + pull16(ppReadPackedMessage, &req->dummy2, end))); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2); + } + return 0; +} +int main(int argc, char *argv[]) +{ + if (argc < 3) + { + printf("Use parameters: \n"); + return 0; + } + + set_thread_priority(50); + + pnf_info pnf; + if(read_pnf_xml(pnf, argv[3]) < 0) + { + printf("Failed to read xml file>\n"); + return 0; + } + + + nfapi_pnf_config_t* config = nfapi_pnf_config_create(); + + config->vnf_ip_addr = argv[1]; + config->vnf_p5_port = atoi(argv[2]); + + config->pnf_param_req = &pnf_param_request; + config->pnf_config_req = &pnf_config_request; + config->pnf_start_req = &pnf_start_request; + config->pnf_stop_req = &pnf_stop_request; + config->param_req = ¶m_request; + config->config_req = &config_request; + config->start_req = &start_request; + + config->measurement_req = &measurement_request; + config->rssi_req = &rssi_request; + config->cell_search_req = &cell_search_request; + config->broadcast_detect_req = &broadcast_detect_request; + config->system_information_schedule_req = &system_information_schedule_request; + config->system_information_req = &system_information_request; + config->nmm_stop_req = &nmm_stop_request; + + config->vendor_ext = &vendor_ext; + + config->trace = &pnf_sim_trace; + + config->user_data = &pnf; + + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv; + + config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext; + + config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension; + + return nfapi_pnf_start(config); + +} diff --git a/nfapi/open-nFAPI/sim_common/Makefile.am b/nfapi/open-nFAPI/sim_common/Makefile.am new file mode 100644 index 0000000000..771b768a16 --- /dev/null +++ b/nfapi/open-nFAPI/sim_common/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AUTOMAKE_OPTIONS=subdir-objects + +AM_CFLAGS = -I$(top_srcdir)/sim_common/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -g -Wall -Werror + +AM_CXXFLAGS = -I$(top_srcdir)/sim_common/public_inc -I$(top_srcdir)/common/public_inc -std=c++11 -I$(top_srcdir)/nfapi/public_inc $(BOOST_CPPFLAGS) -g -Wall -Werror +noinst_LIBRARIES =libnfapi_sim_common.a +#libnfapi_sim_common_a_SOURCES = src/xml_property_tree.cpp src/pool.cpp +libnfapi_sim_common_a_SOURCES = src/pool.cpp + +libnfapi_sim_common_a_CFLAGS =$(AM_CFLAGS) +libnfapi_sim_common_a_CXXFLAGS =$(AM_CXXFLAGS) + +lib_LTLIBRARIES =libnfapi_sim_common.la +#libnfapi_sim_common_la_SOURCES = src/xml_property_tree.cpp +libnfapi_sim_common_la_SOURCES = src/pool.cpp diff --git a/nfapi/open-nFAPI/sim_common/inc/pool.h b/nfapi/open-nFAPI/sim_common/inc/pool.h new file mode 100644 index 0000000000..8591d939f9 --- /dev/null +++ b/nfapi/open-nFAPI/sim_common/inc/pool.h @@ -0,0 +1,186 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _POOL_H_ +#define _POOL_H_ + +#include +#include +#include +#include + + +class pool_config +{ + public: + + size_t size; + uint16_t initial_count; +}; + +class memory_pool +{ + std::mutex mutex; + std::map> free_store; + std::map allocated_store; + + void init(std::vector config) + { + printf("memory_pool::init\n"); + + for(pool_config c : config) + { + // todo : use the initial count to allocate initial pool memory + free_store.insert(std::pair> + (c.size, std::queue())); + allocated_store.insert(std::pair(c.size, 0)); + } + } + + memory_pool() + { + std::vector config + { + {8, 0}, {32, 0}, {64, 0}, {128, 0}, {256, 0}, + {1024, 0}, {4096, 0}, {8912, 0} + + }; + + init(config); + } + + + uint16_t determine_pool_size(size_t size) + { + for(auto pool : free_store) + { + if(pool.first >= size) + return pool.first; + } + + return 0; + } + + uint8_t* alloc(size_t size) + { + if(size == 0) + return 0; + + uint8_t* ptr = 0; + size_t psize = determine_pool_size(size + 4); + + if(psize == 0) + { + ptr = (uint8_t*)malloc(size + 4); + memset(ptr, 0, size + 4); + } + else + { + mutex.lock(); + + auto it = free_store.find(psize); + + if(it == free_store.end()) + { + // Unknown pool size + ptr = (uint8_t*)malloc(psize + 4); + memcpy(ptr, &psize, 4); + } + else + { + if(it->second.size() > 0) + { + // Take from the pool + ptr = (uint8_t*)(it->second.front()); + it->second.pop(); + } + else + { + // No memory left in pool + ptr = (uint8_t*)malloc(psize + 4); + memcpy(ptr, &psize, 4); + } + } + + mutex.unlock(); + } + + return (ptr + 4); + } + + void dealloc(uint8_t* ptr) + { + if(ptr == 0) + return; + + uint8_t* _ptr = (uint8_t*)ptr; + + size_t psize; + memcpy(&psize, _ptr - 4, 4); + + if(psize == 0) + { + free(_ptr - 4); + } + else + { + mutex.lock(); + + auto it = free_store.find(psize); + if(it == free_store.end()) + { + free(_ptr - 4); + } + else + { + assert((_ptr - 4) != 0); + it->second.push(_ptr - 4); + } + + mutex.unlock(); + } + + } + + public: + + memory_pool(memory_pool const&) = delete; + void operator=(memory_pool const&) = delete; + + /*! Get the memory_pool instance */ + static memory_pool& instance() + { + static memory_pool instance; + return instance; + } + + /*! Allocate a buffer from the memory_pool is at least size */ + static uint8_t* allocate(size_t size) + { + return instance().alloc(size); + } + + /*! Return the buffer to the memory_pool */ + static void deallocate(uint8_t* ptr) + { + return instance().dealloc(ptr); + } + + +}; + +#endif // _POOL_H_ diff --git a/nfapi/open-nFAPI/sim_common/inc/vendor_ext.h b/nfapi/open-nFAPI/sim_common/inc/vendor_ext.h new file mode 100644 index 0000000000..d0fd57837d --- /dev/null +++ b/nfapi/open-nFAPI/sim_common/inc/vendor_ext.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _VENDOR_EXT_H_ +#define _VENDOR_EXT_H_ + +#include "nfapi_interface.h" + +typedef enum +{ + P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN, + P5_VENDOR_EXT_RSP, + + P7_VENDOR_EXT_REQ, + P7_VENDOR_EXT_IND + +} vendor_ext_message_id_e; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p5_req; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint16_t error_code; +} vendor_ext_p5_rsp; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; +} vendor_ext_p7_req; + +typedef struct { + nfapi_p7_message_header_t header; + uint16_t error_code; +} vendor_ext_p7_ind; + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_1; + +#define VENDOR_EXT_TLV_1_TAG 0xF001 + +typedef struct { + nfapi_tl_t tl; + uint32_t dummy; +} vendor_ext_tlv_2; + +#define VENDOR_EXT_TLV_2_TAG 0xF002 + + + + +#endif // _VENDOR_EXT_ diff --git a/nfapi/open-nFAPI/sim_common/src/pool.cpp b/nfapi/open-nFAPI/sim_common/src/pool.cpp new file mode 100644 index 0000000000..47d9cfa992 --- /dev/null +++ b/nfapi/open-nFAPI/sim_common/src/pool.cpp @@ -0,0 +1,15 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ diff --git a/nfapi/open-nFAPI/vnf/Makefile.am b/nfapi/open-nFAPI/vnf/Makefile.am new file mode 100644 index 0000000000..ae8d2bb3d6 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/Makefile.am @@ -0,0 +1,43 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + + +AUTOMAKE_OPTIONS=subdir-objects + +AM_CPPFLAGS = -I$(top_srcdir)/vnf/inc\ + -I$(top_srcdir)/vnf/public_inc\ + -I$(top_srcdir)/nfapi/public_inc\ + -I$(top_srcdir)/common/public_inc\ + -Wall -Werror -g + + +noinst_LIBRARIES = libnfapi_vnf.a + +libnfapi_vnf_a_SOURCES = src/vnf.c\ + src/vnf_p7.c\ + src/vnf_interface.c\ + src/vnf_p7_interface.c + +LDADD = -lsctp ../common/bin/libnfapi_common.a + +libnfapi_vnf_a_CFLAGS =$(AM_CFLAGS) + +lib_LTLIBRARIES = libnfapi_vnf.la + +libnfapi_vnf_la_SOURCES = src/vnf.c\ + src/vnf_p7.c\ + src/vnf_interface.c\ + src/vnf_p7_interface.c diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h new file mode 100644 index 0000000000..4fd8d2b91d --- /dev/null +++ b/nfapi/open-nFAPI/vnf/inc/vnf.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _VNF_H_ +#define _VNF_H_ + +#include "nfapi_vnf_interface.h" + +typedef struct +{ + + nfapi_vnf_config_t _public; + + uint8_t terminate; + uint8_t sctp; + + uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + uint16_t next_phy_id; + +} vnf_t; + + +int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); +int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); + +int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf); + +void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info); +nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id); +void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* node); +nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx); +#endif // _VNF_H_ diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h new file mode 100644 index 0000000000..fc2ab4e6b5 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h @@ -0,0 +1,136 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#ifndef _VNF_P7_H_ +#define _VNF_P7_H_ + +#include "nfapi_vnf_interface.h" + +#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20) +#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF) +#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF)) + + + +typedef struct { + uint8_t* buffer; + uint16_t length; +} vnf_p7_rx_message_segment_t; + +typedef struct vnf_p7_rx_message vnf_p7_rx_message_t; + +typedef struct vnf_p7_rx_message { + uint8_t sequence_number; + uint8_t num_segments_received; + uint8_t num_segments_expected; + + // the spec allows of upto 128 segments, this does seem excessive + vnf_p7_rx_message_segment_t segments[128]; + + uint32_t rx_hr_time; + + vnf_p7_rx_message_t* next; +} vnf_p7_rx_message_t; + +typedef struct { + + vnf_p7_rx_message_t* msg_queue; + +} vnf_p7_rx_reassembly_queue_t; + +typedef struct nfapi_vnf_p7_connection_info { + + /*! The PHY id */ + int phy_id; + + + // this does not belong here... + uint8_t stream_id; + + /*! Flag indicating the sync state of the P7 conenction */ + uint8_t in_sync; + + int dl_out_sync_offset; + int dl_out_sync_period; // ms (as a pow2) + + int dl_in_sync_offset; + int dl_in_sync_period; // ms (as a pow2) + + uint8_t filtered_adjust; + uint16_t min_sync_cycle_count; + uint32_t latency[8]; + uint32_t average_latency; + int32_t sf_offset_filtered; + int32_t sf_offset_trend; + int32_t sf_offset; + uint16_t zero_count; + int32_t adjustment; + int32_t insync_minor_adjustment; + int32_t insync_minor_adjustment_duration; + + uint32_t previous_t1; + uint32_t previous_t2; + int32_t previous_sf_offset_filtered; + + int sfn_sf; + + int socket; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + + vnf_p7_rx_reassembly_queue_t reassembly_queue; + uint8_t* reassembly_buffer; + uint32_t reassembly_buffer_size; + + uint32_t sequence_number; + + struct nfapi_vnf_p7_connection_info* next; + +} nfapi_vnf_p7_connection_info_t; + +typedef struct { + + nfapi_vnf_p7_config_t _public; + + // private data + uint8_t terminate; + nfapi_vnf_p7_connection_info_t* p7_connections; + int socket; + uint32_t sf_start_time_hr; + uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info? + uint16_t rx_message_buffer_size; + +} vnf_p7_t; + +uint32_t vnf_get_current_time_hr(void); + +uint16_t increment_sfn_sf(uint16_t sfn_sf); +int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info); +int send_mac_subframe_indications(vnf_p7_t* config); +int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 ); + +void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node); +nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id); +nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id); + +int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header); + +void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header); +void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu); + + +#endif // _VNF_P7_H_ diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h new file mode 100644 index 0000000000..462901391a --- /dev/null +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -0,0 +1,995 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _NFAPI_VNF_INTERFACE_H_ +#define _NFAPI_VNF_INTERFACE_H_ + +#include "nfapi_interface.h" +#include "debug.h" + +#include "netinet/in.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192 + +/*! The nfapi VNF phy configuration information + */ +typedef struct nfapi_vnf_phy_info +{ + /*! The P5 Index */ + int p5_idx; //which p5 connection + /*! The PHY ID */ + int phy_id; //phy_id + + /*! Timing window */ + uint8_t timing_window; + /*! Timing info mode */ + uint8_t timing_info_mode; + /*! Timing info period */ + uint8_t timing_info_period; + + /*! P7 UDP socket information for the pnf */ + struct sockaddr_in p7_pnf_address; + /*! P7 UDP socket information for the vnf */ + struct sockaddr_in p7_vnf_address; + + struct nfapi_vnf_phy_info* next; +} nfapi_vnf_phy_info_t; + +/*! The nfapi VNF pnf configuration information + */ +typedef struct nfapi_vnf_pnf_info +{ + /*! The P5 Index */ + int p5_idx; + /*! The P5 socket */ + int p5_sock; + /*! Flag indicating if the pnf is connected */ + uint8_t connected; + + /*! P5 SCTP socket information for the pnf */ + struct sockaddr_in p5_pnf_sockaddr; + + /*! Flag indicating if this pnf should be deleted */ + uint8_t to_delete; + + struct nfapi_vnf_pnf_info* next; + +} nfapi_vnf_pnf_info_t; + +typedef struct nfapi_vnf_config nfapi_vnf_config_t; + +/*! The nfapi VNF configuration information + */ +typedef struct nfapi_vnf_config +{ + /*! A user define callback to override the default memory allocation */ + void* (*malloc)(size_t size); + /*! A user define callback to override the default memory deallocation */ + void (*free)(void*); + /*! A user define callback to handle trace from the pnf */ + void (*trace)(nfapi_trace_level_t level, const char* message, ...); + + /*! The port the VNF P5 SCTP connection listens on + * + * By default this will be set to 7701. However this can be changed if + * required. + */ + int vnf_p5_port; + + // todo : for enabling ipv4/ipv6 + int vnf_ipv4; + int vnf_ipv6; + + /*! List of connected pnfs */ + nfapi_vnf_pnf_info_t* pnf_list; + + /*! List of configured phys */ + nfapi_vnf_phy_info_t* phy_list; + + /*! Configuration options for the p4 p5 pack unpack functions */ + nfapi_p4_p5_codec_config_t codec_config; + + /*! Optional user defined data that will be avaliable in the callbacks*/ + void* user_data; + + /*! \brief Callback indicating that a pnf has established connection + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 used to indicate this pnf p5 connection + * + * The client is expected to send the PNF_PARAM.request in response to + * the connection indication + * + * \todo Do we need to send the address information of the PNF? + */ + int (*pnf_connection_indication)(nfapi_vnf_config_t* config, int p5_idx); + + /*! \brief Callback indicating that a pnf has lost connection + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 used to indicate this pnf p5 connection + * + * The p5_idx may be used for future new p5 connections + * + * The client is responsiable for communicating to the p7 instance(s) that + * may be associated with this p5 that they should be deleted using the + * nfapi_vnf_p7_del_pnf functon + * + */ + int (*pnf_disconnect_indication)(nfapi_vnf_config_t* config, int p5_idx); + + // p5 interface functions + + /*! \brief A callback to handle the PNF_PARAM.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded PNF_PARAM.response. This will + * have been allocated on the stack. + * \return not currently used. + * + * The PNF_PARAM.resp contains the capability of the PNF identified by the + * p5_idx. + * + * The client is expected to send the PNF_CONFIG.request after receiving the + * PNF_PARAM.resp. This can be done in the call back. + * + * It is expected that the client when building the PNF_CONFIG.request will + * used the nfapi_vnf_allocate_phy() to allocate unique phy id for each FAPI + * instance the client wishes to create. + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*pnf_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp); + + /*! A callback for the PNF_CONFIG.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded PNF_CONFIG.response. This will + * have been allocated on the stack. + * \return not currently used. + * + * The PNF_CONFIG.resp contains the result of the PNF_CONFIG.request for the + * PNF identified by the p5_idx. + * + * The client is expected to send the PNF_START.request after receiving the + * PNF_PARAM.resp. This can be done in the call back. + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*pnf_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp); + + /*! A callback for the PNF_START.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded PNF_START.response. This will + * have been allocated on the stack. + * \return not currently used. + * + * The PNF_START.resp contains the result of the PNF_START.request for the + * PNF identified by the p5_idx. + * + * The client is expected to send the PARAM.request for each FAPI instance + * that has been created in the PNF. + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*pnf_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp); + + /*! A callback for the PNF_STOP.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded PNF_STOP.response. This will + * have been allocated on the stack. + * \return not currently used. + * + * The PNF_STOP.response contains the result of the PNF_STOP.request for the + * PNF identified by the p5_idx. + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*pnf_stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_response_t* resp); + + /*! A callback for the PARAM.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded PARAM.resposne. This will + * have been allocated on the stack. + * \return not currently used. + * + * The PARAM.request contains the capabilities of the FAPI instance identified + * by the phy_id + * + * The client is expected to send the CONFIG.request after receiving the + * PARAM.response. This can be done in the call back. The PARAM.response + * contains the PNF P7 address (ipv4 or ipv6) and port. This information + * is used when calling the nfapi_vnf_p7_add_pnf() + * + * The client is responsible for identifing the VNF P7 ip address + * (ipv4 or ipv6) and port for the VNF P7 entity which will be sent to the + * PNF P7 entity. That endpoint should be valid before send the + * CONFIG.request. + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp); + + /*! A callback for the CONFIG.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded CONFIG.response This will + * have been allocated on the stack. + * \return not currently used. + * + * The CONFIG.response contains the result of the CONFIG.request + * + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp); + + /*! A callback for the START.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded START.response This will + * have been allocated on the stack. + * \return not currently used. + * + * The START.response contains the result of the START.request + * + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp); + + /*! A callback for the STOP.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded STOP.response This will + * have been allocated on the stack. + * \return not currently used. + * + * The STOP.response contains the result of the STOP.request + * + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_response_t* resp); + + /*! A callback for the MEASUREMENT.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded MEASUREMENT.response This will + * have been allocated on the stack. + * \return not currently used. + * + * The MEASUREMENT.response contains the result of the MEASUREMENT.request + * + * The resp may contain pointers to dyanmically allocated sub structures + * such as the vendor_extention. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*measurement_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_measurement_response_t* resp); + + // p4 interface functions + /*! A callback for the RSSI.resp + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded RSSI.response This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*rssi_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_response_t* resp); + + /*! A callback for the RSSI.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded RSSI.indication This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*rssi_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_indication_t* ind); + + /*! A callback for the CELL_SEARCH.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded CELL_SEARCH.response This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*cell_search_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_response_t* resp); + + /*! A callback for the CELL_SEARCH.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded CELL_SEARCH.indication This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*cell_search_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_indication_t* ind); + + /*! A callback for the BROADCAST_DETECT.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded BROADCAST_DETECT.response This will + * have been allocated on the stack. + * \return not currently used. */ + int (*broadcast_detect_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_response_t* resp); + + /*! A callback for the BROADCAST_DETECT.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded BROADCAST_DETECT.indication This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*broadcast_detect_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_indication_t* ind); + + /*! A callback for the SYSTEM_INFORMATION_SCHEUDLE.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.response This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*system_information_schedule_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_response_t* resp); + + /*! A callback for the SYSTEM_INFORMATION_SCHEUDLE.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded SYSTEM_INFORMATION_SCHEUDLE.indication This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*system_information_schedule_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_indication_t* ind); + + /*! A callback for the SYSTEM_INFORMATION.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded SYSTEM_INFORMATION.response This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*system_information_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_response_t* resp); + + /*! A callback for the SYSTEM_INFORMATION.indication + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded SYSTEM_INFORMATION.indication This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*system_information_ind)(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_indication_t* ind); + + /*! A callback for the NMM_STOP.response + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded NMM_STOP.response This will + * have been allocated on the stack. + * \return not currently used. + */ + int (*nmm_stop_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nmm_stop_response_t* resp); + + + /*! A callback for any vendor extension message received + * \param config A pointer to the vnf configuration + * \param p5_idx The p5 index used to indicate a particular pnf p5 connection + * \param resp A data structure for the decoded vendor extention message + * \return not currently used. + */ + int (*vendor_ext)(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg); + + /*! A callback to allocate vendor extension messages + * \param message_id The message is taken from the message header + * \param msg_size The is the vendor extention message that has been allocated. + * The callee must set this value + * \return A pointer to an allocated vendor extention message + */ + nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size); + + /*! A callback to deallocate vendor extension messages + * \param header A pointer to an allocated vendor extention message + */ + void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header); + + + + + + +} nfapi_vnf_config_t; + +/*! Creates and initialise the vnf config structure before use + * \return A pointer to a vnf config structure + */ +nfapi_vnf_config_t* nfapi_vnf_config_create(void); + +/*! Delete an vnf config + */ +void nfapi_vnf_config_destory(nfapi_vnf_config_t* config); + + +/*! Start the VNF library. + * \param config A pointer to a vnf config + * \return 0 means success, -1 failure + * + * The config should be initailize with port the vnf should listen on and + * the callback set to functions that will be called when a nFAPI message is + * recevied before calling nfapi_vnf_start. + * + * This function will not return untill nfapi_vnf_stop is called + */ +int nfapi_vnf_start(nfapi_vnf_config_t* config); + +/*! Stop the VNF library. + * \param config A pointer to a vnf config + * \return 0 means success, -1 failure + * + * This function will cause the nfapi_vnf_start function to return + */ +int nfapi_vnf_stop(nfapi_vnf_config_t* config); + +/*! Allocates a PHY ID for the PNF PHY instance managed by this VNF + * \param config A pointer to a vnf config + * \param p5_idx The P5 index return by the callbacks + * \param phy_id A pointer to a phy_id that will be set by this function + * \return 0 means success, -1 failure + * + * Called before nfapi_vnf_config_req to allocate a vnf phy instance. This + * function will return unqiue phy_id to be used for this identify the phy + * + */ +int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy_id); + +// P5 Request functions +// +/*! Send the PNF_PARAM.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a PNF_PARAM.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req); + +/*! Send the PNF_CONFIG.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a PNF_CONFIG.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_config_request_t* req); + +/*! Send the PNF_START.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a PNF_START.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_start_request_t* req); + +/*! Send the PNF_STOP.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a PNF_STOP.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_stop_request_t* req); + +/*! Send the PARAM.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a PARAM.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req); + +/*! Send the CONFIG.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a CONFIG.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req); + +/*! Send the START.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a START.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req); + +/*! Send the STOP.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a STOP.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req); + +/*! Send the MEASUREMENT.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a MEASUREMENT.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_measurement_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_measurement_request_t* req); + +// P4 Request functions +/*! Send the RSSI.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a RSSI.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_rssi_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_request_t* req); + +/*! Send the CELL_SEARCH.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a CELL_SEARCH.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_cell_search_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_request_t* req); + +/*! Send the BROADCAST_DETECT.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a BROADCAST_DETECT.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_broadcast_detect_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_request_t* req); + +/*! Send the SYSTEM_INFORMATION_SCHEDULE.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a SYSTEM_INFORMATION_SCHEDULE.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_system_information_schedule_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_request_t* req); + +/*! Send the SYSTEM_INFORMATION.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a SYSTEM_INFORMATION.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_system_information_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_request_t* req); + +/*! Send the NMM_STOP.request + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param req A pointer to a NMM_STOP.request message structure + * \return 0 means success, -1 failure + */ +int nfapi_vnf_nmm_stop_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_nmm_stop_request_t* req); + +/*! Send a vendor extension message + * \param config A pointer to a vnf config + * \param p5_idx The P5 index + * \param msg A poiner to a vendor extention message + * \return 0 means success, -1 failure + */ +int nfapi_vnf_vendor_extension(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg); + +//----------------------------------------------------------------------------- + +/*! The nfapi VNF P7 connection information + */ +typedef struct nfapi_vnf_p7_config nfapi_vnf_p7_config_t; + +/*! The nfapi VNF P7 configuration information + */ +typedef struct nfapi_vnf_p7_config +{ + /*! A user define callback to override the default memory allocation + * \param size Size of the memory block to allocate + * \return a pointer to a memory block + * + * If not set the vnf p7 library will use malloc + */ + void* (*malloc)(size_t size); + + /*! A user define callback to override the default memory deallocation + * \param ptr Pointer to a memory block to deallocate + * + * If not set the vnf p7 library will use free + */ + void (*free)(void*); + + /*! A user define callback to handle trace from the pnf + * \param level The trace level + * \param message The trace string + */ + void (*trace)(nfapi_trace_level_t level, const char* message, ...); + + /*! The port the vnf p7 will receive on */ + int port; + + /*! Flag to indicate of the pnf should use the P7 checksum */ + uint8_t checksum_enabled; + + /*! The maxium size of a P7 segement. If a message is large that this it + * will be segemented */ + uint16_t segment_size; + uint16_t max_num_segments; + + /*! Configuration option for the p7 pack unpack functions*/ + nfapi_p7_codec_config_t codec_config; + + /* ! Call back to indicate the sync state with the PNF PHY + * \param config A pointer to the vnf p7 configuration + * \param sync Indicating if the pnf is in sync or not + * \return not currently used + * + * sync = 0 : in sync + * sync != 0 : out of sync + */ + int (*sync_indication)(struct nfapi_vnf_p7_config* config, uint8_t sync); + + /*! A callback for the subframe indication + * \param config A pointer to the vnf p7 configuration + * \param phy_id The ID for the PNF PHY instance + * \param sfn_sf The SFN SF number formated as per the FAPI specification + * \return not currently used + * + * This callback is an indication for the VNF to generate the downlink subframe messages + * for sfn/sf. This indicatoin is called every millisecond + * + * The VNF P7 Lib will adjust the subframe timing to 'catch-up' or 'slow-down' with the PNF PHY's + * + * \todo Need some way the tell the VNF how long it has + */ + + int (*subframe_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf); + + /*! A callback for the HARQ.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded HARQ.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*harq_indication)(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind); + + /*! A callback for the CRC.ind + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded CRC.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*crc_indication)(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind); + + /*! A callback for the RX_ULSCH.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded RX_ULSCH.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + * + * Note that the rx_indication may hold one or many uplink pdus in the + * ind.rx_indication_body.rx_pdu_list + */ + int (*rx_indication)(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind); + + /*! A callback for the RACH.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded RACH.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*rach_indication)(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind); + + /*! A callback for the SRS.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded SRS.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*srs_indication)(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind); + + /*! A callback for the RX_SR.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded RX_SR.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*sr_indication)(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind); + + /*! A callback for the RX_CQI.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded RX_CQI.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*cqi_indication)(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind); + + /*! A callback for the LBT_DL.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded LBT_DL.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*lbt_dl_indication)(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind); + + /*! A callback for the NB_HARQ.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded LBT_DL.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*nb_harq_indication)(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind); + + /*! A callback for the NRACH.indication + * \param config A pointer to the vnf p7 configuration + * \param ind A data structure for the decoded LBT_DL.indication This will + * have been allocated on the stack. + * \return not currently used. + * + * The ind may contain pointers to dyanmically allocated sub structures + * such as the pdu. The dyanmically allocated structure will + * be deallocated on return. If the client wishes to 'keep' the structures + * then the substructure pointers should be set to 0 and then the client should + * use the codec_config.deallocate function to release it at a future point + */ + int (*nrach_indication)(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind); + + /*! A callback for any vendor extension messages + * \param config A pointer to the vnf p7 configuration + * \param msg A data structure for the decoded vendor extention message allocated + * using the allocate_p7_vendor_ext callback + * \return not currently used. + */ + int (*vendor_ext)(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg); + + /*! Optional userdata that will be passed back in the callbacks*/ + void* user_data; + + /*! A callback to allocate a memory for a vendor extension message + * \param message_id The message is taken from the p7 message header + * \param msg_size The is the vendor extention message that has been allocated. + * The callee must set this value + * \return A pointer to an allocated vendor extention message + */ + nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size); + + /*! A callback to deallocate a vendor extension message + * \param header A pointer to an allocated vendor extention message + */ + void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header); + + +} nfapi_vnf_p7_config_t; + +/*! Creates and initializes the nfapi_vnf_p7_config structure before use + * \return A pointer to an allocated vnf p7 configuration + */ +nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create(void); + +/*! Cleanup and delete nfapi_vnf_p7_config structure + * \param config A pointer to an vnf p7 configuration structure + * + * The pointer to the config will not long be valid after this call + */ + +void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config); + +/*! Start the VNF P7 library. + * \param config A pointer to an vnf p7 configuration structure + * \return A status value. 0 equal success, -1 indicates failure + * + * This function is blocking and will not return until the nfapi_vnf_p7_stop + * function is called. + */ + +int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config); + +/*! Stop the VNF P7 library. + * \param config A pointer to an vnf p7 configuration structure + * \return A status value. 0 equal success, -1 indicates failure + * + * This function will cause the nfapi_vnf_p7_start function to return + */ +int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config); + +/*! Release a P7 message back to the vnf_p7 library. This should be used if the + * callback return 0 in the case where MAC wants to keep the message for + * futher processing. + * This function will release any pdu's is they are non-null. If the uplink + * PDU need to be kept then they pdu pointer should be set to 0 in the message + * and then the nfapi_vnf_p7_release_pdu message can be used to release the + * pdu later. + */ +int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t*); + +/*! Release a P7 pdu's back to the vnf_p7 library. + */ +int nfapi_vnf_p7_release_pdu(nfapi_vnf_p7_config_t* config, void*); + +/*! Add a vnf p7 instance to the vnf p7 module + * \param config A pointer to the vnf p7 configuration + * \param pnf_p7_addr The udp address the pnf p7 entity has chosen + * \param pnf_p7_port The udp port the pnf p7 entity has chosen + * \param phy_id The unique phy id for the pnf p7 entity + * \return A status value. 0 equal success, -1 indicates failure + * + * This function should be used to each pnf p7 entity that is to be added to this + * vnf p7 entity. Once added the vnf p7 entity will start establish sync with the + * pnf p7 entity and that has been sucessfull will generate subframe indications for it + */ +int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id); + +/*! Delete a vnf p7 instance to the vnf p7 module + * \param config A pointer to the vnf p7 configuration + * \param phy_id The unique phy id for the pnf p7 entity + * \return A status value. 0 equal success, -1 indicates failure + * + * This function should be used to remove a pnf p7 entity from the vnf p7 entity + */ +int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id); + +/*! Send the DL_CONFIG.request + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded DL_CONFIG.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req); + +/*! Send the UL_CONFIG.request + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded UL_CONFIG.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req); + +/*! Send the HI_DCI0.request + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded HI_DCI0.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req); + +/*! Send the TX.req + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded HI_DCI0.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req); + +/*! Send the LBT_DL_CONFIG.requst + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded LBT_DL_CONFIG.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req); + +/*! Send a vendor extension message + * \param config A pointer to the vnf p7 configuration + * \param msg A data structure for the decoded vendor extention message + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* msg); + +#if defined(__cplusplus) +} +#endif + +#endif // _NFAPI_PNF_INTERFACE_H_ diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c new file mode 100644 index 0000000000..6800ee21d2 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/src/vnf.c @@ -0,0 +1,1123 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "vnf.h" + + +void* vnf_malloc(nfapi_vnf_config_t* config, size_t size) +{ + if(config->malloc) + { + return (config->malloc)(size); + } + else + { + return calloc(1, size); + } +} +void vnf_free(nfapi_vnf_config_t* config, void* ptr) +{ + if(config->free) + { + return (config->free)(ptr); + } + else + { + return free(ptr); + } +} + +void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "Adding phy p5_idx:%d phy_id:%d\n", info->p5_idx, info->phy_id); + info->next = config->phy_list; + config->phy_list = info; +} + +nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id) +{ + nfapi_vnf_phy_info_t* curr = config->phy_list; + while(curr != 0) + { + if(curr->phy_id == phy_id) + return curr; + + curr = curr->next; + } + + return 0; +} + + + + +void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* node) +{ + node->next = config->pnf_list; + config->pnf_list = node; +} + + +nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx) +{ + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : config->pnf_list:%p\n", __FUNCTION__, config->pnf_list); + + nfapi_vnf_pnf_info_t* curr = config->pnf_list; + while(curr != 0) + { + if(curr->p5_idx == p5_idx) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->p5_idx:%d p5_idx:%d\n", __FUNCTION__, curr->p5_idx, p5_idx); + return curr; + } + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->next:%p\n", __FUNCTION__, curr->next); + + curr = curr->next; + } + + return 0; +} + +void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_PARAM.reponse\n"); + + nfapi_pnf_param_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + // Invoke the call back + if(config->pnf_param_resp) + { + (config->pnf_param_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_CONFIG_RESPONSE\n"); + + nfapi_pnf_config_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + // Invoke the call back + if(config->pnf_config_resp) + { + (config->pnf_config_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_START_RESPONSE\n"); + + nfapi_pnf_start_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->pnf_start_resp) + { + (config->pnf_start_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_pnf_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_STOP_RESPONSE\n"); + + nfapi_pnf_stop_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->pnf_stop_resp) + { + (config->pnf_stop_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + + } +} + +void vnf_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PARAM_RESPONSE\n"); + + nfapi_param_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + + if (msg.error_code == NFAPI_MSG_OK) + { + nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id); + + if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag) + { + struct sockaddr_in sockAddr; + + (void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH); + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr)); + + // store address + phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr; + } + + if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag) + { + struct sockaddr_in6 sockAddr6; + char addr6[64]; + (void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH); + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6))); + } + + if (msg.nfapi_config.p7_pnf_port.tl.tag) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value); + + // store port + phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value); + } + } + + if(config->param_resp) + { + (config->param_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CONFIG_RESPONSE\n"); + + nfapi_config_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 ) + { + if(config->config_resp) + { + (config->config_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received START_RESPONSE\n"); + + nfapi_start_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->start_resp) + { + (config->start_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received STOP.response\n"); + + nfapi_stop_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->stop_resp) + { + (config->stop_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_measurement_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received MEASUREMENT.response\n"); + + nfapi_measurement_response_t msg; + + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->measurement_resp) + { + (config->measurement_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_rssi_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received RSSI.response\n"); + + nfapi_rssi_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->rssi_resp) + { + (config->rssi_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_rssi_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received RSSI.indication\n"); + + nfapi_rssi_indication_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->rssi_ind) + { + (config->rssi_ind)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_cell_search_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CELL_SEARCH.response\n"); + + nfapi_cell_search_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->cell_search_resp) + { + (config->cell_search_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_cell_search_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_cell_search_indication: NULL parameters\n"); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CELL_SEARCH.indication\n"); + + nfapi_cell_search_indication_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->cell_search_ind) + { + (config->cell_search_ind)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_cell_search_response: Unpack message failed, ignoring\n"); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_broadcast_detect_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received BROADCAST_DETECT.response\n"); + + nfapi_broadcast_detect_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->broadcast_detect_resp) + { + (config->broadcast_detect_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_broadcast_detect_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received BROADCAST_DETECT.indication\n"); + + nfapi_broadcast_detect_indication_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->broadcast_detect_ind) + { + (config->broadcast_detect_ind)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + return; + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_system_information_schedule_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received SYSTEM_INFORMATION_SCHEDULE.response\n"); + + nfapi_system_information_schedule_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->system_information_schedule_resp) + { + (config->system_information_schedule_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_system_information_schedule_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received SYSTEM_INFORMATION_SCHEDULE.indication\n"); + + nfapi_system_information_schedule_indication_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->system_information_schedule_ind) + { + (config->system_information_schedule_ind)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_system_information_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received SYSTEM_INFORMATION.response\n"); + + nfapi_system_information_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->system_information_resp) + { + (config->system_information_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_system_information_indication(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received SYSTEM_INFORMATION.indication\n"); + + nfapi_system_information_indication_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + return; + } + + if(config->system_information_ind) + { + (config->system_information_ind)(config, p5_idx, &msg); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + +void vnf_handle_nmm_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received NMM_STOP.response\n"); + + nfapi_nmm_stop_response_t msg; + + // unpack the message + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(nfapi_nmm_stop_response_t), &config->codec_config) >= 0) + { + if(config->nmm_stop_resp) + { + (config->nmm_stop_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } + +} + +void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx, uint16_t message_id) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + + if(config->allocate_p4_p5_vendor_ext && config->deallocate_p4_p5_vendor_ext) + { + uint16_t msg_size; + + nfapi_p4_p5_message_header_t* msg = config->allocate_p4_p5_vendor_ext(message_id, &msg_size); + + if(msg) + { + if(nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &config->codec_config) >= 0) + { + if(config->vendor_ext) + config->vendor_ext(config, p5_idx, msg); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + config->deallocate_p4_p5_vendor_ext(msg); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + } + } +} + +void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config) +{ + nfapi_p4_p5_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n"); + return; + } + + // unpack the message header + if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + switch (messageHeader.message_id) + { + case NFAPI_PNF_PARAM_RESPONSE: + vnf_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_PNF_CONFIG_RESPONSE: + vnf_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_PNF_START_RESPONSE: + vnf_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_PNF_STOP_RESPONSE: + vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_PARAM_RESPONSE: + vnf_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_CONFIG_RESPONSE: + vnf_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_START_RESPONSE: + vnf_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_STOP_RESPONSE: + vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + vnf_handle_measurement_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_RSSI_RESPONSE: + vnf_handle_rssi_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_RSSI_INDICATION: + vnf_handle_rssi_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_CELL_SEARCH_RESPONSE: + vnf_handle_cell_search_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_CELL_SEARCH_INDICATION: + vnf_handle_cell_search_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_BROADCAST_DETECT_RESPONSE: + vnf_handle_broadcast_detect_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_BROADCAST_DETECT_INDICATION: + vnf_handle_broadcast_detect_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE: + vnf_handle_system_information_schedule_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION: + vnf_handle_system_information_schedule_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_RESPONSE: + vnf_handle_system_information_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_INDICATION: + vnf_handle_system_information_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NMM_STOP_RESPONSE: + vnf_handle_nmm_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + default: + { + if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id); + } + } + break; + } +} +int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf) +{ + if(1) + { + int socket_connected = 1; + + // 1. Peek the message header + // 2. If the message is larger than the stack buffer then create a dynamic buffer + // 3. Read the buffer + // 4. Handle the p5 message + + uint32_t header_buffer_size = NFAPI_HEADER_LENGTH; + uint8_t header_buffer[header_buffer_size]; + + uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure + uint8_t stack_buffer[stack_buffer_size]; + + uint8_t* dynamic_buffer = 0; + + uint8_t* read_buffer = &stack_buffer[0]; + uint32_t message_size = 0; + + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + struct sctp_sndrcvinfo sndrcvinfo; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + { + int flags = MSG_PEEK; + message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + + if(message_size == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno); + return 0; + } + + nfapi_p4_p5_message_header_t header; + int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0); + if(unpack_result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result); + return 0; + } + message_size = header.message_length; + + // now have the size of the mesage + } + + if(message_size > stack_buffer_size) + { + dynamic_buffer = (uint8_t*)malloc(message_size); + + if(dynamic_buffer == NULL) + { + // todo : add error mesage + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size); + return -1; + } + + read_buffer = dynamic_buffer; + } + + { + int flags = 0; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + if(recvmsg_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno); + } + else + { + if (flags & MSG_NOTIFICATION) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + + // todo - handle the events + } + else + { + /* + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n", + pnf->p5_sock, + inet_ntoa(addr.sin_addr), + ntohs(addr.sin_port), + sndrcvinfo.sinfo_assoc_id, + sndrcvinfo.sinfo_stream, + ntohl(sndrcvinfo.sinfo_ppid), + message_size, + flags); + */ + + // handle now if complete message in one or more segments + if ((flags & 0x80) == 0x80) + { + vnf_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags); + + // assume socket disconnected + NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n"); + socket_connected = 0; + } + + + } + } + } + + if(dynamic_buffer) + { + free(dynamic_buffer); + } + + return socket_connected; + } +} + +static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream) +{ + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s len:%d stream:%d\n", __FUNCTION__, len, stream); + + int result = sctp_sendmsg(pnf->p5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4); + + if(result != len) + { + if(result < 0) + { + // error + NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp sendto failed errno: %d\n", errno); + } + else + { + // did not send all the message + } + } + + return 0; +} + + +int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len) +{ + nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx); + + if(pnf) + { + // pack the message for transmission + int packedMessageLength = nfapi_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config); + + if (packedMessageLength < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength); + return -1; + } + + return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); + return -1; + } +} + + +int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len) +{ + nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx); + + if(pnf) + { + // pack the message for transmission + int packedMessageLength = nfapi_p4_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config); + + if (packedMessageLength < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p4_message_pack failed with return %d\n", packedMessageLength); + return -1; + } + + return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0/*msg->phy_id*/); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); + return -1; + } +} + diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c new file mode 100644 index 0000000000..0aba0a29f5 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c @@ -0,0 +1,676 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "vnf.h" + + + +nfapi_vnf_config_t* nfapi_vnf_config_create() +{ + vnf_t* _this = (vnf_t*)calloc(1, sizeof(vnf_t)); + + if(_this == 0) + return 0; + + _this->sctp = 1; + + _this->next_phy_id = 1; + + // Set the default P5 port + _this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT; + + // set the default memory allocation + _this->_public.malloc = &malloc; + _this->_public.free = &free; + + // set the default memory allocation + _this->_public.codec_config.allocate = &malloc; + _this->_public.codec_config.deallocate = &free; + + + return &(_this->_public); +} + +void nfapi_vnf_config_destory(nfapi_vnf_config_t* config) +{ + free(config); +} + +int nfapi_vnf_start(nfapi_vnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = (nfapi_trace_fn_t)config->trace; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + + int p5ListenSock, p5Sock; + + struct sockaddr_in addr; + socklen_t addrSize; + + struct sockaddr_in6 addr6; + + struct sctp_event_subscribe events; + struct sctp_initmsg initMsg; + int noDelay; + + (void)memset(&addr, 0, sizeof(struct sockaddr_in)); + (void)memset(&addr6, 0, sizeof(struct sockaddr_in6)); + (void)memset(&events, 0, sizeof(struct sctp_event_subscribe)); + (void)memset(&initMsg, 0, sizeof(struct sctp_initmsg)); + + vnf_t* vnf = (vnf_t*)(config); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port); + + /* + char * host = 0; + char * port = "4242"; + struct addrinfo hints; + bzero(&hints, sizeof(struct addrinfo)); + //hints.ai_flags=AI_PASSIVE; + //hints.ai_flags=AI_DEFAULT; + hints.ai_family=AF_UNSPEC; + //hints.ai_family=AF_INET6; + hints.ai_socktype=SOCK_STREAM; + //hints.ai_protocol=IPPROTO_SCTP + + struct addrinfo *aiHead = 0; + + + + int result = getaddrinfo(host, port, &hints, &aiHead); + NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno); + + while(aiHead->ai_next != NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n", + aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP, + aiHead->ai_flags, AI_PASSIVE); + + char hostBfr[ NI_MAXHOST ]; + char servBfr[ NI_MAXSERV ]; + + getnameinfo(aiHead->ai_addr, + aiHead->ai_addrlen, + hostBfr, + sizeof( hostBfr ), + servBfr, + sizeof( servBfr ), + NI_NUMERICHOST | NI_NUMERICSERV ); + + switch(aiHead->ai_family) + { + case PF_INET: + { + struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr; + printf( + " ai_addr = sin_family: %d (AF_INET = %d, " + "AF_INET6 = %d)\n" + " sin_addr: %s\n" + " sin_port: %s\n", + pSadrIn->sin_family, + AF_INET, + AF_INET6, + hostBfr, + servBfr ); + } + break; + case PF_INET6: + { + struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr; + fprintf( stderr, + " ai_addr = sin6_family: %d (AF_INET = %d, " + "AF_INET6 = %d) \n" + " sin6_addr: %s\n" + " sin6_port: %s\n" + " sin6_flowinfo: %d\n" + " sin6_scope_id: %d\n", + pSadrIn6->sin6_family, + AF_INET, + AF_INET6, + hostBfr, + servBfr, + pSadrIn6->sin6_flowinfo, + pSadrIn6->sin6_scope_id); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n"); + break; + } + + aiHead = aiHead->ai_next; + } + */ + + { + int protocol; + int domain; + + if (vnf->sctp) + protocol = IPPROTO_SCTP; + else + protocol = IPPROTO_IP; + + if(config->vnf_ipv6) + { + domain = PF_INET6; + } + else + { + domain = AF_INET; + } + + // open the SCTP socket + if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno); + return 0; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock); + } + + if (vnf->sctp) + { + // configure for MSG_NOTIFICATION + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n"); + // configure the SCTP socket options + initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno) + close(p5ListenSock); + return 0; + } + noDelay = 1; + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + struct sctp_event_subscribe events; + memset( (void *)&events, 0, sizeof(events) ); + events.sctp_data_io_event = 1; + + if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno); + close(p5ListenSock); + return -1; + } + + } + + + if(config->vnf_ipv6) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons(config->vnf_p5_port); + addr6.sin6_addr = in6addr_any; + + // bind to the configured address and port + if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + } + else if(config->vnf_ipv4) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port); + addr.sin_family = AF_INET; + addr.sin_port = htons(config->vnf_p5_port); + addr.sin_addr.s_addr = INADDR_ANY; + + // bind to the configured address and port + if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + //if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock); + + // put the socket into listen mode + if (listen(p5ListenSock, 2) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n"); + + struct timeval tv; + fd_set read_fd_set; + + + int p5_idx = 0; + while(vnf->terminate == 0) + { + FD_ZERO(&read_fd_set); + + FD_SET(p5ListenSock, &read_fd_set); + int max_fd = p5ListenSock; + + tv.tv_sec = 5; + tv.tv_usec = 0; + + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + while(pnf != 0) + { + if(pnf->connected) + { + FD_SET(pnf->p5_sock, &read_fd_set); + if (pnf->p5_sock > max_fd) + { + max_fd = pnf->p5_sock; + } + } + + pnf = pnf->next; + } + + int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv); + + if(select_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno); + close(p5ListenSock); + return 0; + } + else if(select_result) + { + if(FD_ISSET(p5ListenSock, &read_fd_set)) + { + addrSize = sizeof(struct sockaddr_in); + NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n"); + + p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + + if (p5Sock < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf); + memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t)); + pnf->p5_sock = p5Sock; + pnf->p5_idx = p5_idx++; + pnf->p5_pnf_sockaddr = addr; + pnf->connected = 1; + + nfapi_vnf_pnf_list_add(config, pnf); + + // Inform mac that a pnf connection has been established + // todo : allow mac to 'accept' the connection. i.e. to + // reject it. + if(config->pnf_connection_indication != 0) + { + (config->pnf_connection_indication)(config, pnf->p5_idx); + } + + + // check the connection status + { + struct sctp_status status; + (void)memset(&status, 0, sizeof(struct sctp_status)); + socklen_t optLen = (socklen_t) sizeof(struct sctp_status); + if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno); + return -1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms); + + } + } + } + } + else + { + uint8_t delete_pnfs = 0; + + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + while(pnf != 0) + { + if(FD_ISSET(pnf->p5_sock, &read_fd_set)) + { + if(vnf_read_dispatch_message(config, pnf) == 0) + { + if(config->pnf_disconnect_indication != 0) + { + (config->pnf_disconnect_indication)(config, pnf->p5_idx); + } + + close(pnf->p5_sock); + + pnf->to_delete = 1; + delete_pnfs = 1; + } + } + + pnf = pnf->next; + } + + if(delete_pnfs) + { + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + nfapi_vnf_pnf_info_t* prev = 0; + while(pnf != 0) + { + nfapi_vnf_pnf_info_t* curr = pnf; + + if(pnf->to_delete == 1) + { + if(prev == 0) + { + config->pnf_list = pnf->next; + } + else + { + prev->next = pnf->next; + } + + pnf = pnf->next; + + free(curr); + } + else + { + prev = pnf; + pnf = pnf->next; + } + + } + + } + } + + continue; + } + else + { + // timeout + + // Should we test for socket closure here every second? + + continue; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n"); + { + nfapi_vnf_pnf_info_t* curr = config->pnf_list; + while(curr != NULL) + { + if(config->pnf_disconnect_indication) + { + (config->pnf_disconnect_indication)(config, curr->p5_idx); + } + + close(curr->p5_sock); + curr = curr->next; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n"); + close(p5ListenSock); + + return 0; + +} + +int nfapi_vnf_stop(nfapi_vnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + _this->terminate = 1; + return 0; +} + +int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_param_request_t)); +} + +int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_config_request_t)); +} + +int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_start_request_t)); +} + +int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_stop_request_t)); +} + +int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_param_request_t)); +} +int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id); + + if(phy == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s failed to find phy inforation phy_id:%d\n", __FUNCTION__, req->header.phy_id); + return -1; + } + + // set the timing parameters + req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = phy->timing_window; + req->num_tlv++; + + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = phy->timing_info_mode; + req->num_tlv++; + + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = phy->timing_info_period; + req->num_tlv++; + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_config_request_t)); +} +int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_start_request_t)); +} +int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_stop_request_t)); +} +int nfapi_vnf_measurement_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_measurement_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_measurement_request_t)); +} +int nfapi_vnf_rssi_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_rssi_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_rssi_request_t)); +} +int nfapi_vnf_cell_search_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_cell_search_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_cell_search_request_t)); +} +int nfapi_vnf_broadcast_detect_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_broadcast_detect_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_broadcast_detect_request_t)); +} +int nfapi_vnf_system_information_schedule_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_schedule_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_system_information_schedule_request_t)); +} +int nfapi_vnf_system_information_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_system_information_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_system_information_request_t)); +} +int nfapi_vnf_nmm_stop_request(nfapi_vnf_config_t* config, int p5_idx, nfapi_nmm_stop_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p4_message(_this, p5_idx, &req->header, sizeof(nfapi_nmm_stop_request_t)); +} +int nfapi_vnf_vendor_extension(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) +{ + if(config == 0 || msg == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_pack_and_send_p5_message(_this, p5_idx, msg, sizeof(nfapi_p4_p5_message_header_t)); +} + +int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy_id) +{ + vnf_t* vnf = (vnf_t*)config; + + nfapi_vnf_phy_info_t* info = (nfapi_vnf_phy_info_t*)calloc(1, sizeof(nfapi_vnf_phy_info_t)); + info->p5_idx = p5_idx; + info->phy_id = vnf->next_phy_id++; + + info->timing_window = 30; // This seems to override what gets set by the user - why??? + info->timing_info_mode = 0x03; + info->timing_info_period = 128; + + nfapi_vnf_phy_info_list_add(config, info); + + (*phy_id) = info->phy_id; + + return 0; +} diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c new file mode 100644 index 0000000000..1304176752 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -0,0 +1,1599 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include + +#include +#include +#include +#include +#include + +#include "vnf_p7.h" + +#define SYNC_CYCLE_COUNT 2 + +void* vnf_p7_malloc(vnf_p7_t* vnf_p7, size_t size) +{ + if(vnf_p7->_public.malloc) + { + return (vnf_p7->_public.malloc)(size); + } + else + { + return calloc(1, size); + } +} +void vnf_p7_free(vnf_p7_t* vnf_p7, void* ptr) +{ + if(ptr == 0) + return; + + if(vnf_p7->_public.free) + { + (vnf_p7->_public.free)(ptr); + } + else + { + free(ptr); + } +} + +void vnf_p7_codec_free(vnf_p7_t* vnf_p7, void* ptr) +{ + if(ptr == 0) + return; + + if(vnf_p7->_public.codec_config.deallocate) + { + (vnf_p7->_public.codec_config.deallocate)(ptr); + } + else + { + free(ptr); + } +} + +void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + // todo : add mutex + node->next = vnf_p7->p7_connections; + vnf_p7->p7_connections = node; +} + +nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id) +{ + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + while(curr != 0) + { + if(curr->phy_id == phy_id) + { + return curr; + } + curr = curr->next; + } + + return 0; +} + +nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id) +{ + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + nfapi_vnf_p7_connection_info_t* prev = 0; + + while(curr != 0) + { + if(curr->phy_id == phy_id) + { + if(prev == 0) + { + vnf_p7->p7_connections = curr->next; + } + else + { + prev->next = curr->next; + } + + return curr; + } + else + { + prev = curr; + curr = curr->next; + } + } + + return 0; +} + +vnf_p7_rx_message_t* vnf_p7_rx_reassembly_queue_add_segment(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len) +{ + vnf_p7_rx_message_t* msg = 0; + // attempt to find a entry for this segment + vnf_p7_rx_message_t* iterator = queue->msg_queue; + while(iterator != 0) + { + if(iterator->sequence_number == sequence_number) + { + msg = iterator; + break; + } + + iterator = iterator->next; + } + + // if found then copy data to message + if(msg != 0) + { + + msg->segments[segment_number].buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, data_len); + memcpy(msg->segments[segment_number].buffer, data, data_len); + msg->segments[segment_number].length = data_len; + + msg->num_segments_received++; + + // set the segement number if we have the last segment + if(m == 0) + msg->num_segments_expected = segment_number + 1; + } + // else add new rx message entry + else + { + // create a new message + msg = (vnf_p7_rx_message_t*)(vnf_p7_malloc(vnf_p7, sizeof(vnf_p7_rx_message_t))); + memset(msg, 0, sizeof(vnf_p7_rx_message_t)); + + msg->sequence_number = sequence_number; + msg->num_segments_expected = m ? 255 : segment_number + 1; + msg->num_segments_received = 1; + msg->rx_hr_time = vnf_get_current_time_hr(); + + msg->segments[segment_number].buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, data_len); + memcpy(msg->segments[segment_number].buffer, data, data_len); + msg->segments[segment_number].length = data_len; + + // place the message at the head of the queue + msg->next = queue->msg_queue; + queue->msg_queue = msg; + } + + return msg; +} + +void vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, vnf_p7_rx_message_t* msg) +{ + // remove message if it has the same sequence number + vnf_p7_rx_message_t* iterator = queue->msg_queue; + vnf_p7_rx_message_t* previous = 0; + + while(iterator != 0) + { + if(iterator->sequence_number == msg->sequence_number) + { + if(previous == 0) + { + queue->msg_queue = iterator->next; + } + else + { + previous->next = iterator->next; + } + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Deleting reassembly message\n"); + // delete the message + uint16_t i; + for(i = 0; i < 128; ++i) + { + if(iterator->segments[i].buffer) + vnf_p7_free(vnf_p7, iterator->segments[i].buffer); + } + vnf_p7_free(vnf_p7, iterator); + + break; + } + + previous = iterator; + iterator = iterator->next; + } +} + +void vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7_t* vnf_p7, vnf_p7_rx_reassembly_queue_t* queue, uint32_t delta) +{ + // remove all messages that are too old + vnf_p7_rx_message_t* iterator = queue->msg_queue; + vnf_p7_rx_message_t* previous = 0; + + uint32_t rx_hr_time = vnf_get_current_time_hr(); + + while(iterator != 0) + { + if(rx_hr_time - iterator->rx_hr_time > delta) + { + if(previous == 0) + { + queue->msg_queue = iterator->next; + } + else + { + previous->next = iterator->next; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Deleting stale reassembly message (%u %u %d)\n", iterator->rx_hr_time, rx_hr_time, delta); + + vnf_p7_rx_message_t* to_delete = iterator; + iterator = iterator->next; + + // delete the message + uint16_t i; + for(i = 0; i < 128; ++i) + { + if(to_delete->segments[i].buffer) + vnf_p7_free(vnf_p7, to_delete->segments[i].buffer); + } + vnf_p7_free(vnf_p7, to_delete); + + } + else + { + previous = iterator; + iterator = iterator->next; + } + } +} + +uint32_t vnf_get_current_time_hr() +{ + struct timeval now; + (void)gettimeofday(&now, NULL); + uint32_t time_hr = TIME2TIMEHR(now); + return time_hr; +} + +uint16_t increment_sfn_sf(uint16_t sfn_sf) +{ + if((sfn_sf & 0xF) == 9) + { + sfn_sf += 0x0010; + sfn_sf &= 0x3FF0; + } + else if((sfn_sf & 0xF) > 9) + { + // error should not happen + } + else + { + sfn_sf++; + } + + return sfn_sf; +} + +struct timespec timespec_delta(struct timespec start, struct timespec end) +{ + struct timespec temp; + if ((end.tv_nsec-start.tv_nsec)<0) + { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } + else + { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + return temp; +} + +static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) +{ + if(now_hr < sf_start_hr) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier that start of subframe\n"); + return 0; + } + else + { + uint32_t now_us = TIMEHR_USEC(now_hr); + uint32_t sf_start_us = TIMEHR_USEC(sf_start_hr); + + // if the us have wrapped adjust for it + if(now_hr < sf_start_us) + { + now_us += 1000000; + } + + return now_us - sf_start_us; + } +} + +uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr) +{ + uint32_t now_time_hr = vnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + + uint32_t t1 = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + + return t1; +} + + +uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr) +{ + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + + uint32_t t4 = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + + return t4; + +} + + +uint32_t calculate_transmit_timestamp(uint16_t sfn_sf, uint32_t sf_start_time_hr) +{ + uint32_t now_time_hr = vnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + + uint32_t tt = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + + return tt; +} + + +uint16_t increment_sfn_sf_by(uint16_t sfn_sf, uint8_t increment) +{ + while(increment > 0) + { + sfn_sf = increment_sfn_sf(sfn_sf); + --increment; + } + + return sfn_sf; +} + + +int send_mac_subframe_indications(vnf_p7_t* vnf_p7) +{ + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + while(curr != 0) + { + if(curr->in_sync == 1) + { + // ask for subframes in the future + uint16_t sfn_sf_adv = increment_sfn_sf_by(curr->sfn_sf, 2); + + vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf_adv); + } + + curr = curr->next; + } + + return 0; +} + +int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, uint8_t* msg, const uint32_t len) +{ + int sendto_result = sendto(vnf_p7->socket, msg, len, 0, (struct sockaddr*)&(p7_info->remote_addr), sizeof(p7_info->remote_addr)); + + if(sendto_result != len) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sendto_result %d %d\n", __FUNCTION__, sendto_result, errno); + } + + return 0; +} + +int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header) +{ + + nfapi_vnf_p7_connection_info_t* p7_connection = vnf_p7_connection_info_list_find(vnf_p7, header->phy_id); + if(p7_connection) + { + int send_result = 0; + uint8_t buffer[1024 * 32]; + + header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, p7_connection->sequence_number); + + int len = nfapi_p7_message_pack(header, buffer, sizeof(buffer), &vnf_p7->_public.codec_config); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); + + if(len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() failed to pack p7 message phy_id:%d\n", __FUNCTION__, header->phy_id); + return -1; + } + + if(len > vnf_p7->_public.segment_size) + { + // todo : consider replacing with the sendmmsg call + // todo : worry about blocking writes? + + // segmenting the transmit + int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; + int seg_body_len = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; + int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); + + int segment = 0; + int offset = NFAPI_P7_HEADER_LENGTH; + uint8_t tx_buffer[vnf_p7->_public.segment_size]; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); + for(segment = 0; segment < segment_count; ++segment) + { + uint8_t last = 0; + uint16_t size = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH; + if(segment + 1 == segment_count) + { + last = 1; + size = (msg_body_len) - (seg_body_len * segment); + } + + uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH; + + // Update the header with the m and segement + memcpy(&tx_buffer[0], buffer, NFAPI_P7_HEADER_LENGTH); + + // set the segment length + tx_buffer[4] = (segment_size & 0xFF00) >> 8; + tx_buffer[5] = (segment_size & 0xFF); + + // set the m & segment number + tx_buffer[6] = ((!last) << 7) + segment; + + memcpy(&tx_buffer[NFAPI_P7_HEADER_LENGTH], &buffer[0] + offset, size); + offset += size; + + if(vnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(tx_buffer, segment_size); + } + + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr)); + + send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size); + } + } + else + { + if(vnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(buffer, len); + } + + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr)); + + // simple case that the message fits in a single segement + send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len); + } + + p7_connection->sequence_number++; + + return send_result; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find p7 connection info for phy_id:%d\n", __FUNCTION__, header->phy_id); + return -1; + } +} + +int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) +{ + nfapi_dl_node_sync_t dl_node_sync; + memset(&dl_node_sync, 0, sizeof(dl_node_sync)); + + dl_node_sync.header.phy_id = p7_info->phy_id; + dl_node_sync.header.message_id = NFAPI_DL_NODE_SYNC; + dl_node_sync.t1 = calculate_t1(p7_info->sfn_sf, vnf_p7->sf_start_time_hr); + dl_node_sync.delta_sfn_sf = 0; + + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header); +} + +int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) +{ + + if(p7_info->in_sync == 1) + { + uint16_t dl_sync_period_mask = p7_info->dl_in_sync_period-1; + uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf); + + if ((((sfn_sf_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0) + { + vnf_build_send_dl_node_sync(vnf_p7, p7_info); + } + } + else + { + uint16_t dl_sync_period_mask = p7_info->dl_out_sync_period-1; + uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf); + + if ((((sfn_sf_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0) + { + vnf_build_send_dl_node_sync(vnf_p7, p7_info); + } + } + return 0; +} + + +void vnf_handle_harq_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_harq_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.harq_indication) + { + (vnf_p7->_public.harq_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.harq_indication_body.harq_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_crc_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.crc_indication) + { + (vnf_p7->_public.crc_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.crc_indication_body.crc_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_rx_ulsch_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_rx_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.rx_indication) + { + (vnf_p7->_public.rx_indication)(&(vnf_p7->_public), &ind); + } + } + + uint16_t i = 0; + for(i = 0; i < ind.rx_indication_body.number_of_pdus; ++i) + { + vnf_p7_codec_free(vnf_p7, ind.rx_indication_body.rx_pdu_list[i].data); + } + vnf_p7_codec_free(vnf_p7, ind.rx_indication_body.rx_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } + +} + +void vnf_handle_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_rach_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.rach_indication) + { + (vnf_p7->_public.rach_indication)(&vnf_p7->_public, &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.rach_indication_body.preamble_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + + } +} + +void vnf_handle_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_srs_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.srs_indication) + { + (vnf_p7->_public.srs_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.srs_indication_body.srs_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_rx_sr_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_sr_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.sr_indication) + { + (vnf_p7->_public.sr_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.sr_indication_body.sr_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} +void vnf_handle_rx_cqi_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_cqi_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.cqi_indication) + { + (vnf_p7->_public.cqi_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.cqi_indication_body.cqi_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.cqi_indication_body.cqi_raw_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + + } + +} + +void vnf_handle_lbt_dl_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_lbt_dl_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.lbt_dl_indication) + { + (vnf_p7->_public.lbt_dl_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.lbt_dl_indication_body.lbt_indication_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_nb_harq_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nb_harq_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.nb_harq_indication) + { + (vnf_p7->_public.nb_harq_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.nb_harq_indication_body.nb_harq_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_nrach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nrach_indication_t ind; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(ind), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + else + { + if(vnf_p7->_public.nrach_indication) + { + (vnf_p7->_public.nrach_indication)(&(vnf_p7->_public), &ind); + } + } + + vnf_p7_codec_free(vnf_p7, ind.nrach_indication_body.nrach_pdu_list); + vnf_p7_codec_free(vnf_p7, ind.vendor_extension); + } +} + +void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7, uint16_t message_id) +{ + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else if(vnf_p7->_public.allocate_p7_vendor_ext) + { + uint16_t msg_size; + nfapi_p7_message_header_t* msg = vnf_p7->_public.allocate_p7_vendor_ext(message_id, &msg_size); + + if(msg == 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n", __FUNCTION__); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &vnf_p7->_public.codec_config); + + if(unpack_result == 0) + { + if(vnf_p7->_public.vendor_ext) + vnf_p7->_public.vendor_ext(&(vnf_p7->_public), msg); + } + + if(vnf_p7->_public.deallocate_p7_vendor_ext) + vnf_p7->_public.deallocate_p7_vendor_ext(msg); + + } +} + + +void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + uint32_t now_time_hr = vnf_get_current_time_hr(); + + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_ul_node_sync: NULL parameters\n"); + return; + } + + nfapi_ul_node_sync_t ind; + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_ul_node_sync_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_node_sync\n"); + return; + } + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Received UL_NODE_SYNC phy_id:%d t1:%d t2:%d t3:%d\n", ind.header.phy_id, ind.t1, ind.t2, ind.t3); + + nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, ind.header.phy_id); + uint32_t t4 = calculate_t4(now_time_hr, phy->sfn_sf, vnf_p7->sf_start_time_hr); + + uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSFDEC - ind.t1 ; + uint32_t pnf_proc_time = ind.t3 - ind.t2; + + // divide by 2 using shift operator + uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1; + + if(!(phy->filtered_adjust)) + { + phy->latency[phy->min_sync_cycle_count] = latency; + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4, + tx_2_rx, pnf_proc_time, latency); + } + else + { + phy->latency[phy->min_sync_cycle_count] = latency; + + //if(phy->min_sync_cycle_count != SYNC_CYCLE_COUNT) + { + if (ind.t2 < phy->previous_t2 && ind.t1 > phy->previous_t1) + { + // Only t2 wrap has occurred!!! + phy->sf_offset = (NFAPI_MAX_SFNSFDEC + ind.t2) - ind.t1 - latency; + } + else if (ind.t2 > phy->previous_t2 && ind.t1 < phy->previous_t1) + { + // Only t1 wrap has occurred + phy->sf_offset = ind.t2 - ( ind.t1 + NFAPI_MAX_SFNSFDEC) - latency; + } + else + { + // Either no wrap or both have wrapped + phy->sf_offset = ind.t2 - ind.t1 - latency; + } + + if (phy->sf_offset_filtered == 0) + { + phy->sf_offset_filtered = phy->sf_offset; + } + else + { + int32_t oldFilteredValueShifted = phy->sf_offset_filtered << 5; + int32_t newOffsetShifted = phy->sf_offset << 5; + + // 1/8 of new and 7/8 of old + phy->sf_offset_filtered = ((newOffsetShifted >> 3) + ((oldFilteredValueShifted * 7) >> 3)) >> 5; + } + } + + if(1) + { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ts.tv_sec, ts.tv_nsec, ind.header.phy_id, + ind.t1, ind.t2, ind.t3, t4, + tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->sf_offset, phy->sf_offset_filtered, + (ind.t1previous_t1), (ind.t2previous_t2)); + } + + } + + if (phy->filtered_adjust && (phy->sf_offset_filtered > 1e6 || phy->sf_offset_filtered < -1e6)) + { + phy->filtered_adjust = 0; + phy->zero_count=0; + phy->min_sync_cycle_count = 2; + phy->in_sync = 0; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s - ADJUST TOO BAD - go out of filtered phy->sf_offset_filtered:%d\n", __FUNCTION__, phy->sf_offset_filtered); + } + + if(phy->min_sync_cycle_count) + phy->min_sync_cycle_count--; + + if(phy->min_sync_cycle_count == 0) + { + uint32_t curr_sfn_sf = phy->sfn_sf; + int32_t sfn_sf_dec = NFAPI_SFNSF2DEC(phy->sfn_sf); + + if(!phy->filtered_adjust) + { + int i = 0; + //phy->average_latency = 0; + for(i = 0; i < SYNC_CYCLE_COUNT; ++i) + { + phy->average_latency += phy->latency[i]; + + } + phy->average_latency /= SYNC_CYCLE_COUNT; + + phy->sf_offset = ind.t2 - (ind.t1 - phy->average_latency); + + sfn_sf_dec += (phy->sf_offset / 1000); + } + else + { + sfn_sf_dec += ((phy->sf_offset_filtered + 500) / 1000); //Round up go from microsecond to subframe(1ms) + } + + if(sfn_sf_dec < 0) + { + sfn_sf_dec += NFAPI_MAX_SFNSFDEC; + } + else if( sfn_sf_dec >= NFAPI_MAX_SFNSFDEC) + { + sfn_sf_dec -= NFAPI_MAX_SFNSFDEC; + } + + uint16_t new_sfn_sf = NFAPI_SFNSFDEC2SFNSF(sfn_sf_dec); + + + { + phy->adjustment = NFAPI_SFNSF2DEC(new_sfn_sf) - NFAPI_SFNSF2DEC(curr_sfn_sf); + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_sf_offset_filtered:%d phy->previous_sf_offset_filtered:%d phy->sf_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_sf_offset_filtered, phy->previous_sf_offset_filtered, phy->sf_offset_trend); + + phy->previous_t1 = 0; + phy->previous_t2 = 0; + + if(phy->previous_sf_offset_filtered > 0) + { + if( phy->sf_offset_filtered > phy->previous_sf_offset_filtered) + { + // pnf is getting futher ahead of vnf + //phy->sf_offset_trend = phy->sf_offset_filtered - phy->previous_sf_offset_filtered; + phy->sf_offset_trend = (phy->sf_offset_filtered + phy->previous_sf_offset_filtered)/2; + } + else + { + // pnf is getting back in sync + } + } + else if(phy->previous_sf_offset_filtered < 0) + { + if(phy->sf_offset_filtered < phy->previous_sf_offset_filtered) + { + // vnf is getting future ahead of pnf + //phy->sf_offset_trend = -(phy->sf_offset_filtered - phy->previous_sf_offset_filtered); + phy->sf_offset_trend = (-(phy->sf_offset_filtered + phy->previous_sf_offset_filtered)) /2; + } + else + { + // vnf is getting back in sync + } + } + + + int insync_minor_adjustment_1 = phy->sf_offset_trend / 6; + int insync_minor_adjustment_2 = phy->sf_offset_trend / 2; + + + if(insync_minor_adjustment_1 == 0) + insync_minor_adjustment_1 = 2; + + if(insync_minor_adjustment_2 == 0) + insync_minor_adjustment_2 = 10; + + if(!phy->filtered_adjust) + { + if(phy->adjustment < 10) + { + phy->zero_count++; + + if(phy->zero_count >= 10) + { + phy->filtered_adjust = 1; + phy->zero_count = 0; + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF SFN/SF switching to filtered mode\n"); + } + } + else + { + phy->zero_count = 0; + } + } + else + { + // Fine level of adjustment + if (phy->adjustment == 0) + { + if (phy->zero_count >= 10) + { + if(phy->in_sync == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id); + + if(vnf_p7->_public.sync_indication) + (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1); + } + + phy->in_sync = 1; + } + else + { + phy->zero_count++; + } + + if(phy->in_sync) + { + // in sync + if(phy->sf_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_1; //25; + phy->insync_minor_adjustment_duration = ((phy->sf_offset_filtered) / insync_minor_adjustment_1); + } + else if(phy->sf_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_1); //25; + phy->insync_minor_adjustment_duration = (((phy->sf_offset_filtered) / -(insync_minor_adjustment_1))); + } + else + { + phy->insync_minor_adjustment = 0; + } + + if(phy->insync_minor_adjustment != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (sf_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, + phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, + phy->sf_offset_filtered, + insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend, + NFAPI_SFNSF2DEC(new_sfn_sf), + NFAPI_SFNSF2DEC(curr_sfn_sf), + phy->adjustment); + } + } + } + else + { + if (phy->in_sync) + { + if(phy->adjustment == 0) + { + } + else if(phy->adjustment > 0) + { + // VNF is slow + //if(phy->adjustment == 1) + { + // + if(phy->sf_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_2; + phy->insync_minor_adjustment_duration = 2 * ((phy->sf_offset_filtered - 250) / insync_minor_adjustment_2); + } + else if(phy->sf_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_2); + phy->insync_minor_adjustment_duration = 2 * ((phy->sf_offset_filtered + 250) / -(insync_minor_adjustment_2)); + } + + } + //else + { + // out of sync? + } + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (adjustment:%d sf_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, + phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->sf_offset_filtered, + insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend, + NFAPI_SFNSF2DEC(new_sfn_sf), + NFAPI_SFNSF2DEC(curr_sfn_sf), + phy->adjustment); + + } + else if(phy->adjustment < 0) + { + // VNF is fast + //if(phy->adjustment == -1) + { + // + if(phy->sf_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_2; + phy->insync_minor_adjustment_duration = 2 * ((phy->sf_offset_filtered - 250) / insync_minor_adjustment_2); + } + else if(phy->sf_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_2); + phy->insync_minor_adjustment_duration = 2 * ((phy->sf_offset_filtered + 250) / -(insync_minor_adjustment_2)); + } + } + //else + { + // out of sync? + } + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (adjustment:%d sf_offset_filtered:%d) %d %d %d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, + phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->sf_offset_filtered, + insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend); + } + + /* + if (phy->adjustment > 10 || phy->adjustment < -10) + { + phy->zero_count++; // Add one to the getting out of sync counter + } + else + { + phy->zero_count = 0; // Small error - zero the out of sync counter + } + + if (phy->zero_count >= 10) // If we have had 10 consecutive large errors - drop out of sync + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "we have fallen out of sync...\n"); + //pP7SockInfo->syncAchieved = 0; + } + */ + } + } + } + + + if(phy->in_sync == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", + ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"), + NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment, + phy->filtered_adjust ? "FILTERED" : "ABSOLUTE", + phy->zero_count, + phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC"); + + phy->sfn_sf = new_sfn_sf; + } + } + + // reset for next cycle + phy->previous_sf_offset_filtered = phy->sf_offset_filtered; + phy->min_sync_cycle_count = 2; + phy->sf_offset_filtered = 0; + phy->sf_offset = 0; + } + else + { + phy->previous_t1 = ind.t1; + phy->previous_t2 = ind.t2; + } +} + +void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_timing_info: NULL parameters\n"); + return; + } + + nfapi_timing_info_t ind; + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack timing_info\n"); + return; + } + + if (vnf_p7 && vnf_p7->p7_connections) + { + int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); + if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); + } + } +} + +void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + nfapi_p7_message_header_t header; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + switch (header.message_id) + { + case NFAPI_UL_NODE_SYNC: + vnf_handle_ul_node_sync(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_TIMING_INFO: + vnf_handle_timing_info(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_HARQ_INDICATION: + vnf_handle_harq_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_CRC_INDICATION: + vnf_handle_crc_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_ULSCH_INDICATION: + vnf_handle_rx_ulsch_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RACH_INDICATION: + vnf_handle_rach_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_SRS_INDICATION: + vnf_handle_srs_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_SR_INDICATION: + vnf_handle_rx_sr_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_CQI_INDICATION: + vnf_handle_rx_cqi_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_LBT_DL_INDICATION: + vnf_handle_lbt_dl_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_NB_HARQ_INDICATION: + vnf_handle_nb_harq_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_NRACH_INDICATION: + vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + default: + { + if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + vnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, vnf_p7, header.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unknown message ID %d\n", header.message_id); + } + } + break; + } +} + +void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + nfapi_p7_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, vnf_p7); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + if(vnf_p7->_public.checksum_enabled) + { + uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen); + if(checksum != messageHeader.checksum) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d msg:%d len:%d\n", checksum, messageHeader.checksum, messageHeader.message_id, recvMsgLen); + return; + } + } + + uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence); + uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence); + uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence); + + + if(m == 0 && segment_num == 0) + { + // we have a complete message + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + //vnf_dispatch_p7_message(&messageHeader, pRecvMsg, recvMsgLen, vnf_p7); + vnf_dispatch_p7_message(pRecvMsg, recvMsgLen, vnf_p7); + } + else + { + nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, messageHeader.phy_id); + + if(phy) + { + vnf_p7_rx_message_t* rx_msg = vnf_p7_rx_reassembly_queue_add_segment(vnf_p7, &(phy->reassembly_queue), sequence_num, segment_num, m, pRecvMsg, recvMsgLen); + + if(rx_msg->num_segments_received == rx_msg->num_segments_expected) + { + // send the buffer on + uint16_t i = 0; + uint16_t length = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0); + } + + if(phy->reassembly_buffer_size < length) + { + vnf_p7_free(vnf_p7, phy->reassembly_buffer); + phy->reassembly_buffer = 0; + } + + if(phy->reassembly_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing VNF_P7 Reassembly buffer %d->%d\n", phy->reassembly_buffer_size, length); + phy->reassembly_buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, length); + + if(phy->reassembly_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length); + return; + } + + phy->reassembly_buffer_size = length; + } + + uint16_t offset = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + if(i == 0) + { + memcpy(phy->reassembly_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length); + offset += rx_msg->segments[i].length; + } + else + { + memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH); + offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH; + } + } + + + //pnf_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time); + vnf_dispatch_p7_message(phy->reassembly_buffer, length , vnf_p7); + + + // delete the structure + vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7, &(phy->reassembly_queue), rx_msg); + } + + vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 1000); + } + else + { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Unknown phy id %d\n", messageHeader.phy_id); + } + } +} + +int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7) +{ + int recvfrom_result = 0; + struct sockaddr_in remote_addr; + socklen_t remote_addr_size = sizeof(remote_addr); + + do + { + // peek the header + uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH]; + recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size); + + if(recvfrom_result > 0) + { + // get the segment size + nfapi_p7_message_header_t header; + if(nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return -1; + } + + // resize the buffer if we have a large segment + if(header.message_length > vnf_p7->rx_message_buffer_size) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); + vnf_p7->rx_message_buffer = realloc(vnf_p7->rx_message_buffer, header.message_length); + vnf_p7->rx_message_buffer_size = header.message_length; + } + + // read the segment + recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); + + // todo : how to handle incomplete readfroms, need some sort of buffer/select + + if(recvfrom_result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom returned 0\n"); + } + else if(recvfrom_result != header.message_length) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "did not receive the entire message %d %d\n", recvfrom_result, header.message_length); + + recvfrom_result += recvfrom(vnf_p7->socket, &vnf_p7->rx_message_buffer[recvfrom_result], header.message_length - recvfrom_result, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); + + } + + + if(recvfrom_result > 0) + { + vnf_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom failed %d %d\n", recvfrom_result, errno); + } + } + + if(recvfrom_result == -1) + { + if(errno == EAGAIN || errno == EWOULDBLOCK) + { + // return to the select + //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + } + } + while(recvfrom_result > 0); + + return 0; +} + +void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header) +{ + switch(header->message_id) + { + case NFAPI_HARQ_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_harq_indication_t*)(header))->harq_indication_body.harq_pdu_list); + } + break; + case NFAPI_CRC_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_crc_indication_t*)(header))->crc_indication_body.crc_pdu_list); + } + break; + case NFAPI_RX_ULSCH_INDICATION: + { + nfapi_rx_indication_t* rx_ind = (nfapi_rx_indication_t*)(header); + uint16_t i = 0; + for(i = 0; i < rx_ind->rx_indication_body.number_of_pdus; ++i) + { + vnf_p7_codec_free(vnf_p7, rx_ind->rx_indication_body.rx_pdu_list[i].data); + } + + vnf_p7_codec_free(vnf_p7, rx_ind->rx_indication_body.rx_pdu_list); + } + break; + case NFAPI_RACH_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_rach_indication_t*)(header))->rach_indication_body.preamble_list); + } + break; + case NFAPI_SRS_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_srs_indication_t*)(header))->srs_indication_body.srs_pdu_list); + } + break; + case NFAPI_RX_SR_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_sr_indication_t*)(header))->sr_indication_body.sr_pdu_list); + } + break; + case NFAPI_RX_CQI_INDICATION: + { + vnf_p7_codec_free(vnf_p7, ((nfapi_cqi_indication_t*)(header))->cqi_indication_body.cqi_pdu_list); + vnf_p7_codec_free(vnf_p7, ((nfapi_cqi_indication_t*)(header))->cqi_indication_body.cqi_raw_pdu_list); + } + break; + } + + vnf_p7_free(vnf_p7, header); + +} + +void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu) +{ + vnf_p7_free(vnf_p7, pdu); +} + diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c new file mode 100644 index 0000000000..a35d8e3c1d --- /dev/null +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -0,0 +1,562 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vnf_p7.h" + +#define FAPI2_IP_DSCP 0 + +nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create() +{ + vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t)); + + if(_this == 0) + return 0; + + // todo : initialize + _this->_public.segment_size = 1400; + _this->_public.max_num_segments = 8; + _this->_public.checksum_enabled = 1; + + _this->_public.malloc = &malloc; + _this->_public.free = &free; + + _this->_public.codec_config.allocate = &malloc; + _this->_public.codec_config.deallocate = &free; + + + return &(_this->_public); +} + +void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config) +{ + free(config); +} + + +struct timespec timespec_add(struct timespec lhs, struct timespec rhs) +{ + struct timespec result; + + result.tv_sec = lhs.tv_sec + rhs.tv_sec; + result.tv_nsec = lhs.tv_nsec + rhs.tv_nsec; + + if(result.tv_nsec > 1e9) + { + result.tv_sec++; + result.tv_nsec-= 1e9; + } + + return result; +} + +struct timespec timespec_sub(struct timespec lhs, struct timespec rhs) +{ + struct timespec result; + if ((lhs.tv_nsec-rhs.tv_nsec)<0) + { + result.tv_sec = lhs.tv_sec-rhs.tv_sec-1; + result.tv_nsec = 1000000000+lhs.tv_nsec-rhs.tv_nsec; + } + else + { + result.tv_sec = lhs.tv_sec-rhs.tv_sec; + result.tv_nsec = lhs.tv_nsec-rhs.tv_nsec; + } + return result; +} + +// monitor the p7 endpoints and the timing loop and +// send indications to mac +int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) +{ + if(config == 0) + return -1; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + + // Create p7 receive udp port + // todo : this needs updating for Ipv6 + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); + + // open the UDP socket + if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n"); + + // configure the UDP socket options + int iptos_value = FAPI2_IP_DSCP << 2; + if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n"); + + // Create the address structure + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(config->port); + addr.sin_addr.s_addr = INADDR_ANY; + + // bind to the configured port + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + //if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n"); + + + //struct timespec original_pselect_timeout; + struct timespec pselect_timeout; + pselect_timeout.tv_sec = 0; + pselect_timeout.tv_nsec = 1000000; // ns in a 1 us + + + struct timespec pselect_start; + struct timespec pselect_stop; + + //struct timespec sf_end; + + long last_millisecond = -1; + + + struct timespec sf_duration; + sf_duration.tv_sec = 0; + sf_duration.tv_nsec = 1e6; // We want 1ms pause + + struct timespec sf_start; + clock_gettime(CLOCK_MONOTONIC, &sf_start); + long millisecond = sf_start.tv_nsec / 1e6; + sf_start = timespec_add(sf_start, sf_duration); + NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + + while(vnf_p7->terminate == 0) + { + fd_set rfds; + int maxSock = 0; + FD_ZERO(&rfds); + int selectRetval = 0; + + // Add the p7 socket + FD_SET(vnf_p7->socket, &rfds); + maxSock = vnf_p7->socket; + + clock_gettime(CLOCK_MONOTONIC, &pselect_start); + //long millisecond = pselect_start.tv_nsec / 1e6; + + if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec); + + + if((pselect_start.tv_sec > sf_start.tv_sec) || + ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec))) + { + // overran the end of the subframe we do not want to wait + pselect_timeout.tv_sec = 0; + pselect_timeout.tv_nsec = 0; + + //struct timespec overrun = timespec_sub(pselect_start, sf_start); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec); + } + else + { + // still time before the end of the subframe wait + pselect_timeout = timespec_sub(sf_start, pselect_start); + +#if 0 + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sf_start:%d.%ld pselect_start:%d.%ld pseclect_timeout:%d.%ld\n", + __FUNCTION__, + sf_start.tv_sec, sf_start.tv_nsec, + pselect_start.tv_sec, pselect_start.tv_nsec, + pselect_timeout.tv_sec, pselect_timeout.tv_nsec); +#endif + } + +//original_pselect_timeout = pselect_timeout; + + // detemine how long to sleep in ns before the start of the next 1ms + //pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000); + + //uint8_t underrun_possible =0; + + // if we are not sleeping until the next milisecond due to the + // insycn minor adjment flag it so we don't consider it an error + //uint8_t underrun_possible =0; + /* + { + nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; + if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment, + pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000)) + if(phy->insync_minor_adjustment > 0) + { + // todo check we don't go below 0 + if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec) + pselect_timeout.tv_nsec = 0; + else + pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000); + + + //underrun_possible = 1; + } + else if(phy->insync_minor_adjustment < 0) + { + // todo check we don't go below 0 + pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000); + } + + //phy->insync_minor_adjustment = 0; + phy->insync_minor_adjustment_duration--; + } + } + */ + + +//long wraps = pselect_timeout.tv_nsec % 1e9; + + + selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL); + + clock_gettime(CLOCK_MONOTONIC, &pselect_stop); + + nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; + +if (selectRetval==-1 && errno == 22) +{ + NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n", + pselect_timeout.tv_sec, pselect_timeout.tv_nsec, + phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, + sf_duration.tv_sec, sf_duration.tv_nsec); +} +#if 0 + if (selectRetval != 0 || phy->insync_minor_adjustment_duration != 0) + NFAPI_TRACE(NFAPI_TRACE_NOTE, "pselect()=%d maxSock:%d vnf_p7->socket:%d pselect_timeout:%u.%u original_pselect_timeout:%u.%u\n", + selectRetval, maxSock, vnf_p7->socket, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, + original_pselect_timeout.tv_sec, original_pselect_timeout.tv_nsec); +#endif + + if(selectRetval == 0) + { + // calculate the start of the next subframe + sf_start = timespec_add(sf_start, sf_duration); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + + if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0) + { + long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000); + + sf_start.tv_nsec -= insync_minor_adjustment_ns; + +#if 1 + if (sf_start.tv_nsec > 1e9) + { + sf_start.tv_sec++; + sf_start.tv_nsec-=1e9; + } + else if (sf_start.tv_nsec < 0) + { + sf_start.tv_sec--; + sf_start.tv_nsec+=1e9; + } +#else + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec); + if(phy->insync_minor_adjustment > 0) + { + // decrease the subframe duration a little + if (sf_start.tv_nsec > insync_minor_adjustment_ns) + sf_start.tv_nsec -= insync_minor_adjustment_ns; + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns); + sf_start.tv_sec--; + sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns; + } + } + else if(phy->insync_minor_adjustment < 0) + { + // todo check we don't go below 0 + // increase the subframe duration a little + sf_start.tv_nsec += insync_minor_adjustment_ns; + + if (sf_start.tv_nsec < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec); + sf_start.tv_sec++; + sf_start.tv_nsec += 1e9; + } + } +#endif + + //phy->insync_minor_adjustment = 0; + phy->insync_minor_adjustment_duration--; + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n", + phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration); + + if (phy->insync_minor_adjustment_duration==0) + { + phy->insync_minor_adjustment = 0; + } + } + /* + long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6; + if(millisecond == pselect_stop_millisecond) + { + // we have woke up in the same subframe + if(underrun_possible == 0) + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec); + } + else if(((millisecond + 1) % 1000) != pselect_stop_millisecond) + { + // we have overrun the subframe + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond); + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond); + } + last_millisecond = millisecond; + */ + + millisecond ++; + } + } + else + { + // we have overrun the subframe advance to go and collect $200 + if((millisecond - last_millisecond) > 3) + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1); + + last_millisecond = ( last_millisecond + 1 ) % 1000; + selectRetval = 0; + } + + if(selectRetval == 0) + { + vnf_p7->sf_start_time_hr = vnf_get_current_time_hr(); + + // pselect timed out + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + + while(curr != 0) + { + curr->sfn_sf = increment_sfn_sf(curr->sfn_sf); + + vnf_sync(vnf_p7, curr); + + curr = curr->next; + } + + send_mac_subframe_indications(vnf_p7); + + } + else if(selectRetval > 0) + { + // have a p7 message + if(FD_ISSET(vnf_p7->socket, &rfds)) + { + vnf_p7_read_dispatch_message(vnf_p7); + } + } + else + { + // pselect error + if(selectRetval == -1 && errno == EINTR) + { + // a sigal was received. + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond); + // should we exit now? + if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration + { + usleep(100000); + } + } + } + + } + + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n"); + close(vnf_p7->socket); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__); + + return 0; +} + +int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config) +{ + if(config == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + vnf_p7->terminate =1; + return 0; +} + +int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p phy_id:%d pnf_addr:%s pnf_p7_port:%d)\n", __FUNCTION__, config, phy_id, pnf_p7_addr, pnf_p7_port); + + if(config == 0) + { + return -1; + } + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + + nfapi_vnf_p7_connection_info_t* node = (nfapi_vnf_p7_connection_info_t*)malloc(sizeof(nfapi_vnf_p7_connection_info_t)); + + memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t)); + node->phy_id = phy_id; + node->in_sync = 0; + node->dl_out_sync_offset = 30; + node->dl_out_sync_period = 10; + node->dl_in_sync_offset = 30; + node->dl_in_sync_period = 512; + node->sfn_sf = 0; + + node->min_sync_cycle_count = 8; + + // save the remote endpoint information + node->remote_addr.sin_family = AF_INET; + node->remote_addr.sin_port = htons(pnf_p7_port); + node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr); + + vnf_p7_connection_info_list_add(vnf_p7, node); + + return 0; +} + +int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id) +{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(phy_id:%d)\n", __FUNCTION__, phy_id); + + if(config == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + + nfapi_vnf_p7_connection_info_t* to_delete = vnf_p7_connection_info_list_delete(vnf_p7, phy_id); + + if(to_delete) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(phy_id:%d) deleting connection info\n", __FUNCTION__, phy_id); + free(to_delete); + } + + return 0; +} +int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req); + + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} + +int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} +int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} +int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} +int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} +int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header) +{ + if(config == 0 || header == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, header); +} + + +int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header) +{ + if(config == 0 || header == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + vnf_p7_release_msg(vnf_p7, header); + + return 0; + +} + +int nfapi_vnf_p7_release_pdu(nfapi_vnf_p7_config_t* config, void* pdu) +{ + if(config == 0 || pdu == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + vnf_p7_release_pdu(vnf_p7, pdu); + + return 0; +} diff --git a/nfapi/open-nFAPI/vnf/tests/Makefile.am b/nfapi/open-nFAPI/vnf/tests/Makefile.am new file mode 100644 index 0000000000..0c8163102c --- /dev/null +++ b/nfapi/open-nFAPI/vnf/tests/Makefile.am @@ -0,0 +1,30 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +#vnf unit test +#AUTOMAKE_OPTIONS=subdir-objects + +AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/vnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror + +check_PROGRAMS= test_vnf + +test_vnf_SOURCES = vnf_cunit_main.c ../..//common/src/debug.c +test_vnf_LDADD=$(top_builddir)/vnf/libnfapi_vnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit + +LOG_DRIVER = $(top_srcdir)/tap-driver.sh +TESTS=test_vnf +EXTRA_DIST = $(TESTS) + diff --git a/nfapi/open-nFAPI/vnf/tests/vnf_cunit_main.c b/nfapi/open-nFAPI/vnf/tests/vnf_cunit_main.c new file mode 100644 index 0000000000..4df5da7c26 --- /dev/null +++ b/nfapi/open-nFAPI/vnf/tests/vnf_cunit_main.c @@ -0,0 +1,1497 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include "CUnit.h" +#include "Basic.h" +#include "Automated.h" +//#include "CUnit/Console.h" + +#include "nfapi_interface.h" +#include "nfapi_vnf_interface.h" +#include "nfapi.h" +#include // for printf +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" +#include +#include + +/* Test Suite setup and cleanup functions: */ + +int init_suite(void) { return 0; } +int clean_suite(void) { return 0; } + +#define MAX_PACKED_MESSAGE_SIZE 8192 + +#define SFNSF2SFN(_sfnsf) ((_sfnsf) >> 4) +#define SFNSF2SF(_sfnsf) ((_sfnsf) & 0xF) + +typedef struct +{ + uint8_t enabled; + uint8_t started; + uint16_t phy_id; + + int p7_rx_port; + char* p7_rx_addr; + + struct sockaddr_in p7_rx_sockaddr; + int p7_rx_sock; + + struct sockaddr_in p7_tx_sockaddr; + int p7_tx_sock; +} pnf_test_config_phy_t; + +typedef struct +{ + uint8_t enabled; + + char* vnf_p5_addr; + int vnf_p5_port; + + struct sockaddr_in p5_tx_sockaddr; + int p5_sock; + + int p7_rx_port_base; + + pnf_test_config_phy_t phys[4]; + +} pnf_test_config_t; + +pnf_test_config_t pnf_test_config[5]; + +typedef struct +{ + uint8_t enabled; + uint8_t state; + uint16_t p5_idx; + uint16_t phy_id; + + uint8_t vnf_idx; + //struct sockaddr_in p7_rx_sockaddr; + struct sockaddr_in p7_tx_sockaddr; + +} vnf_test_config_phy_t; + +typedef struct +{ + uint8_t enabled; + pthread_t thread; + + char* vnf_p7_addr; + int vnf_p7_port; + + struct sockaddr_in p7_rx_sockaddr; + + nfapi_vnf_p7_config_t* config; + + uint8_t max_phys; + uint8_t phy_count; + //uint8_t phy_ids[4]; + +} vnf_test_config_vnf_t; + +typedef struct +{ + char* p5_addr; + int p5_port; + + pthread_t thread; + + vnf_test_config_vnf_t vnfs[2]; + + uint8_t phy_count; + vnf_test_config_phy_t phys[5]; + + nfapi_vnf_config_t* p5_vnf_config; + +} vnf_test_config_t; + +vnf_test_config_t vnf_test_config[5]; + +void reset_test_configs() +{ + memset(&pnf_test_config, 0, sizeof(pnf_test_config)); + memset(&vnf_test_config, 0, sizeof(vnf_test_config)); +} + +void pnf_create_p5_sock(pnf_test_config_t* config) +{ + config->p5_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + config->p5_tx_sockaddr.sin_family = AF_INET; + config->p5_tx_sockaddr.sin_port = htons(config->vnf_p5_port); + config->p5_tx_sockaddr.sin_addr.s_addr = inet_addr(config->vnf_p5_addr); +} + +void pnf_p5_connect(pnf_test_config_t* config) +{ + int connect_result = connect(config->p5_sock, (struct sockaddr *)&config->p5_tx_sockaddr, sizeof(config->p5_tx_sockaddr) ); + + printf("connect_result %d %d\n", connect_result, errno); +} + +pnf_test_config_phy_t* find_pnf_phy_config(pnf_test_config_t* config, uint16_t phy_id) +{ + int i = 0; + for(i = 0; i < 4; ++i) + { + if(config->phys[i].phy_id == phy_id) + return &(config->phys[i]); + } + + return 0; +} + +vnf_test_config_phy_t* find_vnf_phy_config(vnf_test_config_t* config, uint16_t phy_id) +{ + int i = 0; + for(i = 0; i < 4; ++i) + { + if(config->phys[i].phy_id == phy_id) + return &(config->phys[i]); + } + + return 0; +} + + + + +/************* Test case functions ****************/ + + +void vnf_test_start_no_config(void) +{ + int result = nfapi_vnf_start(0); + CU_ASSERT_EQUAL(result, -1); +} + +void* vnf_test_start_thread(void* ptr) +{ + int result = nfapi_vnf_start((nfapi_vnf_config_t*)ptr); + return (void*)(intptr_t)result; +} + +int pnf_connection_indication_called = 0; +int pnf_connection_indication(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF] pnf_connection_indication p5_idx:%d\n", p5_idx); + pnf_connection_indication_called++; + + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + req.header.message_length = 0; + + nfapi_vnf_pnf_param_req(config, p5_idx, &req); + + return 1; +} + +int pnf_disconnect_indication(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF] pnf_disconnect_indication p5_idx:%d\n", p5_idx); + pnf_connection_indication_called++; + + vnf_test_config_t* test_config = (vnf_test_config_t*)(config->user_data); + printf("[VNF] pnf_disconnect_indication user_data %p\n", config->user_data); + + int i = 0; + for(i = 0; i < test_config->phy_count; ++i) + { + vnf_test_config_phy_t* phy = &test_config->phys[i]; + vnf_test_config_vnf_t* vnf = &test_config->vnfs[phy->p5_idx]; + + // need to send stop request/response + + nfapi_vnf_p7_del_pnf((vnf->config), phy->phy_id); + vnf->phy_count--; + } + + + for(i = 0; i < 2; ++i) + { + vnf_test_config_vnf_t* vnf = &test_config->vnfs[i]; + printf("[VNF] pnf_disconnect_indication phy_count:%d\n", vnf->phy_count); + if(vnf->enabled == 1) + { + nfapi_vnf_p7_stop(vnf->config); + //vnf->config->terminate = 1; + + int* result; + printf("[VNF] waiting for vnf p7 thread to exit\n"); + pthread_join((vnf->thread), (void**)&result); + CU_ASSERT_EQUAL(result, 0); + + vnf->enabled = 0; + } + } + + return 1; +} + +int send_p5_message(int p5Sock, nfapi_p4_p5_message_header_t* msg, unsigned msg_size, struct sockaddr_in* addr, socklen_t addr_size) +{ + char buffer[256]; + int encoded_size = nfapi_p5_message_pack(msg, msg_size, buffer, sizeof(buffer), 0); + int result = sendto(p5Sock, buffer, encoded_size, 0, (struct sockaddr*)addr, addr_size); + (void)result; + return 0; +} + +int recv_p5_message(int p5Sock, nfapi_p4_p5_message_header_t* msg, unsigned msg_size) +{ + struct sockaddr_in addr2; + socklen_t addr2len; + char buffer2[256]; + int result2 = recvfrom(p5Sock, buffer2, sizeof(buffer2), 0, (struct sockaddr*)&addr2, &addr2len); + + int unpack_result = nfapi_p5_message_unpack(buffer2, result2, msg, msg_size, 0); //, sizeof(resp)); + (void)unpack_result; + return 0; +} + +int send_pnf_param_response(pnf_test_config_t* config) //int p5Sock, struct sockaddr_in* addr, socklen_t addr_size) +{ + nfapi_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + + resp.header.message_length = 0; + resp.error_code = NFAPI_MSG_OK; + + //send_p5_message(p5Sock, &resp, sizeof(resp), addr, addr_size); + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int create_p7_rx_socket(const char* addr, int port) +{ + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + struct sockaddr_in sock_addr; + sock_addr.sin_family = AF_INET; + sock_addr.sin_port = htons(port); + + if(addr == 0) + sock_addr.sin_addr.s_addr = INADDR_ANY; + else + sock_addr.sin_addr.s_addr = inet_addr(addr); + + int bind_result = bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); + if(bind_result != 0) + { + printf("Failed to bind p7 rx socket %d(%d) to %s:%d\n", bind_result, errno, addr, port); + } + + + return fd; +} + +int create_p7_tx_socket() +{ + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + return fd; +} + +int send_param_response(pnf_test_config_t* config, uint16_t phy_id) +{ + nfapi_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PARAM_RESPONSE; + resp.header.phy_id = phy_id; + + pnf_test_config_phy_t* phy = find_pnf_phy_config(config, phy_id); + + resp.error_code = NFAPI_MSG_OK; + + resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; + resp.nfapi_config.p7_pnf_port.value = phy->p7_rx_port; + + struct sockaddr_in pnf_p7_sockaddr; + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(phy->p7_rx_addr); + + resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + memcpy(&resp.nfapi_config.p7_pnf_address_ipv4.address[0], &pnf_p7_sockaddr.sin_addr.s_addr, 4); + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int receive_pnf_param_request(pnf_test_config_t* config) +{ + nfapi_pnf_param_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_PNF_PARAM_REQUEST); + if(req.header.message_id == NFAPI_PNF_PARAM_REQUEST) + { + printf("[PNF] nfapi_pnf_param_request\n"); + } + return 0; +} + +int receive_param_request(pnf_test_config_t* config) +{ + nfapi_param_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_PARAM_REQUEST); + if(req.header.message_id == NFAPI_PARAM_REQUEST) + { + printf("[PNF] nfapi_param_request phy_id:%d\n", req.header.phy_id); + } + else + { + printf("[PNF] ERROR, unexpected message %d phy_id:%d\n", req.header.message_id, req.header.phy_id); + } + return req.header.phy_id; +} + +int send_pnf_config_response(pnf_test_config_t* config) +{ + nfapi_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.header.message_length = 0; + resp.error_code = NFAPI_MSG_OK; + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int send_config_response(pnf_test_config_t* config, uint16_t phy_id) +{ + nfapi_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.message_length = 0; + resp.header.phy_id = phy_id; + resp.error_code = NFAPI_MSG_OK; + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + + +int receive_pnf_config_request(pnf_test_config_t* config) +{ + nfapi_pnf_config_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_PNF_CONFIG_REQUEST); + if(req.header.message_id == NFAPI_PNF_CONFIG_REQUEST) + { + printf("decoded nfapi_pnf_config_request\n"); + + int i = 0; + for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + nfapi_phy_rf_config_info_t* info = &(req.pnf_phy_rf_config.phy_rf_config[i]); + printf("adding pnf phy %d id %d\n", i, info->phy_id); + + config->phys[i].enabled = 1; + config->phys[i].phy_id = info->phy_id; + } + } + return 0; +} + +int receive_config_request(pnf_test_config_t* config) +{ + nfapi_config_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_CONFIG_REQUEST); + if(req.header.message_id == NFAPI_CONFIG_REQUEST) + { + printf("[PNF] nfapi_config_request phy_id:%d\n", req.header.phy_id); + + pnf_test_config_phy_t* phy = find_pnf_phy_config(config, req.header.phy_id); + + // todo verify that this is the same as a vnf config? + phy->p7_tx_sockaddr.sin_family = AF_INET; + phy->p7_tx_sockaddr.sin_port = htons(req.nfapi_config.p7_vnf_port.value); + memcpy(&phy->p7_tx_sockaddr.sin_addr.s_addr, &req.nfapi_config.p7_vnf_address_ipv4.address, 4); + phy->p7_tx_sock = create_p7_tx_socket(); + + + printf("[PNF] vnf p7 address %s:%d\n", inet_ntoa(phy->p7_tx_sockaddr.sin_addr), ntohs(phy->p7_tx_sockaddr.sin_port)); + + return req.header.phy_id; + } + + return NFAPI_PHY_ID_NA; +} + +int send_pnf_start_response(pnf_test_config_t* config) +{ + nfapi_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.header.message_length = 0; + resp.error_code = NFAPI_MSG_OK; + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int send_start_response(pnf_test_config_t* config, uint16_t phy_id) +{ + nfapi_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.message_length = 0; + resp.header.phy_id = phy_id; + resp.error_code = NFAPI_MSG_OK; + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int receive_pnf_start_request(pnf_test_config_t* config) +{ + nfapi_pnf_start_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_PNF_START_REQUEST); + if(req.header.message_id == NFAPI_PNF_START_REQUEST) + { + printf("decoded nfapi_pnf_start_request\n"); + + int phy_idx = 0; + for(phy_idx = 0; phy_idx < 4; ++phy_idx) + { + if(config->phys[phy_idx].enabled) + { + pnf_test_config_phy_t* phy = &(config->phys[phy_idx]); + phy->p7_rx_port = config->p7_rx_port_base + phy_idx; + phy->p7_rx_addr = "127.0.0.1"; + } + } + } + return 0; +} + +int receive_start_request(pnf_test_config_t* config) +{ + nfapi_start_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_START_REQUEST); + if(req.header.message_id == NFAPI_START_REQUEST) + { + printf("[PNF] nfapi_start_request\n"); + + pnf_test_config_phy_t* phy = find_pnf_phy_config(config, req.header.phy_id); + printf("[PNF] creating p7 rx socket %s:%d\n", phy->p7_rx_addr, phy->p7_rx_port); + phy->p7_rx_sock = create_p7_rx_socket(phy->p7_rx_addr, phy->p7_rx_port); + phy->started = 1; + + } + + return req.header.phy_id; +} + +int send_pnf_stop_response(pnf_test_config_t* config, uint16_t phy_id) +{ + printf("pnf_stop_response\n"); + nfapi_pnf_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; + resp.header.message_length = 0; + resp.error_code = NFAPI_MSG_OK; + + send_p5_message(config->p5_sock, &resp.header, sizeof(resp), &(config->p5_tx_sockaddr), sizeof(config->p5_tx_sockaddr)); + return 0; +} + +int receive_pnf_stop_request(pnf_test_config_t* config) +{ + printf("pnf_stop_request\n"); + nfapi_pnf_stop_request_t req; + recv_p5_message(config->p5_sock, &req.header, sizeof(req)); + + CU_ASSERT_EQUAL(req.header.message_id, NFAPI_PNF_STOP_REQUEST); + if(req.header.message_id == NFAPI_PNF_STOP_REQUEST) + { + printf("decoded nfapi_pnf_stop_request\n"); + } + return 0; +} +int pnf_param_response(nfapi_vnf_config_t* config, int p5_idx,nfapi_pnf_param_response_t* response) +{ + printf("[VNF] pnf_param_response p5_idx:%d\n", p5_idx); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + uint16_t phy_id; + nfapi_vnf_allocate_phy(config, p5_idx, &phy_id); + + nfapi_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + req.header.message_length = 0; + req.header.phy_id = NFAPI_PHY_ID_NA; + + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 2; + nfapi_vnf_allocate_phy(config, p5_idx, &req.pnf_phy_rf_config.phy_rf_config[0].phy_id); + nfapi_vnf_allocate_phy(config, p5_idx, &req.pnf_phy_rf_config.phy_rf_config[1].phy_id); + + uint16_t i = vnf_test_config[0].phy_count; + + vnf_test_config[0].phys[i].enabled = 1; + vnf_test_config[0].phys[i].p5_idx = p5_idx; + vnf_test_config[0].phys[i].phy_id = req.pnf_phy_rf_config.phy_rf_config[0].phy_id; + + i++; + + vnf_test_config[0].phys[i].enabled = 1; + vnf_test_config[0].phys[i].p5_idx = p5_idx; + vnf_test_config[0].phys[i].phy_id = req.pnf_phy_rf_config.phy_rf_config[1].phy_id; + + i++; + + vnf_test_config[0].phy_count = i; + + nfapi_vnf_pnf_config_req(config, p5_idx, &req); + + return 0; +} + +int pnf_config_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* response) +{ + printf("pnf_config_response\n"); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + req.header.message_length = 0; + req.header.phy_id = response->header.phy_id; + + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + + return 0; +} + + +void* vnf_test_start_p7_thread(void* ptr) +{ + int result = nfapi_vnf_p7_start((nfapi_vnf_p7_config_t*)ptr); + (void)result; + return 0; +} + +int test_subframe_indication(nfapi_vnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf) +{ + //printf("[VNF:%d] (%d:%d) SUBFRAME_IND\n", phy_id, SFNSF2SFN(sfn_sf), SFNSF2SF(sfn_sf)); + + nfapi_dl_config_request_t dl_config_req; + memset(&dl_config_req, 0, sizeof(dl_config_req)); + dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_req.header.phy_id = phy_id; + dl_config_req.sfn_sf = sfn_sf; + nfapi_vnf_p7_dl_config_req(config, &dl_config_req); + + nfapi_ul_config_request_t ul_config_req; + memset(&ul_config_req, 0, sizeof(ul_config_req)); + ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_req.header.phy_id = phy_id; + ul_config_req.sfn_sf = sfn_sf; + nfapi_vnf_p7_ul_config_req(config, &ul_config_req); + + nfapi_hi_dci0_request_t hi_dci0_req; + memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); + hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req.header.phy_id = phy_id; + hi_dci0_req.sfn_sf = sfn_sf; + nfapi_vnf_p7_hi_dci0_req(config, &hi_dci0_req); + + + nfapi_tx_request_t tx_req; + memset(&tx_req, 0, sizeof(tx_req)); + tx_req.header.message_id = NFAPI_TX_REQUEST; + tx_req.header.phy_id = phy_id; + tx_req.sfn_sf = sfn_sf; + nfapi_vnf_p7_tx_req(config, &tx_req); + return 0; +} + +int test_harq_indication(nfapi_vnf_p7_config_t* config, nfapi_harq_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) HARQ_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} + +int test_nb_harq_indication(nfapi_vnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) HARQ_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} + + +int test_crc_indication(nfapi_vnf_p7_config_t* config, nfapi_crc_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) CRC_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_rx_indication(nfapi_vnf_p7_config_t* config, nfapi_rx_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) RX_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_rach_indication(nfapi_vnf_p7_config_t* config, nfapi_rach_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) RACH_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_nrach_indication(nfapi_vnf_p7_config_t* config, nfapi_nrach_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) RACH_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_srs_indication(nfapi_vnf_p7_config_t* config, nfapi_srs_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) SRS_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_sr_indication(nfapi_vnf_p7_config_t* config, nfapi_sr_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) SR_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} +int test_cqi_indication(nfapi_vnf_p7_config_t* config, nfapi_cqi_indication_t* ind) +{ + //printf("[VNF:%d] (%d:%d) CQI_IND\n", ind->header.phy_id, SFNSF2SFN(ind->sfn_sf), SFNSF2SF(ind->sfn_sf)); + return 0; +} + +int pnf_start_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* response) +{ + printf("[VNF] pnf_start_response p5_idx:%d\n", p5_idx); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + return 0; +} + +int pnf_stop_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_response_t* response) +{ + printf("pnf_stop_response\n"); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + nfapi_vnf_p7_stop(vnf_test_config[0].vnfs[0].config); + return 0; +} + +int param_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* response) +{ + printf("[VNF] param_response p5_idx:%d phy_id:%d\n", p5_idx, response->header.phy_id); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + struct sockaddr_in addr; + memcpy(&addr.sin_addr.s_addr, &response->nfapi_config.p7_pnf_address_ipv4.address, 4); + printf("[VNF] param_response pnf p7 %s:%d\n", inet_ntoa(addr.sin_addr), response->nfapi_config.p7_pnf_port.value); + + // find the vnf phy configuration + vnf_test_config_phy_t* phy = find_vnf_phy_config(&(vnf_test_config[0]), response->header.phy_id); + + // save the pnf p7 connection information + phy->p7_tx_sockaddr.sin_port = response->nfapi_config.p7_pnf_port.value; + memcpy(&phy->p7_tx_sockaddr.sin_addr.s_addr, &response->nfapi_config.p7_pnf_address_ipv4.address, 4); + + nfapi_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_CONFIG_REQUEST; + req.header.phy_id = response->header.phy_id; + + vnf_test_config_vnf_t* vnf = &(vnf_test_config[0].vnfs[phy->vnf_idx]); + req.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + memcpy(&req.nfapi_config.p7_vnf_address_ipv4.address, &vnf->p7_rx_sockaddr.sin_addr.s_addr, 4); + + req.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req.nfapi_config.p7_vnf_port.value = vnf->p7_rx_sockaddr.sin_port; + + nfapi_vnf_config_req(config, p5_idx, &req); + return 0; +} + +int config_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* response) +{ + printf("[VNF] config_response p5_idx:%d phy_id:%d\n", p5_idx, response->header.phy_id); + return 0; + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + +} + +int send_vnf_start_req(vnf_test_config_t* config, vnf_test_config_phy_t* phy) +{ + nfapi_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = phy->phy_id; + + nfapi_vnf_start_req(config->p5_vnf_config, phy->p5_idx, &req); + return 0; +} + +int start_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* response) +{ + printf("[VNF] start_response p5_idx:%d phy_id:%d\n", p5_idx, response->header.phy_id); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + + sleep(1); + + vnf_test_config_phy_t* phy = find_vnf_phy_config(&(vnf_test_config[0]), response->header.phy_id); + + char* addr = inet_ntoa(phy->p7_tx_sockaddr.sin_addr); + int port = phy->p7_tx_sockaddr.sin_port; + + vnf_test_config_vnf_t* vnf = &(vnf_test_config[0].vnfs[phy->vnf_idx]); + + nfapi_vnf_p7_add_pnf(vnf->config, addr, port, response->header.phy_id); + return 0; +} + +int stop_response(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_response_t* response) +{ + printf("stop_response p5_idx:%d phy_id:%d\n", p5_idx, response->header.phy_id); + CU_ASSERT_EQUAL(response->error_code, NFAPI_MSG_OK); + return 0; +} + +void start_vnf_p5(vnf_test_config_t* test_config) +{ + test_config->p5_vnf_config = nfapi_vnf_config_create(); + + test_config->p5_vnf_config->vnf_p5_port = test_config->p5_port; + test_config->p5_vnf_config->vnf_ipv4 = 1; + test_config->p5_vnf_config->pnf_connection_indication = &pnf_connection_indication; + test_config->p5_vnf_config->pnf_disconnect_indication = &pnf_disconnect_indication; + test_config->p5_vnf_config->pnf_param_resp = &pnf_param_response; + test_config->p5_vnf_config->pnf_config_resp = &pnf_config_response; + test_config->p5_vnf_config->pnf_start_resp = &pnf_start_response; + test_config->p5_vnf_config->pnf_stop_resp = &pnf_stop_response; + test_config->p5_vnf_config->param_resp = ¶m_response; + test_config->p5_vnf_config->config_resp = &config_response; + test_config->p5_vnf_config->start_resp = &start_response; + test_config->p5_vnf_config->stop_resp = &stop_response; + + test_config->p5_vnf_config->user_data = test_config; + + pthread_create(&test_config->thread, NULL, &vnf_test_start_thread, test_config->p5_vnf_config); + + sleep(1); + +} + +void start_vnf_p7(vnf_test_config_vnf_t* vnf) +{ + + // todo : select which vnf to use for these phy's + vnf->enabled = 1; + + vnf->p7_rx_sockaddr.sin_addr.s_addr = inet_addr(vnf->vnf_p7_addr); + vnf->p7_rx_sockaddr.sin_port = vnf->vnf_p7_port; + + + vnf->config = nfapi_vnf_p7_config_create(); + vnf->config->checksum_enabled = 0; + vnf->config->port = vnf->vnf_p7_port; + vnf->config->subframe_indication = &test_subframe_indication; + vnf->config->harq_indication = &test_harq_indication; + vnf->config->crc_indication = &test_crc_indication; + vnf->config->rx_indication = &test_rx_indication; + vnf->config->rach_indication = &test_rach_indication; + vnf->config->srs_indication = &test_srs_indication; + vnf->config->sr_indication = &test_sr_indication; + vnf->config->cqi_indication = &test_cqi_indication; + + vnf->config->nb_harq_indication = &test_nb_harq_indication; + vnf->config->nrach_indication = &test_nrach_indication; + + + vnf->config->segment_size = 1400; + vnf->config->max_num_segments = 6; + + pthread_create(&(vnf->thread), NULL, &vnf_test_start_p7_thread, vnf->config); + + vnf->enabled = 1; + + //vnf->phy_count++; + + sleep(1); +} + +void send_p7_segmented_msg(int sock, char* msg, int len, int segment_size, struct sockaddr* addr, socklen_t addr_len) +{ + static uint8_t sequence_num = 0; + if(len < segment_size) + { + msg[7] = sequence_num; + sendto(sock, msg, len, 0, addr, addr_len); + } + else + { + int msg_body_len = len - 12 ; + int seg_body_len = segment_size - 12 ; + int segments = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); + + //printf("sending segmented message len:%d seg_size:%d count:%d\n", len, segment_size, segments); + + int segment = 0; + int offset = 12; + for(segment = 0; segment < segments; ++segment) + { + uint8_t last = 0; + uint16_t size = segment_size - 12; + if(segment + 1 == segments) + { + last = 1; + size = (msg_body_len) - (seg_body_len * segment); + } + + char buffer[segment_size]; + + memcpy(&buffer[0], msg, 12); + buffer[6] = ((!last) << 7) + segment; + buffer[7] = sequence_num; + + // msg length + uint8_t* p = (uint8_t*)&buffer[4]; + push16(size + 12, &p, (uint8_t*)&buffer[size + 12]); + + memcpy(&buffer[12], msg + offset, size); + offset += size; + + sendto(sock, &buffer[0], size + 12, 0, addr, addr_len); + + } + + + } + + sequence_num++; +} + +void start_phy(vnf_test_config_phy_t* phy) +{ + + nfapi_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = phy->phy_id; + + nfapi_vnf_config_t* p5_vnf_config = (vnf_test_config[0].p5_vnf_config); + + + nfapi_vnf_param_req(p5_vnf_config, phy->p5_idx, &req); + +} + + +void vnf_test_start_connect(void) +{ + reset_test_configs(); + + int segment_size = 256; + + vnf_test_config[0].p5_addr = "127.0.0.1"; + vnf_test_config[0].p5_port = 4242; + + vnf_test_config[0].vnfs[0].enabled = 0; + vnf_test_config[0].vnfs[0].vnf_p7_addr = "127.0.0.1"; + vnf_test_config[0].vnfs[0].vnf_p7_port = 7878; + vnf_test_config[0].vnfs[0].max_phys = 1; + + vnf_test_config[0].vnfs[1].enabled = 0; + vnf_test_config[0].vnfs[1].vnf_p7_addr = "127.0.0.1"; + vnf_test_config[0].vnfs[1].vnf_p7_port = 7879; + vnf_test_config[0].vnfs[1].max_phys = 1; + + + // this is the action that p9 would take to set the vnf p5 address/port + pnf_test_config[0].enabled = 1; + pnf_test_config[0].vnf_p5_port = vnf_test_config[0].p5_port; + pnf_test_config[0].vnf_p5_addr = vnf_test_config[0].p5_addr; + pnf_test_config[0].p7_rx_port_base = 8000; + + pnf_test_config[1].enabled = 1; + pnf_test_config[1].vnf_p5_port = vnf_test_config[0].p5_port; + pnf_test_config[1].vnf_p5_addr = vnf_test_config[0].p5_addr; + pnf_test_config[1].p7_rx_port_base = 8100; + + pnf_connection_indication_called = 0; + + start_vnf_p5(&vnf_test_config[0]); + + + pnf_create_p5_sock(&pnf_test_config[0]); + pnf_p5_connect(&pnf_test_config[0]); + + receive_pnf_param_request(&pnf_test_config[0]); + send_pnf_param_response(&pnf_test_config[0]); + + receive_pnf_config_request(&pnf_test_config[0]); + send_pnf_config_response(&pnf_test_config[0]); + + receive_pnf_start_request(&pnf_test_config[0]); + send_pnf_start_response(&pnf_test_config[0]); + + pnf_create_p5_sock(&pnf_test_config[1]); + + pnf_p5_connect(&pnf_test_config[1]); + + receive_pnf_param_request(&pnf_test_config[1]); + send_pnf_param_response(&pnf_test_config[1]); + + receive_pnf_config_request(&pnf_test_config[1]); + send_pnf_config_response(&pnf_test_config[1]); + + receive_pnf_start_request(&pnf_test_config[1]); + send_pnf_start_response(&pnf_test_config[1]); + + // start the vnf_p7 thread and assign by phys to that instance + + start_vnf_p7(&vnf_test_config[0].vnfs[0]); + //start_vnf_p7(&vnf_test_config[0].vnfs[1]); + + printf("---- configuring phy %d -----\n", vnf_test_config[0].phys[0].phy_id); + vnf_test_config[0].phys[0].vnf_idx = 0; + start_phy(&vnf_test_config[0].phys[0]); + + int phy_id = receive_param_request(&pnf_test_config[0]); + send_param_response(&pnf_test_config[0], phy_id); + + phy_id = receive_config_request(&pnf_test_config[0]); + send_config_response(&pnf_test_config[0], phy_id); + + printf("---- configuring phy %d -----\n", vnf_test_config[0].phys[2].phy_id); + vnf_test_config[0].phys[2].vnf_idx = 0; + start_phy(&vnf_test_config[0].phys[2]); + + phy_id = receive_param_request(&pnf_test_config[1]); + send_param_response(&pnf_test_config[1], phy_id); + + phy_id = receive_config_request(&pnf_test_config[1]); + send_config_response(&pnf_test_config[1], phy_id); + + printf("---- configuring phy %d -----\n", vnf_test_config[0].phys[1].phy_id); + + vnf_test_config[0].phys[1].vnf_idx = 0; + start_phy(&vnf_test_config[0].phys[1]); + + phy_id = receive_param_request(&pnf_test_config[0]); + send_param_response(&pnf_test_config[0], phy_id); + + phy_id = receive_config_request(&pnf_test_config[0]); + send_config_response(&pnf_test_config[0], phy_id); + + //------------- + printf("---- starting phy %d -----\n", vnf_test_config[0].phys[0].phy_id); + + send_vnf_start_req(&vnf_test_config[0], &vnf_test_config[0].phys[0]); + phy_id = receive_start_request(&pnf_test_config[0]); + send_start_response(&pnf_test_config[0], phy_id); +/* + printf("---- starting phy %d -----\n", vnf_test_config[0].phys[2].phy_id); + + send_vnf_start_req(&vnf_test_config[0], &vnf_test_config[0].phys[2]); + phy_id = receive_start_request(&pnf_test_config[1]); + send_start_response(&pnf_test_config[1], phy_id); + + printf("---- starting phy %d -----\n", vnf_test_config[0].phys[1].phy_id); + + send_vnf_start_req(&vnf_test_config[0], &vnf_test_config[0].phys[1]); + phy_id = receive_start_request(&pnf_test_config[0]); + send_start_response(&pnf_test_config[0], phy_id); +*/ + //close(pnf_test_config[0].p5_sock); + + char buffer[2048]; + int buffer_size = sizeof(buffer); + + + fd_set rdfs; + int exit = 0; + while(exit != 1) + { + int pnf_idx, phy_idx; + int max_fd = 0; + FD_ZERO(&rdfs); + + for(pnf_idx = 0; pnf_idx < 4; ++pnf_idx) + { + if(pnf_test_config[pnf_idx].enabled) + { + FD_SET(pnf_test_config[pnf_idx].p5_sock, &rdfs); + if(pnf_test_config[pnf_idx].p5_sock > max_fd) + max_fd = pnf_test_config[pnf_idx].p5_sock; + } + + for(phy_idx = 0; phy_idx < 4; ++phy_idx) + { + pnf_test_config_phy_t* phy_info = &(pnf_test_config[pnf_idx].phys[phy_idx]); + + if(phy_info->started == 1 && phy_info->enabled == 1) + { + //////////////////printf("adding %d/%d %d %d\n", pnf_idx, phy_idx, phy_info->phy_id, phy_info->p7_rx_sock); + FD_SET(phy_info->p7_rx_sock, &rdfs); + if(phy_info->p7_rx_sock > max_fd) + max_fd = phy_info->p7_rx_sock; + } + } + } + + + // changed to select, + int select_result = select(max_fd + 1, &rdfs, NULL, NULL, NULL); + (void)select_result; + + for(pnf_idx = 0; pnf_idx < 4; ++pnf_idx) + { + if(pnf_test_config[pnf_idx].enabled) + { + //pnf_test_config_t* pnf_config = &(pnf_test_config[pnf_idx]); + } + + for(phy_idx = 0; phy_idx < 4; ++phy_idx) + { + pnf_test_config_phy_t* phy_info = &(pnf_test_config[pnf_idx].phys[phy_idx]); + + if(phy_info->enabled) + { + if(FD_ISSET(phy_info->p7_rx_sock, &rdfs)) + { + //struct sockaddr_in recv_addr; + //memset(&recv_addr, 0, sizeof(recv_addr)); + //socklen_t recv_addr_size; + int len = recvfrom(phy_info->p7_rx_sock, &buffer[0], buffer_size, 0, 0, 0);// (struct sockaddr*)&recv_addr, &recv_addr_size); + + if(len == -1) + { + printf("recvfrom %d failed %d\n", phy_info->p7_rx_sock, errno); + continue; + } + + nfapi_p7_message_header_t header; + nfapi_p7_message_header_unpack(buffer, len, &header, sizeof(header), 0); + + switch(header.message_id) + { + case NFAPI_DL_NODE_SYNC: + { + nfapi_dl_node_sync_t msg; + nfapi_p7_message_unpack(buffer, len, &msg, sizeof(msg), 0); + printf("[PNF:%d] NFAPI_DL_NODE_SYNC t1:%d\n", msg.header.phy_id, msg.t1); + + nfapi_ul_node_sync_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_UL_NODE_SYNC; + resp.header.phy_id = msg.header.phy_id; + resp.t1 = msg.t1; + usleep(50); + resp.t2 = msg.t1 + 50; // 50 us rx latency + resp.t3 = msg.t1 + 10; // 10 us pnf proc + + usleep(50); + + len = nfapi_p7_message_pack(&resp, buffer, buffer_size, 0); + // send ul node sycn + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + } + break; + case NFAPI_DL_CONFIG_REQUEST: + { + nfapi_dl_config_request_t msg; + nfapi_p7_message_unpack(buffer, len, &msg, sizeof(msg), 0); + //printf("[PNF:%d] (%d/%d) NFAPI_DL_CONFIG_REQUEST\n", header.phy_id, SFNSF2SFN(msg.sfn_sf), SFNSF2SF(msg.sfn_sf)); + + if(SFNSF2SFN(msg.sfn_sf) == 500) + exit = 1; + // simulate the uplink messages + + nfapi_harq_indication_t harq_ind; + memset(&harq_ind, 0, sizeof(harq_ind)); + harq_ind.header.message_id = NFAPI_HARQ_INDICATION; + harq_ind.header.phy_id = msg.header.phy_id; + harq_ind.sfn_sf = msg.sfn_sf; + harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + harq_ind.harq_indication_body.number_of_harqs = 2; + + harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)(malloc(sizeof(nfapi_harq_indication_pdu_t) * harq_ind.harq_indication_body.number_of_harqs)); + + int i = 0; + for(i = 0; i < harq_ind.harq_indication_body.number_of_harqs; ++i) + { + harq_ind.harq_indication_body.harq_pdu_list[i].rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + } + len = nfapi_p7_message_pack(&harq_ind, buffer, buffer_size, 0); + //sendto(phy_info->p7_tx_sock, &buffer[0], len, 0, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + + + //sendto(phy_info->p7_tx_sock, &buffer[0], len, 0, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + free(harq_ind.harq_indication_body.harq_pdu_list); + + nfapi_crc_indication_t crc_ind; + memset(&crc_ind, 0, sizeof(crc_ind)); + crc_ind.header.message_id = NFAPI_CRC_INDICATION; + crc_ind.header.phy_id = msg.header.phy_id; + crc_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&crc_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_sr_indication_t sr_ind; + memset(&sr_ind, 0, sizeof(sr_ind)); + sr_ind.header.message_id = NFAPI_RX_SR_INDICATION; + sr_ind.header.phy_id = msg.header.phy_id; + sr_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&sr_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_cqi_indication_t cqi_ind; + memset(&cqi_ind, 0, sizeof(cqi_ind)); + cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION; + cqi_ind.header.phy_id = msg.header.phy_id; + cqi_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&cqi_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_rach_indication_t rach_ind; + memset(&rach_ind, 0, sizeof(rach_ind)); + rach_ind.header.message_id = NFAPI_RACH_INDICATION; + rach_ind.header.phy_id = msg.header.phy_id; + rach_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&rach_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_srs_indication_t srs_ind; + memset(&srs_ind, 0, sizeof(srs_ind)); + srs_ind.header.message_id = NFAPI_SRS_INDICATION; + srs_ind.header.phy_id = msg.header.phy_id; + srs_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&srs_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_rx_indication_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = NFAPI_RX_ULSCH_INDICATION; + rx_ind.header.phy_id = msg.header.phy_id; + rx_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&rx_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + if(msg.sfn_sf % 5 == 0) + { + // periodically send the timing info + nfapi_timing_info_t timing_info; + memset(&timing_info, 0, sizeof(timing_info)); + timing_info.header.message_id = NFAPI_TIMING_INFO; + timing_info.header.phy_id = msg.header.phy_id; + len = nfapi_p7_message_pack(&timing_info, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + } + + nfapi_nb_harq_indication_t nb_harq_ind; + memset(&nb_harq_ind, 0, sizeof(nb_harq_ind)); + nb_harq_ind.header.message_id = NFAPI_NB_HARQ_INDICATION; + nb_harq_ind.header.phy_id = msg.header.phy_id; + nb_harq_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&nb_harq_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + nfapi_nrach_indication_t nrach_ind; + memset(&nrach_ind, 0, sizeof(nrach_ind)); + nrach_ind.header.message_id = NFAPI_NRACH_INDICATION; + nrach_ind.header.phy_id = msg.header.phy_id; + nrach_ind.sfn_sf = msg.sfn_sf; + len = nfapi_p7_message_pack(&nrach_ind, buffer, buffer_size, 0); + send_p7_segmented_msg(phy_info->p7_tx_sock, &buffer[0], len, segment_size, (struct sockaddr*)&phy_info->p7_tx_sockaddr, sizeof(phy_info->p7_tx_sockaddr)); + + } + break; + case NFAPI_UL_CONFIG_REQUEST: + { + nfapi_ul_config_request_t msg; + nfapi_p7_message_unpack(buffer, len, &msg, sizeof(msg), 0); + //printf("[PNF:%d] (%d/%d) NFAPI_UL_CONFIG_REQUEST\n", header.phy_id, SFNSF2SFN(msg.sfn_sf), SFNSF2SF(msg.sfn_sf)); + } + break; + case NFAPI_HI_DCI0_REQUEST: + { + nfapi_hi_dci0_request_t msg; + nfapi_p7_message_unpack(buffer, len, &msg, sizeof(msg), 0); + //printf("[PNF:%d] (%d/%d) NFAPI_HI_DCI0_REQUEST\n", header.phy_id, SFNSF2SFN(msg.sfn_sf), SFNSF2SF(msg.sfn_sf)); + } + break; + case NFAPI_TX_REQUEST: + { + nfapi_tx_request_t msg; + nfapi_p7_message_unpack(buffer, len, &msg, sizeof(msg), 0); + //printf("[PNF:%d] (%d/%d) NFAPI_TX_REQUEST\n", header.phy_id, SFNSF2SFN(msg.sfn_sf), SFNSF2SF(msg.sfn_sf)); + } + break; + } + + } + } + } + } + } + + printf("Triggering p5 shutdown\n"); + + // vnf p5 trigger shutdown + nfapi_pnf_stop_request_t stop_req; + memset(&stop_req, 0, sizeof(stop_req)); + stop_req.header.message_id = NFAPI_PNF_STOP_REQUEST; + nfapi_vnf_pnf_stop_req(vnf_test_config[0].p5_vnf_config, 0, &stop_req); + + phy_id = receive_pnf_stop_request(&pnf_test_config[0]); + send_pnf_stop_response(&pnf_test_config[0], phy_id); + + + nfapi_vnf_stop(vnf_test_config[0].p5_vnf_config); + + + + int* result; + pthread_join((vnf_test_config[0].thread), (void**)&result); + CU_ASSERT_EQUAL(result, 0); + //CU_ASSERT_EQUAL(pnf_connection_indication_called, 1); + + + close(pnf_test_config[0].p5_sock); +} + +void vnf_test_start_connect_ipv6(void) +{ + char* vnf_addr = "::1"; + int vnf_port = 4242; + pnf_connection_indication_called = 0; + + nfapi_vnf_config_t* config = nfapi_vnf_config_create(); + config->vnf_p5_port = vnf_port; + config->vnf_ipv4 = 0; + config->vnf_ipv6 = 1; + config->pnf_connection_indication = &pnf_connection_indication; + config->pnf_disconnect_indication = &pnf_disconnect_indication; + config->pnf_param_resp = &pnf_param_response; + config->pnf_config_resp = &pnf_config_response; + config->pnf_start_resp = &pnf_start_response; + + pthread_t thread; + pthread_create(&thread, NULL, &vnf_test_start_thread, config); + + sleep(1); + + + int p5Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + struct sockaddr_in6 addr; + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(vnf_port); + //addr.sin6_addr = inet_addr(vnf_addr); + inet_pton(AF_INET6, vnf_addr, &addr.sin6_addr); + + + /* + int connect_result = connect(p5Sock, (struct sockaddr *)&addr, sizeof(addr) ); + + printf("connect_result %d %d\n", connect_result, errno); + + receive_pnf_param_request(p5Sock); + send_pnf_param_response(p5Sock, &addr, sizeof(addr)); + + receive_pnf_config_request(p5Sock); + send_pnf_config_response(p5Sock, &addr, sizeof(addr)); + + receive_pnf_start_request(p5Sock); + send_pnf_start_response(p5Sock, &addr, sizeof(addr)); + */ + sleep(4); + nfapi_vnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL(result, 0); + CU_ASSERT_EQUAL(pnf_connection_indication_called, 1); + + + close(p5Sock); +} +void vnf_test_start_connect_2(void) +{ + char* vnf_addr = "127.0.0.1"; + int vnf_port = 4242; + pnf_connection_indication_called = 0; + + nfapi_vnf_config_t * config = nfapi_vnf_config_create(); + config->vnf_p5_port = vnf_port; + config->pnf_connection_indication = &pnf_connection_indication; + + pthread_t thread; + pthread_create(&thread, NULL, &vnf_test_start_thread, config); + + sleep(1); + + + + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(vnf_port); + addr.sin_addr.s_addr = inet_addr(vnf_addr); + + + int p5Sock1 = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + int connect_result_1 = connect(p5Sock1, (struct sockaddr *)&addr, sizeof(addr) ); + + printf("connect_result_1 %d %d\n", connect_result_1, errno); + + int p5Sock2 = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + int connect_result_2 = connect(p5Sock2, (struct sockaddr *)&addr, sizeof(addr) ); + + printf("connect_result_2 %d %d\n", connect_result_2, errno); + + sleep(1); + + close(p5Sock1); + + sleep(1); + + close(p5Sock2); + + sleep(1); + + nfapi_vnf_stop(config); + + int* result; + pthread_join(thread, (void**)&result); + CU_ASSERT_EQUAL(result, 0); + CU_ASSERT_EQUAL(pnf_connection_indication_called, 2); + + + close(p5Sock1); + close(p5Sock2); +} + +void vnf_test_p7_segmentation_test1(void) +{ + +} + + +/************* Test Runner Code goes here **************/ + +int main ( void ) +{ + CU_pSuite pSuite = NULL; + + /* initialize the CUnit test registry */ + if ( CUE_SUCCESS != CU_initialize_registry() ) + return CU_get_error(); + + /* add a suite to the registry */ + pSuite = CU_add_suite( "vnf_test_suite", init_suite, clean_suite ); + if ( NULL == pSuite ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + //(NULL == CU_add_test(pSuite, "vnf_test_start_connect_2", vnf_test_start_connect_2)) + /* add the tests to the suite */ + if ( (NULL == CU_add_test(pSuite, "vnf_test_start_no_config", vnf_test_start_no_config)) || + (NULL == CU_add_test(pSuite, "vnf_test_start_connect", vnf_test_start_connect)) || + (NULL == CU_add_test(pSuite, "vnf_test_p7_segmentation_test1", vnf_test_p7_segmentation_test1)) + ) + { + CU_cleanup_registry(); + return CU_get_error(); + } + + // Run all tests using the basic interface + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_set_output_filename("vnf_unit_test_results.xml"); + CU_basic_run_tests(); + + CU_pSuite s = CU_get_registry()->pSuite; + int count = 0; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + count++; + t = t->pNext; + } + s = s->pNext; + } + + printf("%d..%d\n", 1, count); + + + + s = CU_get_registry()->pSuite; + count = 1; + while(s) + { + CU_pTest t = s->pTest; + while(t) + { + int pass = 1; + CU_FailureRecord* failures = CU_get_failure_list(); + while(failures) + { + if(strcmp(failures->pSuite->pName, s->pName) == 0 && + strcmp(failures->pTest->pName, t->pName) == 0) + { + pass = 0; + failures = 0; + } + else + { + failures = failures->pNext; + } + } + + if(pass) + printf("ok %d - %s:%s\n", count, s->pName, t->pName); + else + printf("not ok %d - %s:%s\n", count, s->pName, t->pName); + + count++; + t = t->pNext; + } + s = s->pNext; + } + + CU_cleanup_registry(); + return CU_get_error(); + +} diff --git a/nfapi/open-nFAPI/vnf_sim/Makefile.am b/nfapi/open-nFAPI/vnf_sim/Makefile.am new file mode 100644 index 0000000000..c3e42cebf3 --- /dev/null +++ b/nfapi/open-nFAPI/vnf_sim/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright 2017 Cisco Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# + +AUTOMAKE_OPTIONS=subdir-objects +AM_CPPFLAGS = -I$(top_srcdir)/vnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/vnf/inc -I$(top_srcdir)/vnf/public_inc $(XML_CFLAGS) -Wall -Werror -g +AM_CXXFLAGS = -I$(top_srcidr)/vnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/vnf/inc -I$(top_srcdir)/vnf/public_inc $(XML_CFLAGS) -std=c++11 $(BOOST_CPPFLAGS) -g +bin_PROGRAMS = vnfsim +vnfsim_SOURCES = src/main.cpp src/mac.cpp +LDADD= $(top_builddir)/vnf/libnfapi_vnf.a $(top_builddir)/common/libnfapi_common.a $(top_builddir)/nfapi/libnfapi.a $(top_builddir)/sim_common/libnfapi_sim_common.a -L$(libdir) -lpthread -lrt -lsctp -lz diff --git a/nfapi/open-nFAPI/vnf_sim/inc/mac.h b/nfapi/open-nFAPI/vnf_sim/inc/mac.h new file mode 100644 index 0000000000..eac5b3b2ac --- /dev/null +++ b/nfapi/open-nFAPI/vnf_sim/inc/mac.h @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef _MAC_H_ +#define _MAC_H_ + +#include "nfapi_interface.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct mac mac_t; + +typedef struct mac +{ + void* user_data; + + void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req); + void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req); + void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req); + void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req); +} mac_t; + +mac_t* mac_create(uint8_t wireshark_test_mode); +void mac_destroy(mac_t* mac); + +void mac_start_data(mac_t* mac, unsigned rx_port, const char* tx_addres, unsigned tx_port); + +void mac_subframe_ind(mac_t* mac, uint16_t phy_id, uint16_t sfn_sf); +void mac_harq_ind(mac_t* mac, nfapi_harq_indication_t* ind); +void mac_crc_ind(mac_t* mac, nfapi_crc_indication_t* ind); +void mac_rx_ind(mac_t* mac, nfapi_rx_indication_t* ind); +void mac_rach_ind(mac_t* mac, nfapi_rach_indication_t* ind); +void mac_srs_ind(mac_t* mac, nfapi_srs_indication_t* ind); +void mac_sr_ind(mac_t* mac, nfapi_sr_indication_t* ind); +void mac_cqi_ind(mac_t* mac, nfapi_cqi_indication_t* ind); +void mac_lbt_dl_ind(mac_t* mac, nfapi_lbt_dl_indication_t* ind); +void mac_nb_harq_ind(mac_t* mac, nfapi_nb_harq_indication_t* ind); +void mac_nrach_ind(mac_t* mac, nfapi_nrach_indication_t* ind); + + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/nfapi/open-nFAPI/vnf_sim/src/mac.cpp b/nfapi/open-nFAPI/vnf_sim/src/mac.cpp new file mode 100644 index 0000000000..fa6f487be8 --- /dev/null +++ b/nfapi/open-nFAPI/vnf_sim/src/mac.cpp @@ -0,0 +1,1327 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "mac.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +uint32_t rand_range(uint32_t min, uint32_t max) +{ + return ((rand() % (max + 1 - min)) + min); +} + +struct mac_pdu +{ + mac_pdu() : buffer_len(1500), buffer(0), len(0) + { + buffer = (char*) malloc(buffer_len); + } + + virtual ~mac_pdu() + { + free(buffer); + } + + unsigned buffer_len; + char* buffer; + unsigned len; +}; + +class mac_private +{ + std::mutex mutex; + std::queue rx_buffer; + + std::queue free_store; + public: + + mac_private(bool _wireshark_test_mode) + : byte_count(0), tick(0), wireshark_test_mode(_wireshark_test_mode) + { + + } + + mac_pdu* allocate_mac_pdu() + { + mac_pdu* pdu = 0; + mutex.lock(); + if(free_store.empty()) + { + pdu = new mac_pdu(); + } + else + { + pdu = free_store.front(); + free_store.pop(); + } + mutex.unlock(); + return pdu; + } + + void release_mac_pdu(mac_pdu* pdu) + { + mutex.lock(); + free_store.push(pdu); + mutex.unlock(); + } + + + + void push_rx_buffer(mac_pdu* buff) + { + mutex.lock(); + rx_buffer.push(buff); + mutex.unlock(); + } + + mac_pdu* pop_rx_buffer() + { + mac_pdu* buff = 0; + mutex.lock(); + if(!rx_buffer.empty()) + { + buff = rx_buffer.front(); + rx_buffer.pop(); + } + mutex.unlock(); + return buff; + } + + uint32_t byte_count; + uint32_t tick; + + bool wireshark_test_mode; + +}; + +extern "C" +{ + typedef struct { + mac_t _public; + + int rx_sock; + int tx_sock; + struct sockaddr_in tx_addr; + + uint32_t tx_byte_count; + + mac_private* mac; + + } mac_internal_t; + + mac_t* mac_create(uint8_t wireshark_test_mode) + { + mac_internal_t* instance = (mac_internal_t*)malloc(sizeof(mac_internal_t)); + instance->mac = new mac_private((wireshark_test_mode >= 1)); + return (mac_t*)instance; + } + + void mac_destroy(mac_t* mac) + { + mac_internal_t* instance = (mac_internal_t*)mac; + delete instance->mac; + free(instance); + } + + void* mac_rx_thread_start(void* ptr) + { + mac_internal_t* instance = (mac_internal_t*)ptr; + + while(1) + { + mac_pdu* pdu = instance->mac->allocate_mac_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); + if(len > 0) + { + pdu->len = len; + instance->mac->push_rx_buffer(pdu); + } + else + { + instance->mac->release_mac_pdu(pdu); + } + } + return 0; + } + + void mac_start_data(mac_t* mac, unsigned rx_port, const char* tx_address, unsigned tx_port) + { + mac_internal_t* instance = (mac_internal_t*)mac; + + printf("[MAC] Rx Data from %d\n", rx_port); + printf("[MAC] Tx Data to %s.%d\n", tx_address, tx_port); + + instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(instance->rx_sock < 0) + { + printf("[MAC] Failed to create socket\n"); + return; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(0)); + addr.sin_family = AF_INET; + addr.sin_port = htons(rx_port); + addr.sin_addr.s_addr = INADDR_ANY; + + if(bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + { + printf("[MAC] Failed to bind to %d\n", rx_port); + close(instance->rx_sock); + return; + } + + pthread_t mac_rx_thread; + pthread_create(&mac_rx_thread, NULL, &mac_rx_thread_start, instance); + + instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); + instance->tx_addr.sin_family = AF_INET; + instance->tx_addr.sin_port = htons(tx_port); + instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); + } + + + + void generate_test_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) + { + //mac_internal_t* instance = (mac_internal_t*)mac; + + uint8_t max_num_dl_pdus = 50; + nfapi_dl_config_request_pdu_t dl_config_pdus[max_num_dl_pdus]; + memset(&dl_config_pdus, 0, sizeof(dl_config_pdus)); + + nfapi_dl_config_request_t dl_config_req; + memset(&dl_config_req, 0, sizeof(dl_config_req)); + dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_req.header.phy_id = phy_id; + dl_config_req.sfn_sf = sfn_sf; + dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + dl_config_req.dl_config_request_body.number_pdu = rand_range(4, max_num_dl_pdus); + + uint16_t i = 0; + for(i = 0; i < dl_config_req.dl_config_request_body.number_pdu; ++i) + { + dl_config_pdus[i].pdu_type = rand_range(0, 11); + + switch(dl_config_pdus[i].pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.dci_format = rand_range(0, 9); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = rand_range(0, 32); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rand_range(0, 320000); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.harq_process = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpmi = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.pmi = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.precoding_information = rand_range(0, 63); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpc = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_size_index = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_power_offset = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.allocate_prach_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.preamble_index = rand_range(0, 63); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.prach_mask_index = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = rand_range(0, 10000); + + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_change_notification = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.scrambling_identity = rand_range(0, 1); + + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.carrier_indicator = rand_range(0, 7); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_request = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.n_dl_rb = rand_range(0, 100); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); + + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.primary_cell_type = rand_range(0, 2); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.number_ul_dl_configurations = 2; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); + + + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.codebook_size_determination = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.drms_table_flag = rand_range(0, 1); + + // if the tpm extention is present of not. + if(rand_range(0, 1)) + { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_prb_per_subband = rand_range(0, 8); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands = rand_range(0, 13); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas = 1; // rand_range(0, 8); + + for(int j = 0; j < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands; ++j) + { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].subband_index = j; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues = 1; //rand_range(1, 4); + + for(int k = 0; k < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas; ++k) + for(int l = 0; l < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues; ++l) + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].precoding_value[k][l] = rand_range(0, 65535); + } + } + else + { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = 0; + } + + } + break; + + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = rand_range(0, 10000); + } + break; + + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + { + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.rnti = 0xFFFD; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_allocation_type = 0; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_block_coding = 0; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.modulation = rand_range(0, 8); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.mbsfn_area_id = rand_range(0, 255); + } + break; + + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.rnti = rand_range(1, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = rand_range(0, 5); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = rand_range(0, 32000); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.modulation = rand_range(2, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rand_range(0, 3); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_blocks = rand_range(1, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = rand_range(0, 13); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_layers = rand_range(1, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 2; //rand_range(0, 13); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[0] = rand_range(0, 15); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[1] = rand_range(0, 15); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = rand_range(0, 14); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pa = rand_range(0, 7); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.nprb = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_mode = rand_range(1, 10); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 2; //rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 2; //rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].subband_index = rand_range(0, 4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].num_antennas = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].bf_value[0] = rand_range(0, 128); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].subband_index = rand_range(0, 4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].num_antennas = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].bf_value[0] = rand_range(0, 128); + + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.nscid = rand_range(0, 1); + + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config_r10 = 0; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_number_nzp_configuration = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.pdsch_start = rand_range(0, 4); + + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_config_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_scrambling = rand_range(0, 503); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_config_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_scrambling = rand_range(0, 503); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_atenna_ports = rand_range(1,4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_freq_shift = rand_range(0, 5); + + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.altcqi_table_r12 = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.maxlayers = rand_range(1, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.n_dl_harq = rand_range(0, 255); + + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.dwpts_symbols = rand_range(3, 14); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.ue_type = rand_range(0, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = rand_range(0, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + { + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.p_rnti = 0xFFFE; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_allocation_type = rand_range(2, 6); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_block_coding = rand_range(0, 34000); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.mcs = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.redundancy_version = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_transport_blocks = 1; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_scheme = rand_range(1, 6); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_layers = rand_range(1, 4); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.codebook_index = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ue_category_capacity = rand_range(0, 14); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pa = rand_range(0, 7); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.nprb = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG; + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.ue_mode = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + } + break; + + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + { + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG; + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_bandwidth = rand_range(6, 100); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_cyclic_prefix_type = rand_range(0, 1); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_muting = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + { + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_antenna_port_count_r10 = rand_range(1, 16); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config_r10 = 0; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 8); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_number_of_nzp_configuration = 2; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[1] = rand_range(0, 31); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.csi_rs_class = rand_range(0, 2); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.cdm_type = rand_range(0, 1); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.num_bf_vector = 0; // set to zero as not clear how to handle bf value array + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].csi_rs_resource_index = rand_range(0, 7); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].bf_value[0] = 42; + } + break; + + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + { + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.dci_format = rand_range(0, 9); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.cce_idx = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.aggregation_level = rand_range(0, 32); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_allocation_type = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_block_coding = rand_range(0, 320000); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_1 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_1 = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_2 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_2 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.harq_process = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpmi = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.pmi = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.precoding_information = rand_range(0, 63); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpc = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_size_index = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_power_offset = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.allocate_prach_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.preamble_index = rand_range(0, 63); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.prach_mask_index = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti_type = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transmission_power = rand_range(0, 10000); + + + + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_change_notification = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.scrambling_identity = rand_range(0, 1); + + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.carrier_indicator = rand_range(0, 7); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_request = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.n_dl_rb = rand_range(0, 100); + + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); + + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.primary_cell_type = rand_range(0, 2); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.number_ul_dl_configurations = 2; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); + + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.codebook_size_determination = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.drms_table_flag = rand_range(0, 1); + + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_resource_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_id = rand_range(0, 503); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_start_symbol = rand_range(1, 4); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb = rand_range(2, 8); + for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_prb_index[j] = rand_range(0, 99); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.subband_index = rand_range(0, 25); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.num_antennas= rand_range(1, 4); + for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.bf_value[j] = rand_range(0, 65535); + + + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.dwpts_symbols = rand_range(3, 14); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.initial_lbt_sf = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + { + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = rand_range(2, 6); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = rand_range(0, 14); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = rand_range(1, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = rand_range(0, 22); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = rand_range(2, 24); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = rand_range(1, 2); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = rand_range(0, 503); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_format = rand_range(10, 12); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = rand_range(0, 0xFFFF); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mcs = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = rand_range(1, 8); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_process = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(1, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpc = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = rand_range(0, 63); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.srs_request = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = rand_range(0, 255); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = rand_range(0, 8); + for(int j = 0 ; j < dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports; ++j) + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.precoding_value[j] = rand_range(0, 65535); + } + break; + + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + { + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG; + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs = rand_range(0, 3); + } + break; + + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + { + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.ncce_index = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.aggregation_level = rand_range(1, 2); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.start_symbol = rand_range(0, 4); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti_type = rand_range(0, 3); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_format = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.repetition_number = rand_range(0, 15); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.mcs = rand_range(0, 13); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource = rand_range(0, 15); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.starting_number_of_nprach_repetitions = rand_range(0, 3); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.subcarrier_indication_of_nprach = rand_range(0, 63); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.paging_direct_indication_differentation_flag = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.direct_indication = rand_range(0, 255); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 255); + } + break; + + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + { + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG; + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.start_symbol = rand_range(0, 4); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti_type = rand_range(0, 1); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.resource_assignment = rand_range(0, 7); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.repetition_number = rand_range(0, 15); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.modulation = 2; + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.number_of_subframes_for_resource_assignment = rand_range(1, 10); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.sf_idx = rand_range(1, 10240); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + } + break; + + }; + } + + + dl_config_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdus; + mac->dl_config_req(mac, &dl_config_req); + + uint8_t num_ul_pdus = 18; + nfapi_ul_config_request_pdu_t ul_config_pdus[num_ul_pdus]; + memset(&ul_config_pdus, 0, sizeof(ul_config_pdus)); + + nfapi_ul_config_request_t ul_config_req; + memset(&ul_config_req, 0, sizeof(ul_config_req)); + ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_req.header.phy_id = phy_id; + ul_config_req.sfn_sf = sfn_sf; + ul_config_req.ul_config_request_body.tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_config_req.ul_config_request_body.number_of_pdus = num_ul_pdus; + ul_config_req.ul_config_request_body.rach_prach_frequency_resources = rand_range(0, 255); + ul_config_req.ul_config_request_body.srs_present = rand_range(0, 1); + + auto ul_config_ulsch_pdu_test_gen = [](nfapi_ul_config_ulsch_pdu& ulsch_pdu) + { + ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ulsch_pdu.ulsch_pdu_rel8.handle = rand_range(0, 50000); + ulsch_pdu.ulsch_pdu_rel8.size = rand_range(0, 32000); + ulsch_pdu.ulsch_pdu_rel8.rnti = rand_range(1, 65535); + ulsch_pdu.ulsch_pdu_rel8.resource_block_start = rand_range(0, 99); + ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = rand_range(1, 100); + ulsch_pdu.ulsch_pdu_rel8.modulation_type = rand_range(2, 6); + ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + ulsch_pdu.ulsch_pdu_rel8.new_data_indication = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rand_range(0, 3); + ulsch_pdu.ulsch_pdu_rel8.harq_process_number = rand_range(0, 15); + ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = rand_range(0, 5); + ulsch_pdu.ulsch_pdu_rel8.n_srs = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG; + ulsch_pdu.ulsch_pdu_rel10.resource_allocation_type = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.resource_block_coding = rand_range(0, 35000); + ulsch_pdu.ulsch_pdu_rel10.transport_blocks = rand_range(1, 2); + ulsch_pdu.ulsch_pdu_rel10.transmission_scheme = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.number_of_layers = rand_range(1, 4); + ulsch_pdu.ulsch_pdu_rel10.codebook_index = rand_range(0, 23); + ulsch_pdu.ulsch_pdu_rel10.disable_sequence_hopping_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG; + ulsch_pdu.ulsch_pdu_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.npusch_identity = rand_range(0, 509); + ulsch_pdu.ulsch_pdu_rel11.dmrs_config_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.ndmrs_csh_identity = rand_range(0, 509); + ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ulsch_pdu.ulsch_pdu_rel13.ue_type = rand_range(0, 2); + ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = rand_range(1, 2048); + ulsch_pdu.ulsch_pdu_rel13.repetition_number = rand_range(1, 2048); + ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + ulsch_pdu.ulsch_pdu_rel13.empty_symbols_due_to_re_tunning = rand_range(0, 8); + }; + + auto ul_config_cqi_ri_info_test_gen = [](nfapi_ul_config_cqi_ri_information& cqi_ri_information) + { + cqi_ri_information.cqi_ri_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG; + cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_1 = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_greater_1 = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel8.ri_size = rand_range(0, 3); + cqi_ri_information.cqi_ri_information_rel8.delta_offset_cqi = rand_range(0, 15); + cqi_ri_information.cqi_ri_information_rel8.delta_offset_ri = rand_range(0, 15); + + cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + cqi_ri_information.cqi_ri_information_rel9.report_type = 1; // rand_range(0, 1); + cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = rand_range(0, 15); + cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = rand_range(0, 15); + + if(cqi_ri_information.cqi_ri_information_rel9.report_type == 0) + { + cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.control_type = rand_range(0, 1); + } + else + { + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = rand_range(0, 3); + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0] = rand_range(0, 255); + } + + cqi_ri_information.cqi_ri_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG; + cqi_ri_information.cqi_ri_information_rel13.report_type = rand_range(0, 1); + + if(cqi_ri_information.cqi_ri_information_rel13.report_type == 0) + { + cqi_ri_information.cqi_ri_information_rel13.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2 = rand_range(255, 10000); + } + }; + + auto ul_config_init_tx_params_test_gen = [](nfapi_ul_config_initial_transmission_parameters& initial_transmission_parameters) + { + initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = rand_range(0, 1); + initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rand_range(1, 100); + }; + + auto ul_config_harqinfo_test_gen = [](nfapi_ul_config_ulsch_harq_information& harq_information) + { + harq_information.harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; + harq_information.harq_information_rel10.harq_size = rand_range(0, 21); + harq_information.harq_information_rel10.delta_offset_harq = rand_range(0, 15); + harq_information.harq_information_rel10.ack_nack_mode = rand_range(0, 5); + harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG; + harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 21); + harq_information.harq_information_rel13.delta_offset_harq_2 = rand_range(0, 15); + }; + + auto ul_config_sr_info_test_gen = [](nfapi_ul_config_sr_information& sr_info) + { + sr_info.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr_info.sr_information_rel8.pucch_index = rand_range(0, 2047); + sr_info.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; + sr_info.sr_information_rel10.number_of_pucch_resources = rand_range(1, 2); + sr_info.sr_information_rel10.pucch_index_p1 = rand_range(0, 2047); + }; + + auto ul_config_ue_info_test_gen = [](nfapi_ul_config_ue_information& ue_information) + { + ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ue_information.ue_information_rel8.handle = rand_range(0, 99999); + ue_information.ue_information_rel8.rnti = rand_range(1, 65535); + ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; + ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); + ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; + ue_information.ue_information_rel13.ue_type = rand_range(0, 2); + ue_information.ue_information_rel13.empty_symbols = rand_range(0, 2); + ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); + ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); + }; + + auto ul_config_cqi_info_test_gen = [](nfapi_ul_config_cqi_information& cqi_information) + { + cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + cqi_information.cqi_information_rel8.pucch_index = rand_range(0, 1184); + cqi_information.cqi_information_rel8.dl_cqi_pmi_size = rand_range(0, 255); + cqi_information.cqi_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG; + cqi_information.cqi_information_rel10.number_of_pucch_resource = rand_range(1, 2); + cqi_information.cqi_information_rel10.pucch_index_p1 = rand_range(0, 1184); + cqi_information.cqi_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG; + cqi_information.cqi_information_rel13.csi_mode = rand_range(0, 2); + cqi_information.cqi_information_rel13.dl_cqi_pmi_size_2 = rand_range(0, 999); + cqi_information.cqi_information_rel13.starting_prb = rand_range(0, 109); + cqi_information.cqi_information_rel13.n_prb = rand_range(0, 7); + cqi_information.cqi_information_rel13.cdm_index = rand_range(0, 1); + cqi_information.cqi_information_rel13.n_srs = rand_range(0, 1); + }; + + auto ul_config_harq_info_test_gen = [](nfapi_ul_config_harq_information& harq_information) + { + harq_information.harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information.harq_information_rel10_tdd.harq_size = rand_range(0, 21); + harq_information.harq_information_rel10_tdd.ack_nack_mode = rand_range(0, 5); + harq_information.harq_information_rel10_tdd.number_of_pucch_resources = rand_range(0, 4); + harq_information.harq_information_rel10_tdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_1 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_2 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_3 = rand_range(0, 2047); + harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; + harq_information.harq_information_rel8_fdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel8_fdd.harq_size = rand_range(1, 2); + harq_information.harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information.harq_information_rel9_fdd.harq_size = rand_range(1, 10); + harq_information.harq_information_rel9_fdd.ack_nack_mode = rand_range(0, 4); + harq_information.harq_information_rel9_fdd.number_of_pucch_resources = rand_range(0, 4); + harq_information.harq_information_rel9_fdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_1 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_2 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_3 = rand_range(0, 2047); + harq_information.harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; + harq_information.harq_information_rel11.num_ant_ports = rand_range(1, 2); + harq_information.harq_information_rel11.n_pucch_2_0 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_1 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_2 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_3 = rand_range(0, 2047); + harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG; + harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 999); + harq_information.harq_information_rel13.starting_prb = rand_range(0, 109); + harq_information.harq_information_rel13.n_prb = rand_range(0, 7); + harq_information.harq_information_rel13.cdm_index = rand_range(0, 1); + harq_information.harq_information_rel13.n_srs = rand_range(0, 1); + }; + + + ul_config_pdus[0].pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[0].ulsch_pdu); + + ul_config_pdus[1].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.ulsch_pdu); + ul_config_cqi_ri_info_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.cqi_ri_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.initial_transmission_parameters); + + ul_config_pdus[2].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[2].ulsch_harq_pdu.ulsch_pdu); + ul_config_harqinfo_test_gen(ul_config_pdus[2].ulsch_harq_pdu.harq_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[2].ulsch_harq_pdu.initial_transmission_parameters); + + ul_config_pdus[3].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.ulsch_pdu); + ul_config_cqi_ri_info_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.cqi_ri_information); + ul_config_harqinfo_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.harq_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters); + + + ul_config_pdus[4].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.cqi_information); + + ul_config_pdus[5].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[5].uci_sr_pdu.ue_information); + ul_config_sr_info_test_gen(ul_config_pdus[5].uci_sr_pdu.sr_information); + + + ul_config_pdus[6].pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[6].uci_harq_pdu.ue_information); + ul_config_harq_info_test_gen(ul_config_pdus[6].uci_harq_pdu.harq_information); + + + ul_config_pdus[7].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.ue_information); + ul_config_sr_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.sr_information); + ul_config_harq_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.harq_information); + + ul_config_pdus[8].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.cqi_information); + ul_config_harq_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.harq_information); + + ul_config_pdus[9].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.cqi_information); + ul_config_sr_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.sr_information); + + ul_config_pdus[10].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.cqi_information); + ul_config_sr_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.sr_information); + ul_config_harq_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.harq_information); + + ul_config_pdus[11].pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.handle = rand_range(0, 9999); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.size = rand_range(1, 999); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.rnti = rand_range(1, 65535); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_bandwidth = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.frequency_domain_position = rand_range(0, 23); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.transmission_comb = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.i_srs = rand_range(0, 1023); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = rand_range(0, 11); + ul_config_pdus[11].srs_pdu.srs_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel10.antenna_port = rand_range(0, 2); + ul_config_pdus[11].srs_pdu.srs_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel13.number_of_combs = rand_range(0, 1); + + ul_config_pdus[12].pdu_type = NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[12].harq_buffer_pdu.ue_information); + + ul_config_pdus[13].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.ulsch_pdu); + ul_config_cqi_info_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.csi_information); + + ul_config_pdus[14].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.ulsch_pdu); + ul_config_harq_info_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.harq_information); + + ul_config_pdus[15].pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.ulsch_pdu); + ul_config_cqi_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.csi_information); + ul_config_harq_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.harq_information); + + ul_config_pdus[16].pdu_type = NFAPI_UL_CONFIG_NULSCH_PDU_TYPE; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nulsch_format = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.handle = rand_range(0, 0xFFFF); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.size = rand_range(0, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.rnti = rand_range(1, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.subcarrier_indication = rand_range(0, 47); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.resource_assignment = rand_range(0, 7); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.mcs = rand_range(0, 12); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.redudancy_version = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.repetition_number = rand_range(0, 7); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.new_data_indication = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.n_srs = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.sf_idx = rand_range(0, 40960); + + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.handle = rand_range(0, 0xFF); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.rnti = rand_range(1, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.ue_type = rand_range(0, 2); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.empty_symbols = rand_range(0, 0x3); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); + + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource = rand_range(0, 15); + + ul_config_pdus[17].pdu_type = NFAPI_UL_CONFIG_NRACH_PDU_TYPE; + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG; + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_0 = rand_range(0, 1); + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_1 = rand_range(0, 1); + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_2 = rand_range(0, 1); + + ul_config_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdus; + mac->ul_config_req(mac, &ul_config_req); + + + uint8_t num_dci_pdus = 4; + uint8_t num_hi_pdus = 1; + nfapi_hi_dci0_request_pdu_t hi_dci0_pdus[num_dci_pdus + num_hi_pdus]; + memset(&hi_dci0_pdus, 0, sizeof(hi_dci0_pdus)); + + nfapi_hi_dci0_request_t hi_dci0_req; + memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); + hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req.header.phy_id = phy_id; + hi_dci0_req.sfn_sf = sfn_sf; + + hi_dci0_req.hi_dci0_request_body.tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req.hi_dci0_request_body.sfnsf = sfn_sf; + hi_dci0_req.hi_dci0_request_body.number_of_dci = num_dci_pdus; + hi_dci0_req.hi_dci0_request_body.number_of_hi = num_hi_pdus; + + hi_dci0_pdus[0].pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.hi_value = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.i_phich = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.flag_tb2 = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.hi_value_2 = rand_range(0, 1); + + hi_dci0_pdus[1].pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dci_format = rand_range(0, 4); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cce_index = rand_range(0, 88); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.aggregation_level = rand_range(1, 8); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.rnti = rand_range(1, 65535); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.mcs_1 = rand_range(0, 31); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ul_index = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.carrier_indicator = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_request = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.mcs_2 = rand_range(0, 31); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tpmi = rand_range(0, 63); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.n_ul_rb = rand_range(6, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.pscch_resource = rand_range(0, 16); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.time_resource_pattern = rand_range(0, 32); + + + hi_dci0_pdus[2].pdu_type = NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dci_format = rand_range(0, 4); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cce_index = rand_range(0, 88); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.aggregation_level = rand_range(1, 8); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.rnti = rand_range(1, 65535); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.mcs_1 = rand_range(0, 31); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ul_index = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.carrier_indicator = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_request = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.mcs_2 = rand_range(0, 31); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tpmi = rand_range(0, 63); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.n_ul_rb = rand_range(6, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_parameters_rel11.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG; + + hi_dci0_pdus[3].pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[3].mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG; + + hi_dci0_pdus[4].pdu_type = NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG; + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.ncce_index = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level = rand_range(1, 2); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.start_symbol = rand_range(0, 4); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti = rand_range(1, 65535); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication = rand_range(0, 63); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.resource_assignment = rand_range(0, 7); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay = rand_range(0, 3); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs = rand_range(0, 12); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number = rand_range(0, 7); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 3); + + hi_dci0_req.hi_dci0_request_body.hi_dci0_pdu_list = hi_dci0_pdus; + mac->hi_dci0_req(mac, &hi_dci0_req); + + uint8_t num_tx_pdus = 2; + nfapi_tx_request_pdu_t tx_pdus[num_tx_pdus]; + memset(&tx_pdus, 0, sizeof(tx_pdus)); + + nfapi_tx_request_t tx_req; + memset(&tx_req, 0, sizeof(tx_req)); + tx_req.header.message_id = NFAPI_TX_REQUEST; + tx_req.header.phy_id = phy_id; + tx_req.sfn_sf = sfn_sf; + + tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req.tx_request_body.number_of_pdus = num_tx_pdus; + + uint32_t data[2]; + data[0] = 0x11223344; + data[1] = 0x55667788; + + tx_pdus[0].pdu_length = 8; + tx_pdus[0].pdu_index = 1; + tx_pdus[0].num_segments = 2; + tx_pdus[0].segments[0].segment_length = 4; + tx_pdus[0].segments[0].segment_data = (uint8_t*)&data[0]; + tx_pdus[0].segments[1].segment_length = 4; + tx_pdus[0].segments[1].segment_data = (uint8_t*)&data[1]; + + tx_pdus[1].pdu_length = 8; + tx_pdus[1].pdu_index = 2; + tx_pdus[1].num_segments = 2; + tx_pdus[1].segments[0].segment_length = 4; + tx_pdus[1].segments[0].segment_data = (uint8_t*)&data[0]; + tx_pdus[1].segments[1].segment_length = 4; + tx_pdus[1].segments[1].segment_data = (uint8_t*)&data[1]; + + + tx_req.tx_request_body.tx_pdu_list = tx_pdus; + mac->tx_req(mac, &tx_req); + } + + void generate_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) + { + mac_internal_t* instance = (mac_internal_t*)mac; + + nfapi_dl_config_request_t dl_config_req; + memset(&dl_config_req, 0, sizeof(dl_config_req)); + dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_req.header.phy_id = phy_id; + dl_config_req.sfn_sf = sfn_sf; + + dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_config_req.dl_config_request_body.number_pdu = 8; + + nfapi_dl_config_request_pdu_t pdus[8]; + memset(&pdus, 0, sizeof(pdus)); + for(int i = 0; i < 8; i++) + { + pdus[i].pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE; + + pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + pdus[i].bch_pdu.bch_pdu_rel8.length = 42; + pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = i; + pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = 56; + + } + + dl_config_req.dl_config_request_body.dl_config_pdu_list = pdus; + + /* + vendor_ext_tlv_1 ve; + ve.tl.tag = VENDOR_EXT_TLV_1_TAG; + ve.dummy = 999; + dl_config_req.vendor_extension = &ve.tl; + */ + + mac->dl_config_req(mac, &dl_config_req); + + + nfapi_ul_config_request_t ul_config_req; + memset(&ul_config_req, 0, sizeof(ul_config_req)); + ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_req.header.phy_id = phy_id; + ul_config_req.sfn_sf = sfn_sf; + mac->ul_config_req(mac, &ul_config_req); + + nfapi_hi_dci0_request_t hi_dci0_req; + memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); + hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req.header.phy_id = phy_id; + hi_dci0_req.sfn_sf = sfn_sf; + mac->hi_dci0_req(mac, &hi_dci0_req); + + + + nfapi_tx_request_t tx_req; + memset(&tx_req, 0, sizeof(tx_req)); + tx_req.header.message_id = NFAPI_TX_REQUEST; + tx_req.header.phy_id = phy_id; + tx_req.sfn_sf = sfn_sf; + + nfapi_tx_request_pdu_t tx_pdus[8]; + + tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req.tx_request_body.number_of_pdus = 0; + tx_req.tx_request_body.tx_pdu_list = &tx_pdus[0]; + + mac_pdu* buff = 0; + int i = 0; + std::list free_list; + do + { + buff = instance->mac->pop_rx_buffer(); + if(buff != 0) + { + if(buff->len == 0) + { + printf("[MAC] Buffer length = 0\n"); + } + + tx_req.tx_request_body.tx_pdu_list[i].pdu_length = buff->len; + tx_req.tx_request_body.tx_pdu_list[i].pdu_index = i; + tx_req.tx_request_body.tx_pdu_list[i].num_segments = 1; + tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = buff->len; + tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (uint8_t*)buff->buffer; + + tx_req.tx_request_body.number_of_pdus++; + i++; + + instance->mac->byte_count += buff->len; + + free_list.push_back(buff); + } + }while(buff != 0 && i < 8); + + mac->tx_req(mac, &tx_req); + + //for(int j = 0; j < tx_req.tx_request_body.number_of_pdus; ++j) + for(mac_pdu* pdu : free_list) + { + instance->mac->release_mac_pdu(pdu); + //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); + } + } + + void mac_subframe_ind(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) + { + + + //printf("[MAC] subframe indication phyid:%d sfnsf:%d\n", phy_id, sfn_sf); + mac_internal_t* instance = (mac_internal_t*)mac; + + if(instance->mac->tick == 1000) + { + if(instance->mac->byte_count > 0) + { + printf("[MAC] Rx rate %d bytes/sec\n", instance->mac->byte_count); + instance->mac->byte_count = 0; + } + instance->mac->tick = 0; + } + instance->mac->tick++; + + if(instance->mac->wireshark_test_mode) + { + generate_test_subframe(mac, phy_id, sfn_sf); + } + else + { + generate_subframe(mac, phy_id, sfn_sf); + } + } + + void mac_harq_ind(mac_t* mac, nfapi_harq_indication_t* ind) + { + } + void mac_crc_ind(mac_t* mac, nfapi_crc_indication_t* ind) + { + } + void mac_rx_ind(mac_t* mac, nfapi_rx_indication_t* ind) + { + mac_internal_t* instance = (mac_internal_t*)mac; + + for(int i = 0; i < ind->rx_indication_body.number_of_pdus; ++i) + { + uint16_t len = ind->rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length; + uint8_t* data = ind->rx_indication_body.rx_pdu_list[i].data; + //printf("[MAC] sfnsf:%d len:%d\n", ind->sfn_sf,len); + // + instance->tx_byte_count += len; + + int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr)); + + if(sendto_result < 0) + { + // error + } + } + + } + void mac_rach_ind(mac_t* mac, nfapi_rach_indication_t* ind) + { + } + void mac_srs_ind(mac_t* mac, nfapi_srs_indication_t* ind) + { + } + void mac_sr_ind(mac_t* mac, nfapi_sr_indication_t* ind) + { + } + void mac_cqi_ind(mac_t* mac, nfapi_cqi_indication_t* ind) + { + } + void mac_lbt_dl_ind(mac_t* mac, nfapi_lbt_dl_indication_t* ind) + { + } + void mac_nb_harq_ind(mac_t* mac, nfapi_nb_harq_indication_t* ind) + { + } + void mac_nrach_ind(mac_t* mac, nfapi_nrach_indication_t* ind) + { + } +} + diff --git a/nfapi/open-nFAPI/vnf_sim/src/main.cpp b/nfapi/open-nFAPI/vnf_sim/src/main.cpp new file mode 100644 index 0000000000..5dc7161157 --- /dev/null +++ b/nfapi/open-nFAPI/vnf_sim/src/main.cpp @@ -0,0 +1,1525 @@ +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include + +#include +#include "debug.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pool.h" + +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include "mac.h" + +#include + +//int vnf_main(int iPortP5, int, int); +int start_simulated_mac(int*, int*); +int read_xml(const char *xml_file); + +} + +static uint32_t rand_range(uint32_t min, uint32_t max) +{ + return ((rand() % (max + 1 - min)) + min); +} + + +void* vnf_allocate(size_t size) +{ + return (void*)memory_pool::allocate(size); +} + +void vnf_deallocate(void* ptr) +{ + memory_pool::deallocate((uint8_t*)ptr); +} + + + +class udp_data +{ + public: + bool enabled; + uint32_t rx_port; + uint32_t tx_port; + std::string tx_addr; +}; + + +class phy_info +{ + public: + + uint16_t index; + uint16_t id; + + std::vector rfs; + std::vector excluded_rfs; + + int remote_port; + std::string remote_addr; + + uint16_t earfcn; + +}; + +class rf_info +{ + public: + + uint16_t index; + uint16_t band; +}; + +class pnf_info +{ + public: + + std::vector phys; + std::vector rfs; +}; + +class vnf_p7_info +{ + public: + + vnf_p7_info() + : thread_started(false), + config(nfapi_vnf_p7_config_create(), + [] (nfapi_vnf_p7_config_t* f) { nfapi_vnf_p7_config_destory(f); }), + mac(0) + { + local_port = 0; + + timing_window = 0; + periodic_timing_enabled = 0; + aperiodic_timing_enabled = 0; + periodic_timing_period = 0; + + //config = nfapi_vnf_p7_config_create(); + } + + vnf_p7_info(const vnf_p7_info& other) = default; + + vnf_p7_info(vnf_p7_info&& other) = default; + + vnf_p7_info& operator=(const vnf_p7_info&) = default; + + vnf_p7_info& operator=(vnf_p7_info&&) = default; + + + + virtual ~vnf_p7_info() + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "*** vnf_p7_info delete ***\n"); + + //nfapi_vnf_p7_config_destory(config); + + // should we delete the mac? + } + + + int local_port; + std::string local_addr; + + unsigned timing_window; + unsigned periodic_timing_enabled; + unsigned aperiodic_timing_enabled; + unsigned periodic_timing_period; + + // This is not really the right place if we have multiple PHY, + // should be part of the phy struct + udp_data udp; + + bool thread_started; + + //nfapi_vnf_p7_config_t* config; + std::shared_ptr config; + + mac_t* mac; + + +}; + +class vnf_info +{ + public: + + uint8_t wireshark_test_mode; + + std::map pnfs; + + std::vector p7_vnfs; + +}; + + +/// maybe these should be in the mac file... +int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec) +{ + (void)tl; + (void)ppReadPackedMessage; + (void)ve; + return -1; +} + +int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) + { + case VENDOR_EXT_TLV_1_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + default: + return -1; + break; + } +} + +int vnf_sim_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_pack_vendor_extension_tlv\n"); + nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + switch(tlv->tag) + { + case VENDOR_EXT_TLV_2_TAG: + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); + vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + return 1; + } + break; + } + return -1; +} + +int vnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec) +{ + return -1; +} + + + + +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) + { + vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header); + if(!pull16(ppReadPackedMessage, &req->error_code, end)) + return 0; + } + return 1; +} + +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_REQ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + if(!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))) + return 0; + } + return 1; +} + +int vnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) + { + vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header); + return(!pull16(ppReadPackedMessage, &req->error_code, end)); + } + return 0; +} + +int vnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) + { + vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); + return (!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))); + } + return 0; +} + +void vnf_sim_trace(nfapi_trace_level_t level, const char* message, ...) +{ + va_list args; + va_start(args, message); + vprintf(message, args); + va_end(args); +} + +void mac_dl_config_req(mac_t* mac, nfapi_dl_config_request_t* req) +{ + vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); + + nfapi_vnf_p7_dl_config_req(info->config.get(), req); +} + +void mac_ul_config_req(mac_t* mac, nfapi_ul_config_request_t* req) +{ + vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); + + nfapi_vnf_p7_ul_config_req(info->config.get(), req); +} + +void mac_hi_dci0_req(mac_t* mac, nfapi_hi_dci0_request_t* req) +{ + vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); + + nfapi_vnf_p7_hi_dci0_req(info->config.get(), req); +} + +void mac_tx_req(mac_t* mac, nfapi_tx_request_t* req) +{ + vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); + + nfapi_vnf_p7_tx_req(info->config.get(), req); +} + +int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf) +{ + //printf("[VNF_SIM] subframe indication %d\n", sfn_sf); + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_subframe_ind(p7_vnf->mac, phy_id, sfn_sf); + return 0; +} +int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_harq_ind(p7_vnf->mac, ind); + return 1; +} +int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_crc_ind(p7_vnf->mac, ind); + return 1; +} +int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_rx_ind(p7_vnf->mac, ind); + return 1; +} +int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_rach_ind(p7_vnf->mac, ind); + return 1; +} +int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_srs_ind(p7_vnf->mac, ind); + return 1; +} +int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_sr_ind(p7_vnf->mac, ind); + return 1; +} +int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_cqi_ind(p7_vnf->mac, ind); + return 1; +} +int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_lbt_dl_ind(p7_vnf->mac, ind); + return 1; +} +int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_nb_harq_ind(p7_vnf->mac, ind); + return 1; +} +int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind) +{ + vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); + mac_nrach_ind(p7_vnf->mac, ind); + return 1; +} +int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg) +{ + if(msg->message_id == P7_VENDOR_EXT_IND) + { + //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; + //printf("[VNF_SIM] vendor_ext (error_code:%d)\n", ind->error_code); + } + else + { + printf("[VNF_SIM] unknown %d\n", msg->message_id); + } + return 0; +} +nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P7_VENDOR_EXT_IND) + { + *msg_size = sizeof(vendor_ext_p7_ind); + return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind)); + } + return 0; +} +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) +{ + free(header); +} + +//static pthread_t vnf_start_pthread; +static pthread_t vnf_p7_start_pthread; +void* vnf_p7_start_thread(void *ptr) +{ + printf("%s()\n", __FUNCTION__); + + //std::shared_ptr config = std::shared_ptr(ptr); + nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; + + nfapi_vnf_p7_start(config); + + return 0; +} + +void set_thread_priority(int priority) +{ + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) + { + printf("Failed to set scheduler to SCHED_RR\n"); + } + + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) + { + printf("Failed to set pthread sched policy SCHED_RR\n"); + } + + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + + struct sched_param thread_params; + thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) + { + printf("failed to set sched param\n"); + } +} + +void* vnf_p7_thread_start(void* ptr) +{ + printf("%s()\n", __FUNCTION__); + + set_thread_priority(79); + + vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; + + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->harq_indication = &phy_harq_indication; + p7_vnf->config->crc_indication = &phy_crc_indication; + p7_vnf->config->rx_indication = &phy_rx_indication; + p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->srs_indication = &phy_srs_indication; + p7_vnf->config->sr_indication = &phy_sr_indication; + p7_vnf->config->cqi_indication = &phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &phy_nrach_indication; + p7_vnf->config->malloc = &vnf_allocate; + p7_vnf->config->free = &vnf_deallocate; + + p7_vnf->config->trace = &vnf_sim_trace; + + p7_vnf->config->vendor_ext = &phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + + p7_vnf->mac->user_data = p7_vnf; + + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &vnf_allocate; + p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + + printf("[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config.get()); + + return 0; +} + +int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF_SIM] pnf connection indication idx:%d\n", p5_idx); + + pnf_info pnf; + vnf_info* vnf = (vnf_info*)(config->user_data); + vnf->pnfs.insert(std::pair(p5_idx, pnf)); + + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + nfapi_vnf_pnf_param_req(config, p5_idx, &req); + return 0; +} +int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) +{ + printf("[VNF_SIM] pnf disconnection indication idx:%d\n", p5_idx); + + + vnf_info* vnf = (vnf_info*)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + for(phy_info& phy : pnf.phys) + { + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + nfapi_vnf_p7_del_pnf((p7_vnf.config.get()), phy.id); + } + } + + return 0; +} + +int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp) +{ + printf("[VNF_SIM] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) + { + phy_info phy; + phy.index = resp->pnf_phy.phy[i].phy_config_index; + + printf("[VNF_SIM] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + + + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) + { + printf("[VNF_SIM] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs.push_back(resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + } + + + pnf.phys.push_back(phy); + } + for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) + { + rf_info rf; + rf.index = resp->pnf_rf.rf[i].rf_config_index; + + printf("[VNF_SIM] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); + + pnf.rfs.push_back(rf); + } + + nfapi_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = pnf.phys.size(); + + for(unsigned i = 0; i < pnf.phys.size(); ++i) + { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf.phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf.phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf.phys[i].rfs[0]; + } + + + nfapi_vnf_pnf_config_req(config, p5_idx, &req); + } + return 0; +} + +int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp) +{ + printf("[VNF_SIM] pnf config response idx:%d\n", p5_idx); + + if(1) + { + vnf_info* vnf = (vnf_info*)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + //pnf_info& pnf = find_result->second; + + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + } + else + { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + + //vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + return 0; +} + +int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp) +{ + printf("[VNF_SIM] pnf start response idx:%d\n", p5_idx); + + vnf_info* vnf = (vnf_info*)(config->user_data); + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + + if(p7_vnf.thread_started == false) + { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, &p7_vnf); + p7_vnf.thread_started = true; + } + else + { + // P7 thread already running. + } + + // start all the phys in the pnf. + + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + for(unsigned i = 0; i < pnf.phys.size(); ++i) + { + pnf_info& pnf = find_result->second; + + nfapi_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = pnf.phys[i].id; + nfapi_vnf_param_req(config, p5_idx, &req); + } + } + + return 0; +} +int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp) +{ + printf("[VNF_SIM] param response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) + { return item.id == resp->header.phy_id; }); + + if(found != pnf.phys.end()) + { + phy_info& phy = (*found); + + phy.remote_port = resp->nfapi_config.p7_pnf_port.value; + + struct sockaddr_in pnf_p7_sockaddr; + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + + phy.remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + + // for now just 1 + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + + printf("[VNF_SIM] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy.id, phy.remote_addr.c_str(), phy.remote_port, p7_vnf.timing_window, p7_vnf.periodic_timing_period, p7_vnf.aperiodic_timing_enabled, p7_vnf.periodic_timing_period); + + + nfapi_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_CONFIG_REQUEST; + req.header.phy_id = phy.id; + + + req.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req.nfapi_config.p7_vnf_port.value = p7_vnf.local_port; + req.num_tlv++; + + req.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf.local_addr.c_str()); + memcpy(&(req.nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req.num_tlv++; + + req.nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; + req.nfapi_config.timing_window.value = p7_vnf.timing_window; + req.num_tlv++; + + if(p7_vnf.periodic_timing_enabled || p7_vnf.aperiodic_timing_enabled) + { + req.nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; + req.nfapi_config.timing_info_mode.value = (p7_vnf.aperiodic_timing_enabled << 1) | (p7_vnf.periodic_timing_enabled); + req.num_tlv++; + + if(p7_vnf.periodic_timing_enabled) + { + req.nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; + req.nfapi_config.timing_info_period.value = p7_vnf.periodic_timing_period; + req.num_tlv++; + } + } + + req.nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + req.nfapi_config.earfcn.value = phy.earfcn; + req.num_tlv++; + + + if(1) + { + // Poplate all tlv for wireshark testing + req.subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + req.num_tlv++; + + req.subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; + req.num_tlv++; + req.subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; + req.num_tlv++; + req.subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + req.num_tlv++; + req.subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + req.num_tlv++; + + req.rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + req.num_tlv++; + req.rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + req.num_tlv++; + req.rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; + req.num_tlv++; + req.rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + req.num_tlv++; + req.rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + req.num_tlv++; + + req.phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + req.num_tlv++; + req.phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + req.num_tlv++; + req.phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + req.num_tlv++; + + req.sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + req.num_tlv++; + req.sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + req.num_tlv++; + req.sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + req.num_tlv++; + + req.prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + req.num_tlv++; + req.prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + req.num_tlv++; + req.prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + req.num_tlv++; + req.prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + + req.pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; + req.num_tlv++; + req.pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; + req.num_tlv++; + + req.pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; + req.num_tlv++; + req.pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; + req.num_tlv++; + req.pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; + req.num_tlv++; + req.pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; + req.num_tlv++; + + req.srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; + req.num_tlv++; + req.srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + req.num_tlv++; + req.srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; + req.num_tlv++; + req.srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; + req.num_tlv++; + + req.uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + req.num_tlv++; + req.uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + req.num_tlv++; + req.uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + req.num_tlv++; + + req.laa_config.ed_threshold_lbt_pdsch.tl.tag = NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG; + req.num_tlv++; + req.laa_config.ed_threshold_lbt_drs.tl.tag = NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG; + req.num_tlv++; + req.laa_config.pd_threshold.tl.tag = NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_type.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_tx.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_freeze.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG; + req.num_tlv++; + req.laa_config.tx_antenna_ports_drs.tl.tag = NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG; + req.num_tlv++; + req.laa_config.tx_power_drs.tl.tag = NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG; + req.num_tlv++; + + req.emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + req.num_tlv++; + req.emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + req.num_tlv++; + + req.nb_iot_config.operating_mode.tl.tag = NFAPI_NB_IOT_CONFIG_OPERATING_MODE_TAG; + req.nb_iot_config.operating_mode.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.anchor.tl.tag = NFAPI_NB_IOT_CONFIG_ANCHOR_TAG; + req.nb_iot_config.anchor.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.prb_index.tl.tag = NFAPI_NB_IOT_CONFIG_PRB_INDEX_TAG; + req.nb_iot_config.prb_index.value = rand_range(0, 0x1F); + req.num_tlv++; + req.nb_iot_config.control_region_size.tl.tag = NFAPI_NB_IOT_CONFIG_CONTROL_REGION_SIZE_TAG; + req.nb_iot_config.control_region_size.value = rand_range(1, 4); + req.num_tlv++; + req.nb_iot_config.assumed_crs_aps.tl.tag = NFAPI_NB_IOT_CONFIG_ASSUMED_CRS_APS_TAG; + req.nb_iot_config.assumed_crs_aps.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_ENABLED_TAG; + req.nb_iot_config.nprach_config_0_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_0_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_START_TIME_TAG; + req.nb_iot_config.nprach_config_0_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_0_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_0_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_0_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_0_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_ENABLED_TAG; + req.nb_iot_config.nprach_config_1_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_1_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_START_TIME_TAG; + req.nb_iot_config.nprach_config_1_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_1_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_1_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_1_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_1_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_ENABLED_TAG; + req.nb_iot_config.nprach_config_2_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_2_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_START_TIME_TAG; + req.nb_iot_config.nprach_config_2_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_2_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_2_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_2_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_2_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.three_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_THREE_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.three_tone_base_sequence.value = rand_range(0, 0x0F); + req.num_tlv++; + req.nb_iot_config.six_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_SIX_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.six_tone_base_sequence.value = rand_range(0, 0x03); + req.num_tlv++; + req.nb_iot_config.twelve_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_TWELVE_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.twelve_tone_base_sequence.value = rand_range(0, 0x1F); + req.num_tlv++; + req.nb_iot_config.three_tone_cyclic_shift.tl.tag = NFAPI_NB_IOT_CONFIG_THREE_TONE_CYCLIC_SHIFT_TAG; + req.nb_iot_config.three_tone_cyclic_shift.value = rand_range(0, 5); // what is the max + req.num_tlv++; + req.nb_iot_config.six_tone_cyclic_shift.tl.tag = NFAPI_NB_IOT_CONFIG_SIX_TONE_CYCLIC_SHIFT_TAG; + req.nb_iot_config.six_tone_cyclic_shift.value = rand_range(0, 5); // what is the max + req.num_tlv++; + req.nb_iot_config.dl_gap_config_enable.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_CONFIG_ENABLE_TAG; + req.nb_iot_config.dl_gap_config_enable.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.dl_gap_threshold.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_THRESHOLD_TAG; + req.nb_iot_config.dl_gap_threshold.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.dl_gap_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_PERIODICITY_TAG; + req.nb_iot_config.dl_gap_periodicity.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.dl_gap_duration_coefficient.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_DURATION_COEFFICIENT_TAG; + req.nb_iot_config.dl_gap_duration_coefficient.value = rand_range(0, 3); + req.num_tlv++; + + req.tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; + req.num_tlv++; + req.tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; + req.num_tlv++; + + req.l23_config.data_report_mode.tl.tag = NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG; + req.num_tlv++; + req.l23_config.sfnsf.tl.tag = NFAPI_L23_CONFIG_SFNSF_TAG; + req.num_tlv++; + } + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req.vendor_extension = &ve2.tl; + + nfapi_vnf_config_req(config, p5_idx, &req); + } + else + { + printf("[VNF_SIM] param response failed to find pnf %d phy %d\n", p5_idx, resp->header.phy_id); + } + } + else + { + printf("[VNF_SIM] param response failed to find pnf %d\n", p5_idx); + } + + return 0; +} + +int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp) +{ + printf("[VNF_SIM] config response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + + nfapi_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_vnf_start_req(config, p5_idx, &req); + + return 0; +} + +void test_p4_requests(nfapi_vnf_config_t* config, int p5_idx, int phy_id) +{ + { + nfapi_measurement_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_MEASUREMENT_REQUEST; + req.header.phy_id = phy_id; + + req.dl_rs_tx_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG; + req.dl_rs_tx_power.value = 42; + req.received_interference_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG; + req.received_interference_power.value = 42; + req.thermal_noise_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG; + req.thermal_noise_power.value = 42; + + nfapi_vnf_measurement_req(config, p5_idx, &req); + } + { + nfapi_rssi_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_RSSI_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; + lte_req.lte_rssi_request.frequency_band_indicator = 2; + lte_req.lte_rssi_request.measurement_period = 1000; + lte_req.lte_rssi_request.bandwidth = 50; + lte_req.lte_rssi_request.timeout = 0; + lte_req.lte_rssi_request.number_of_earfcns = 2; + lte_req.lte_rssi_request.earfcn[0] = 389; + lte_req.lte_rssi_request.earfcn[1] = 123; + + nfapi_vnf_rssi_request(config, p5_idx, <e_req); + + nfapi_rssi_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_RSSI_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG; + utran_req.utran_rssi_request.frequency_band_indicator = 2; + utran_req.utran_rssi_request.measurement_period = 1000; + utran_req.utran_rssi_request.timeout = 0; + utran_req.utran_rssi_request.number_of_uarfcns = 2; + utran_req.utran_rssi_request.uarfcn[0] = 2348; + utran_req.utran_rssi_request.uarfcn[1] = 52; + + nfapi_vnf_rssi_request(config, p5_idx, &utran_req); + + + nfapi_rssi_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_RSSI_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG; + geran_req.geran_rssi_request.frequency_band_indicator = 2; + geran_req.geran_rssi_request.measurement_period = 1000; + geran_req.geran_rssi_request.timeout = 0; + geran_req.geran_rssi_request.number_of_arfcns = 1; + geran_req.geran_rssi_request.arfcn[0].arfcn = 34; + geran_req.geran_rssi_request.arfcn[0].direction = 0; + + nfapi_vnf_rssi_request(config, p5_idx, &geran_req); + } + { + nfapi_cell_search_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG; + lte_req.lte_cell_search_request.earfcn = 1234; + lte_req.lte_cell_search_request.measurement_bandwidth = 50; + lte_req.lte_cell_search_request.exhaustive_search = 1; + lte_req.lte_cell_search_request.timeout = 1000; + lte_req.lte_cell_search_request.number_of_pci = 1; + lte_req.lte_cell_search_request.pci[0] = 234; + + nfapi_vnf_cell_search_request(config, p5_idx, <e_req); + + nfapi_cell_search_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG; + utran_req.utran_cell_search_request.uarfcn = 1234; + utran_req.utran_cell_search_request.exhaustive_search = 0; + utran_req.utran_cell_search_request.timeout = 1000; + utran_req.utran_cell_search_request.number_of_psc = 1; + utran_req.utran_cell_search_request.psc[0] = 234; + + nfapi_vnf_cell_search_request(config, p5_idx, &utran_req); + + nfapi_cell_search_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG; + geran_req.geran_cell_search_request.timeout = 1000; + geran_req.geran_cell_search_request.number_of_arfcn = 1; + geran_req.geran_cell_search_request.arfcn[0] = 8765; + + nfapi_vnf_cell_search_request(config, p5_idx, &geran_req); + } + { + nfapi_broadcast_detect_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG; + lte_req.lte_broadcast_detect_request.earfcn = 1234; + lte_req.lte_broadcast_detect_request.pci = 50; + lte_req.lte_broadcast_detect_request.timeout = 1000; + + lte_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + lte_req.pnf_cell_search_state.length = 3; + + nfapi_vnf_broadcast_detect_request(config, p5_idx, <e_req); + + nfapi_broadcast_detect_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_LTE; + utran_req.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG; + utran_req.utran_broadcast_detect_request.uarfcn = 1234; + utran_req.utran_broadcast_detect_request.psc = 50; + utran_req.utran_broadcast_detect_request.timeout = 1000; + + utran_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + utran_req.pnf_cell_search_state.length = 3; + + nfapi_vnf_broadcast_detect_request(config, p5_idx, &utran_req); + } + { + nfapi_system_information_schedule_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; + lte_req.lte_system_information_schedule_request.earfcn = 1234; + lte_req.lte_system_information_schedule_request.pci = 50; + lte_req.lte_system_information_schedule_request.downlink_channel_bandwidth = 100; + lte_req.lte_system_information_schedule_request.phich_configuration = 3; + lte_req.lte_system_information_schedule_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_schedule_request.retry_count = 4; + lte_req.lte_system_information_schedule_request.timeout = 1000; + + lte_req.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + lte_req.pnf_cell_broadcast_state.length = 3; + + nfapi_vnf_system_information_schedule_request(config, p5_idx, <e_req); + } + { + nfapi_system_information_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + lte_req.header.phy_id = phy_id; + + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG; + lte_req.lte_system_information_request.earfcn = 1234; + lte_req.lte_system_information_request.pci= 456; + lte_req.lte_system_information_request.downlink_channel_bandwidth = 5; + lte_req.lte_system_information_request.phich_configuration = 2; + lte_req.lte_system_information_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_request.number_of_si_periodicity = 1; + lte_req.lte_system_information_request.si_periodicity[0].si_periodicity = 3; + lte_req.lte_system_information_request.si_periodicity[0].si_index = 3; + lte_req.lte_system_information_request.si_window_length = 15; + lte_req.lte_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, <e_req); + + nfapi_system_information_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + utran_req.header.phy_id = phy_id; + + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG; + utran_req.utran_system_information_request.uarfcn = 1234; + utran_req.utran_system_information_request.psc = 456; + utran_req.utran_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, &utran_req); + + nfapi_system_information_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + geran_req.header.phy_id = phy_id; + + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG; + geran_req.geran_system_information_request.arfcn = 1234; + geran_req.geran_system_information_request.bsic = 21; + geran_req.geran_system_information_request.timeout = 1000; + + nfapi_vnf_system_information_request(config, p5_idx, &geran_req); + } + { + nfapi_nmm_stop_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NMM_STOP_REQUEST; + req.header.phy_id = phy_id; + nfapi_vnf_nmm_stop_request(config, p5_idx, &req); + } +} + + +int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp) +{ + printf("[VNF_SIM] start response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + + vnf_info* vnf = (vnf_info*)(config->user_data); + + if(vnf->wireshark_test_mode) + test_p4_requests(config, p5_idx, resp->header.phy_id); + + auto find_result = vnf->pnfs.find(p5_idx); + if(find_result != vnf->pnfs.end()) + { + pnf_info& pnf = find_result->second; + + + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) + { return item.id == resp->header.phy_id; }); + + if(found != pnf.phys.end()) + { + phy_info& phy = (*found); + + vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + + nfapi_vnf_p7_add_pnf((p7_vnf.config.get()), phy.remote_addr.c_str(), phy.remote_port, phy.id); + + + } + + + } + return 0; +} + + +nfapi_p4_p5_message_header_t* vnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) +{ + if(message_id == P5_VENDOR_EXT_RSP) + { + *msg_size = sizeof(vendor_ext_p5_rsp); + return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp)); + } + return 0; +} +void vnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) +{ + free(header); +} +int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) +{ + printf("[VNF_SIM] %s\n", __FUNCTION__); + + switch(msg->message_id) + { + case P5_VENDOR_EXT_RSP: + { + vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg; + printf("[VNF_SIM] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + + // send the start request + + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + break; + + } + + return 0; +} + +int read_vnf_xml(vnf_info& vnf, const char* xml_file) +{ + try + { + + std::ifstream input(xml_file); + + using boost::property_tree::ptree; + ptree pt; + + read_xml(input, pt); + + + + for(const auto& v : pt.get_child("vnf.vnf_p7_list")) + { + if(v.first == "vnf_p7") + { + vnf_p7_info vnf_p7; + vnf_p7.local_port = v.second.get("port"); + vnf_p7.local_addr = v.second.get("address"); + + vnf_p7.timing_window = v.second.get("timing_window"); + vnf_p7.periodic_timing_enabled = v.second.get("periodic_timing_enabled"); + vnf_p7.aperiodic_timing_enabled = v.second.get("aperiodic_timing_enabled"); + vnf_p7.periodic_timing_period = v.second.get("periodic_timing_window"); + + + boost::optional d = v.second.get_child_optional("data.udp"); + if(d.is_initialized()) + { + vnf_p7.udp.enabled = true; + vnf_p7.udp.rx_port = d.get().get("rx_port"); + vnf_p7.udp.tx_port = d.get().get("tx_port"); + vnf_p7.udp.tx_addr = d.get().get("tx_addr"); + } + else + { + vnf_p7.udp.enabled = false; + } + + vnf.wireshark_test_mode = v.second.get("wireshark_test_mode", 0); + + vnf_p7.mac = mac_create(vnf.wireshark_test_mode); + vnf_p7.mac->dl_config_req = &mac_dl_config_req; + vnf_p7.mac->ul_config_req = &mac_ul_config_req; + vnf_p7.mac->hi_dci0_req = &mac_hi_dci0_req; + vnf_p7.mac->tx_req = &mac_tx_req; + + if(vnf_p7.udp.enabled) + { + mac_start_data(vnf_p7.mac, + vnf_p7.udp.rx_port, + vnf_p7.udp.tx_addr.c_str(), + vnf_p7.udp.tx_port); + } + + vnf.p7_vnfs.push_back(vnf_p7); + } + } + } + catch(std::exception& e) + { + printf("%s", e.what()); + return -1; + } + catch(boost::exception& e) + { + printf("%s", boost::diagnostic_information(e).c_str()); + } + + struct ifaddrs *ifaddr; + getifaddrs(&ifaddr); + + + while(ifaddr) + { + int family = ifaddr->ifa_addr->sa_family; + if(family == AF_INET) + { + char host[128]; + getnameinfo(ifaddr->ifa_addr, sizeof(sockaddr_in), host, sizeof(host), NULL, 0, 0); + printf("%s\n", host); + } + ifaddr = ifaddr->ifa_next; + } + + return 0; + +} + + +int main(int argc, char *argv[]) +{ + if (argc < 3) + { + printf("Use parameters: \n"); + return 0; + } + + set_thread_priority(50); + + vnf_info vnf; + + if(read_vnf_xml(vnf, argv[2]) < 0) + { + printf("Failed to read xml file>\n"); + return 0; + } + + nfapi_vnf_config_t* config = nfapi_vnf_config_create(); + + config->vnf_ipv4 = 1; + config->vnf_p5_port = atoi(argv[1]); + config->pnf_connection_indication = &pnf_connection_indication_cb; + config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + config->pnf_param_resp = &pnf_param_resp_cb; + config->pnf_config_resp = &pnf_config_resp_cb; + config->pnf_start_resp = &pnf_start_resp_cb; + config->param_resp = ¶m_resp_cb; + config->config_resp = &config_resp_cb; + config->start_resp = &start_resp_cb; + config->vendor_ext = &vendor_ext_cb; + + + + config->trace = &vnf_sim_trace; + + config->malloc = &vnf_allocate; + config->free = &vnf_deallocate; + + config->user_data = &vnf; + + config->codec_config.unpack_vendor_extension_tlv = &vnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &vnf_sim_pack_vendor_extension_tlv; + + config->codec_config.unpack_p4_p5_vendor_extension = &vnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &vnf_sim_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &vnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &vnf_sim_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &vnf_allocate; + config->codec_config.deallocate = &vnf_deallocate; + + + printf("Calling nfapi_vnf_start\n"); + return nfapi_vnf_start(config); +} diff --git a/nfapi/open-nFAPI/xml/pnf_phy_1_A.xml b/nfapi/open-nFAPI/xml/pnf_phy_1_A.xml new file mode 100644 index 0000000000..45f8f46831 --- /dev/null +++ b/nfapi/open-nFAPI/xml/pnf_phy_1_A.xml @@ -0,0 +1,88 @@ + + + 0 + 0 + + + 500 + 500 + 500 + 500 + + 1 + 30 + 1 + 1 + + 0 + 0 + + 0 + + ALPHA + + + + + 88 + 2500 +
192.168.1.74
+ + 1 + + 22 + 22 + + 1 + 1 + + <3gpp_release_supported>31 + + 0 + + 8 + 8 + + + + + 0 + + + 1 + + + + + 5201 + 192.168.1.28 + 5200 + + +
+
+ + + 0 + 2 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + + 1 + 3 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + +
diff --git a/nfapi/open-nFAPI/xml/pnf_phy_1_A_ws.xml b/nfapi/open-nFAPI/xml/pnf_phy_1_A_ws.xml new file mode 100644 index 0000000000..5eb0284148 --- /dev/null +++ b/nfapi/open-nFAPI/xml/pnf_phy_1_A_ws.xml @@ -0,0 +1,90 @@ + + + 1 + + 0 + 0 + + + 500 + 500 + 500 + 500 + + 1 + 30 + 1 + 1 + + 0 + 0 + + 0 + + ALPHA + + + + + 88 + 2500 +
127.0.0.1
+ + 1 + + 22 + 22 + + 1 + 1 + + <3gpp_release_supported>31 + + 0 + + 8 + 8 + + + + + 0 + + + 1 + + + + + 7722 + 127.0.0.1 + 7733 + + +
+
+ + + 0 + 2 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + + 1 + 3 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + +
diff --git a/nfapi/open-nFAPI/xml/pnf_phy_1_B.xml b/nfapi/open-nFAPI/xml/pnf_phy_1_B.xml new file mode 100644 index 0000000000..302e1e19c5 --- /dev/null +++ b/nfapi/open-nFAPI/xml/pnf_phy_1_B.xml @@ -0,0 +1,88 @@ + + + 0 + 0 + + + 500 + 500 + 500 + 500 + + 1 + 30 + 1 + 1 + + 0 + 0 + + 0 + + ALPHA + + + + + 89 + 2510 +
127.0.0.1
+ + 1 + + 22 + 22 + + 1 + 1 + + <3gpp_release_supported>31 + + 0 + + 8 + 8 + + + + + 0 + + + 1 + + + + + 7744 + 127.0.0.1 + 7755 + + +
+
+ + + 0 + 2 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + + 1 + 3 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + +
diff --git a/nfapi/open-nFAPI/xml/pnf_phy_2_A.xml b/nfapi/open-nFAPI/xml/pnf_phy_2_A.xml new file mode 100644 index 0000000000..b820fa135e --- /dev/null +++ b/nfapi/open-nFAPI/xml/pnf_phy_2_A.xml @@ -0,0 +1,90 @@ + + + 0 + 0 + + + 500 + 500 + 500 + 500 + + 1 + 30 + 1 + 1 + + 0 + 0 + + 0 + + ALPHA + + + + 88 + 2500 +
127.0.0.1
+ + 1 + 22 + 22 + 1 + 1 + <3gpp_release_supported>31 + 0 + 8 + 8 + + + 0 + + +
+ + 44 + 2600 +
127.0.0.1
+ + 1 + 22 + 22 + 1 + 1 + <3gpp_release_supported>31 + 0 + 8 + 8 + + + 1 + + +
+
+ + + 0 + 2 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + + 1 + 4 + -30 + -230 + 2 + 1890 + 1890 + 1890 + 1890 + + +
diff --git a/nfapi/open-nFAPI/xml/vnf_A.xml b/nfapi/open-nFAPI/xml/vnf_A.xml new file mode 100644 index 0000000000..3791239ce7 --- /dev/null +++ b/nfapi/open-nFAPI/xml/vnf_A.xml @@ -0,0 +1,21 @@ + + + + + 5201 +
192.168.1.28
+ 10 + 0 + 0 + 0 + + + + 8891 + 192.168.1.28 + 8892 + + +
+
+
diff --git a/nfapi/open-nFAPI/xml/vnf_A_ws.xml b/nfapi/open-nFAPI/xml/vnf_A_ws.xml new file mode 100644 index 0000000000..c26adc3cfa --- /dev/null +++ b/nfapi/open-nFAPI/xml/vnf_A_ws.xml @@ -0,0 +1,23 @@ + + + + + + 1 + 5200 +
127.0.0.1
+ 10 + 0 + 0 + 0 + + + + 8891 + 127.0.0.1 + 8892 + + +
+
+
diff --git a/nfapi/open-nfapi.oai.patch b/nfapi/open-nfapi.oai.patch new file mode 100644 index 0000000000..5b91e3675b --- /dev/null +++ b/nfapi/open-nfapi.oai.patch @@ -0,0 +1,20010 @@ +diff --git a/common/public_inc/debug.h b/common/public_inc/debug.h +index 05e9870..14f97a1 100644 +--- a/common/public_inc/debug.h ++++ b/common/public_inc/debug.h +@@ -39,7 +39,8 @@ extern nfapi_trace_fn_t nfapi_trace_g; + extern nfapi_trace_level_t nfapi_trace_level_g; + + /*! NFAPI trace macro */ +-#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } ++//#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } ++#define NFAPI_TRACE(level, format, ...) { if (nfapi_trace_g) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } + + /*! Function to change the trace level + * \param new_level The modified trace level +diff --git a/nfapi/public_inc/nfapi_interface.h b/nfapi/public_inc/nfapi_interface.h +index 2d58c2a..f665d11 100644 +--- a/nfapi/public_inc/nfapi_interface.h ++++ b/nfapi/public_inc/nfapi_interface.h +@@ -1772,7 +1772,7 @@ typedef struct { + uint8_t number_of_cc; + struct { + uint8_t ri_size; +- uint8_t dl_cqi_pmi_size; ++ uint8_t dl_cqi_pmi_size[8]; + } cc[NFAPI_MAX_CC]; + } nfapi_ul_config_aperiodic_cqi_pmi_ri_report_t; + +diff --git a/nfapi/src/nfapi.c b/nfapi/src/nfapi.c +index 0e06963..3f017bc 100644 +--- a/nfapi/src/nfapi.c ++++ b/nfapi/src/nfapi.c +@@ -823,6 +823,10 @@ uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *e + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag); + } ++ else ++ { ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag); ++ } + } + + return 1; +diff --git a/nfapi/src/nfapi_p7.c b/nfapi/src/nfapi_p7.c +index a3b0141..69ff860 100644 +--- a/nfapi/src/nfapi_p7.c ++++ b/nfapi/src/nfapi_p7.c +@@ -111,6 +111,8 @@ static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void* tlv, uint8_t **ppWrite + { + nfapi_dl_config_dci_dl_pdu_rel8_t* value = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; + ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format); ++ + return ( push8(value->dci_format, ppWritePackedMsg, end) && + push8(value->cce_idx, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && +@@ -234,6 +236,8 @@ static uint8_t pack_dl_config_bch_pdu_rel8_value(void* tlv, uint8_t **ppWritePac + { + nfapi_dl_config_bch_pdu_rel8_t* value = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; + ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__); ++ + return( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end)); +@@ -545,6 +549,8 @@ static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePac + { + nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich); ++ + if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) && + push8(value->number_dci, ppWritePackedMsg, end) && + push16(value->number_pdu, ppWritePackedMsg, end) && +@@ -574,6 +580,8 @@ static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePac + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__); ++ + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && +@@ -587,6 +595,8 @@ static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePac + break; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { ++ //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__); ++ + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value))) + return 0; + } +@@ -684,10 +694,21 @@ static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uin + { + nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; + +- return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && +- pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) && +- pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); ++ //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && ++ //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) && ++ //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); ++ { ++ uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); ++ uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value); ++ uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + ++ if (!x || !y || !z) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z); ++ } ++ ++ return x && y && z; ++ } + } + + static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end) +@@ -796,9 +817,10 @@ static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppW + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0) + return 0; + +- if(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size > 0) ++ uint8_t j; ++ for(j = 0; j < 8; ++j) + { +- if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size, ppWritePackedMsg, end) == 0) ++ if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0) + return 0; + } + } +@@ -1518,7 +1540,21 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, + for(j = 0; j < pdu->num_segments; ++j) + { + // Use -1 as it is unbounded +- if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) ++ // DJP - does not handle -1 ++ // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) ++ int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end); ++ ++ if (0 && pdu->segments[j].segment_length == 3) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, ++ pdu->segments[j].segment_data[0], ++ pdu->segments[j].segment_data[1], ++ pdu->segments[j].segment_data[2] ++ ); ++ } ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret); ++ ++ if (push_ret == 0) + { + return 0; + } +@@ -1532,9 +1568,13 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e + { + nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; + +- return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && +- pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value) && +- pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); ++ int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); ++ int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value); ++ int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); ++ ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z); ++ ++ return x && y && z; + } + + static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +@@ -1844,6 +1884,8 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP + { + nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; + ++ //printf("RX ULSCH BODY\n"); ++ + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + +@@ -1851,21 +1893,26 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP + uint16_t i = 0; + uint16_t offset = 2; // taking into account the number_of_pdus + uint16_t total_number_of_pdus = value->number_of_pdus; ++ //printf("ULSCH:pdus:%d\n", total_number_of_pdus); ++ + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) + { ++ //printf("NFAPI_RX_UE_INFORMATION_TAG\n"); + offset += 4 + 6; + } + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { ++ //printf("NFAPI_RX_INDICATION_REL8_TAG\n"); + offset += 4 + 7; + } + + if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) + { ++ //printf("NFAPI_RX_INDICATION_REL9_TAG\n"); + offset += 4 + 2; + } + } +@@ -2592,11 +2639,16 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu + return -1; + } + ++ if (pMessageHeader->message_id != NFAPI_TIMING_INFO) ++ { ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp); ++ } + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) + { + case NFAPI_DL_CONFIG_REQUEST: ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__); + result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + +@@ -2609,6 +2661,7 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu + break; + + case NFAPI_TX_REQUEST: ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); + result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + +@@ -2621,6 +2674,7 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu + break; + + case NFAPI_RX_ULSCH_INDICATION: ++ //printf("RX ULSCH\n"); + result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + +@@ -3482,9 +3536,10 @@ static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppRe + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0) + return 0; + +- if(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size > 0) ++ uint8_t j; ++ for(j = 0; j < 8; ++j) + { +- if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size, end) == 0) ++ if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0) + return 0; + } + } +@@ -4394,6 +4449,14 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * + { + if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end)) + return 0; ++ if (0 && pdu->segments[0].segment_length == 3) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, ++ pdu->segments[0].segment_data[0], ++ pdu->segments[0].segment_data[1], ++ pdu->segments[0].segment_data[2] ++ ); ++ } + } + else + { +diff --git a/pnf/public_inc/nfapi_pnf_interface.h b/pnf/public_inc/nfapi_pnf_interface.h +index f93624d..b25caf2 100644 +--- a/pnf/public_inc/nfapi_pnf_interface.h ++++ b/pnf/public_inc/nfapi_pnf_interface.h +@@ -319,10 +319,10 @@ typedef struct nfapi_pnf_config + * 0 will be returned if it fails. + * + * \code +- * nfapi_pnf_config_t* config = nfapi_pnf_config_create(); ++ * nfapi_pnf_config_t* config = nfapi_pnf_config_create(void); + * \endcode + */ +-nfapi_pnf_config_t* nfapi_pnf_config_create(); ++nfapi_pnf_config_t* nfapi_pnf_config_create(void); + + /*! Delete a pnf configuration + * \param config A pointer to a pnf configuraiton +@@ -681,7 +681,7 @@ typedef struct nfapi_pnf_p7_config + /*! Create and initialise a nfapi_pnf_p7_config structure + * \return A pointer to a PNF P7 config structure + */ +-nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(); ++nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(void); + + /*! Delete an nfapi_pnf_p7_config structure + * \param config +diff --git a/pnf/src/pnf.c b/pnf/src/pnf.c +index d6cf364..d0a7fa6 100644 +--- a/pnf/src/pnf.c ++++ b/pnf/src/pnf.c +@@ -412,10 +412,10 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) + { + nfapi_start_request_t req; + +- NFAPI_TRACE(NFAPI_TRACE_INFO, "START.request received\n"); +- + nfapi_pnf_config_t* config = &(pnf->_public); + ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state); ++ + // unpack the message + if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { +diff --git a/pnf/src/pnf_interface.c b/pnf/src/pnf_interface.c +index 74f29a0..7310fc0 100644 +--- a/pnf/src/pnf_interface.c ++++ b/pnf/src/pnf_interface.c +@@ -76,6 +76,7 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config) + + sleep(1); + } ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__); + + return 0; + } +@@ -227,7 +228,7 @@ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* res + } + else + { +- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id); ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + +diff --git a/pnf/src/pnf_p7.c b/pnf/src/pnf_p7.c +index 0fd7828..02b828d 100644 +--- a/pnf/src/pnf_p7.c ++++ b/pnf/src/pnf_p7.c +@@ -25,12 +25,64 @@ + #include + #include + #include ++#include + + #include "pnf_p7.h" + + #define FAPI2_IP_DSCP 0 + +-uint32_t get_current_time_hr() ++extern uint16_t sf_ahead; ++//uint16_t sf_ahead=4; ++ ++void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset) ++{ ++ *frameP = *frameP + ((*subframeP + offset) / 10); ++ ++ *subframeP = ((*subframeP + offset) % 10); ++} ++ ++void subtract_sf(uint16_t *frameP, uint16_t *subframeP, int offset) ++{ ++ if (*subframeP < offset) ++ { ++ *frameP = (*frameP+1024-1)%1024; ++ } ++ *subframeP = (*subframeP+10-offset)%10; ++} ++ ++uint16_t sfnsf_add_sf(uint16_t sfnsf, int offset) ++{ ++ uint16_t new_sfnsf; ++ uint16_t sfn = NFAPI_SFNSF2SFN(sfnsf); ++ uint16_t sf = NFAPI_SFNSF2SF(sfnsf); ++ ++ //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf); ++ add_sf(&sfn, &sf, offset); ++ ++ new_sfnsf = sfn<<4|sf; ++ ++ //printf("%s() sfn:%u sf:%u offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, sfn, sf, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf)); ++ ++ return new_sfnsf; ++} ++ ++uint16_t sfnsf_subtract_sf(uint16_t sfnsf, int offset) ++{ ++ uint16_t new_sfnsf; ++ uint16_t sfn = NFAPI_SFNSF2SFN(sfnsf); ++ uint16_t sf = NFAPI_SFNSF2SF(sfnsf); ++ ++ //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf); ++ subtract_sf(&sfn, &sf, offset); ++ ++ new_sfnsf = sfn<<4|sf; ++ ++ //printf("%s() offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf)); ++ ++ return new_sfnsf; ++} ++ ++uint32_t pnf_get_current_time_hr(void) + { + struct timeval now; + (void)gettimeofday(&now, NULL); +@@ -64,11 +116,14 @@ void pnf_p7_free(pnf_p7_t* pnf_p7, void* ptr) + // todo : for now these just malloc/free need to move to a memory cache + nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7) + { +- return pnf_p7_malloc(pnf_p7, sizeof(nfapi_dl_config_request_t)); ++ void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_dl_config_request_t)); ++ //printf("%s() ptr:%p\n", __FUNCTION__, ptr); ++ return ptr; + } + + void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t* pnf_p7) + { ++ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->dl_config_request_body.dl_config_pdu_list); +@@ -77,17 +132,21 @@ void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t + { + free(req->dl_config_request_body.dl_config_pdu_list); + } ++ req->dl_config_request_body.dl_config_pdu_list=0; + + pnf_p7_free(pnf_p7, req); + } + + nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7) + { +- return pnf_p7_malloc(pnf_p7, sizeof(nfapi_ul_config_request_t)); ++ void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_ul_config_request_t)); ++ //printf("%s() ptr:%p\n", __FUNCTION__, ptr); ++ return ptr; + } + + void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t* pnf_p7) + { ++ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->ul_config_request_body.ul_config_pdu_list); +@@ -96,6 +155,7 @@ void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t + { + free(req->ul_config_request_body.ul_config_pdu_list); + } ++ req->ul_config_request_body.ul_config_pdu_list=0; + + pnf_p7_free(pnf_p7, req); + } +@@ -107,6 +167,7 @@ nfapi_hi_dci0_request_t* allocate_nfapi_hi_dci0_request(pnf_p7_t* pnf_p7) + + void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pnf_p7) + { ++ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list); + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->hi_dci0_request_body.hi_dci0_pdu_list); +@@ -115,6 +176,7 @@ void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pn + { + free(req->hi_dci0_request_body.hi_dci0_pdu_list); + } ++ req->hi_dci0_request_body.hi_dci0_pdu_list=0; + + pnf_p7_free(pnf_p7, req); + } +@@ -127,6 +189,9 @@ nfapi_tx_request_t* allocate_nfapi_tx_request(pnf_p7_t* pnf_p7) + void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7) + { + int i = 0; ++ ++ //printf("%s() SFN/SF:%d %s req:%p pdu[0]:data:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->tx_request_body.tx_pdu_list[i].segments[0].segment_data); ++ + for(i = 0; i < req->tx_request_body.number_of_pdus; ++i) + { + void* data = req->tx_request_body.tx_pdu_list[i].segments[0].segment_data; +@@ -139,6 +204,7 @@ void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7) + { + free(data); + } ++ data=0; + } + + +@@ -150,6 +216,7 @@ void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7) + { + free(req->tx_request_body.tx_pdu_list); + } ++ req->tx_request_body.tx_pdu_list=0; + + pnf_p7_free(pnf_p7, req); + } +@@ -169,6 +236,7 @@ void deallocate_nfapi_lbt_dl_config_request(nfapi_lbt_dl_config_request_t* req, + { + free(req->lbt_dl_config_request_body.lbt_dl_config_req_pdu_list); + } ++ req->lbt_dl_config_request_body.lbt_dl_config_req_pdu_list=0; + + pnf_p7_free(pnf_p7, req); + } +@@ -307,11 +375,11 @@ void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reas + } + + +-uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) ++static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) + { + if(now_hr < sf_start_hr) + { +- NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier that start of subframe\n"); ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + return 0; + } + else +@@ -482,29 +550,41 @@ void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7) + + void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) + { ++ struct timespec t; ++ clock_gettime( CLOCK_MONOTONIC, &t); ++ ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(sfn_sf:%d) t:%ld.%09ld\n", __FUNCTION__, NFAPI_SFNSF2DEC(sfn_sf), t.tv_sec, t.tv_nsec); ++ ++ if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) ++ { ++ pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf; ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - enter\n"); ++ (pnf_p7->_public.tx_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.tx_req); ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - exit\n"); ++ } + 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; ++ //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); ++ //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); + } + 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); + } +- if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) +- { +- pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf; +- (pnf_p7->_public.tx_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.tx_req); +- } + if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) + { + pnf_p7->_public.dummy_subframe.lbt_dl_config_req->sfn_sf = sfn_sf; ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy lbt - enter\n"); + (pnf_p7->_public.lbt_dl_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_subframe.lbt_dl_config_req); + } + } +@@ -526,10 +606,14 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + return -1; + } + ++#if 1 + // save the curren time and sfn_sf +- pnf_p7->sf_start_time_hr = get_current_time_hr(); ++ pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); + pnf_p7->sfn_sf = sfn_sf; + ++ uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); ++ uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); ++ + // If the subframe_buffer has been configured + if(pnf_p7->_public.subframe_buffer_size != 0) + { +@@ -550,6 +634,10 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/sf (%d -> %d)\n", pnf_p7->sfn_sf_shift, NFAPI_SFNSF2DEC(sfn_sf), shifted_sfn_sf); + sfn_sf = shifted_sfn_sf; + ++ // ++ // DJP - why does the shift not apply to pnf_p7->sfn_sf??? ++ // ++ + pnf_p7->sfn_sf_shift = 0; + } + +@@ -558,77 +646,119 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + + nfapi_pnf_p7_subframe_buffer_t* subframe_buffer = &(pnf_p7->subframe_buffer[buffer_index]); + ++ uint8_t tx_buffer_index = tx_sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; ++ nfapi_pnf_p7_subframe_buffer_t* tx_subframe_buffer = &(pnf_p7->subframe_buffer[tx_buffer_index]); ++ ++ //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); ++ ++ if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d subframe_buffer->sfn_sf:%d tx_subframe_buffer->sfn_sf:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] " ++ "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n", ++ __FUNCTION__, ++ pnf_p7->sfn_sf_shift, ++ NFAPI_SFNSF2DEC(subframe_buffer->sfn_sf), ++ NFAPI_SFNSF2DEC(tx_subframe_buffer->sfn_sf), ++ sfn_sf_dec, buffer_index, subframe_buffer->dl_config_req, subframe_buffer->tx_req, ++ tx_sfn_sf_dec, tx_buffer_index, tx_subframe_buffer->dl_config_req, tx_subframe_buffer->tx_req); ++ + // if the subframe buffer sfn sf is set then we have atlease 1 message + // from the vnf. + // todo : how to handle the messages we don't have, send dummies for + // now +- if(subframe_buffer->sfn_sf == sfn_sf) ++ ++ //printf("tx_subframe_buffer->sfn_sf:%d sfn_sf_tx:%d\n", tx_subframe_buffer->sfn_sf, sfn_sf_tx); ++ //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf); ++ if(tx_subframe_buffer->sfn_sf == sfn_sf_tx) + { +- if(subframe_buffer->dl_config_req != 0) ++ if(tx_subframe_buffer->tx_req != 0) + { +- if(pnf_p7->_public.dl_config_req) +- (pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), subframe_buffer->dl_config_req); ++ if(pnf_p7->_public.tx_req) ++ (pnf_p7->_public.tx_req)(&(pnf_p7->_public), tx_subframe_buffer->tx_req); + +- deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); ++ //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + } + else + { + // send dummy +- if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_config_req) ++ if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) + { +- pnf_p7->_public.dummy_subframe.dl_config_req->sfn_sf = sfn_sf; +- (pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.dl_config_req); ++ pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf_tx; ++ (pnf_p7->_public.tx_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.tx_req); + } + } + +- if(subframe_buffer->ul_config_req != 0) ++ if(tx_subframe_buffer->dl_config_req != 0) + { +- if(pnf_p7->_public.ul_config_req) +- (pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), subframe_buffer->ul_config_req); ++ if(pnf_p7->_public.dl_config_req) ++ (pnf_p7->_public.dl_config_req)(&(pnf_p7->_public), tx_subframe_buffer->dl_config_req); + +- deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); ++ //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + } + else + { + // send dummy +- if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req) ++ if(pnf_p7->_public.dl_config_req && pnf_p7->_public.dummy_subframe.dl_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.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); + } + } + +- if(subframe_buffer->hi_dci0_req != 0) ++ if(tx_subframe_buffer->hi_dci0_req != 0) + { + if(pnf_p7->_public.hi_dci0_req) +- (pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), subframe_buffer->hi_dci0_req); ++ (pnf_p7->_public.hi_dci0_req)(&(pnf_p7->_public), tx_subframe_buffer->hi_dci0_req); + +- deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); ++ //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + } + else + { + //send dummy + 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; ++ 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); + } + } + +- if(subframe_buffer->tx_req != 0) ++ if(tx_subframe_buffer->dl_config_req != 0) ++ { ++ deallocate_nfapi_dl_config_request(tx_subframe_buffer->dl_config_req, pnf_p7); ++ tx_subframe_buffer->dl_config_req = 0; ++ } ++ if(tx_subframe_buffer->tx_req != 0) ++ { ++ deallocate_nfapi_tx_request(tx_subframe_buffer->tx_req, pnf_p7); ++ tx_subframe_buffer->tx_req = 0; ++ } ++ if(tx_subframe_buffer->hi_dci0_req != 0) ++ { ++ deallocate_nfapi_hi_dci0_request(tx_subframe_buffer->hi_dci0_req, pnf_p7); ++ tx_subframe_buffer->hi_dci0_req = 0; ++ } ++ } ++ else ++ { ++ // If we ever need to "send" a dummy ul_config this won't work!!! ++ send_dummy_subframe(pnf_p7, sfn_sf_tx); ++ } ++ ++ if(subframe_buffer->sfn_sf == sfn_sf) ++ { ++ ++ if(subframe_buffer->ul_config_req != 0) + { +- if(pnf_p7->_public.tx_req) +- (pnf_p7->_public.tx_req)(&(pnf_p7->_public), subframe_buffer->tx_req); ++ if(pnf_p7->_public.ul_config_req) ++ (pnf_p7->_public.ul_config_req)(&(pnf_p7->_public), subframe_buffer->ul_config_req); + +- deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); ++ //deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + } + else + { + // send dummy +- if(pnf_p7->_public.tx_req && pnf_p7->_public.dummy_subframe.tx_req) ++ if(pnf_p7->_public.ul_config_req && pnf_p7->_public.dummy_subframe.ul_config_req) + { +- pnf_p7->_public.dummy_subframe.tx_req->sfn_sf = sfn_sf; +- (pnf_p7->_public.tx_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.tx_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); + } + } + +@@ -637,7 +767,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + if(pnf_p7->_public.lbt_dl_config_req) + (pnf_p7->_public.lbt_dl_config_req)(&(pnf_p7->_public), subframe_buffer->lbt_dl_config_req); + +- deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); ++ //deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); + } + else + { +@@ -650,14 +780,35 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + + } + +- memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t)); +- pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1; +- } +- else +- { +- send_dummy_subframe(pnf_p7, sfn_sf); ++ //if(subframe_buffer->dl_config_req != 0) ++ //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); ++ //if(subframe_buffer->tx_req != 0) ++ //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); ++ if(subframe_buffer->ul_config_req != 0) ++ { ++ deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); ++ subframe_buffer->ul_config_req = 0; ++ ++ } ++ //if(subframe_buffer->hi_dci0_req != 0) ++ //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); ++ if(subframe_buffer->lbt_dl_config_req != 0) ++ { ++ deallocate_nfapi_lbt_dl_config_request(subframe_buffer->lbt_dl_config_req, pnf_p7); ++ subframe_buffer->lbt_dl_config_req = 0; ++ } ++ } // sfn_sf match ++ ++ if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0) ++ { ++ memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t)); ++ pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1; + } + ++ //printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period); ++ //printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send); ++ //printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter); ++ + // send the periodic timing info if configured + if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) + { +@@ -678,14 +829,15 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + } + else + { +- send_dummy_subframe(pnf_p7, sfn_sf); ++ //send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + ++ //printf("pnf_p7->tick:%d\n", pnf_p7->tick); + if(pnf_p7->tick == 1000) + { + +- NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id, ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id, + pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late, + pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late, + pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late, +@@ -694,6 +846,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) + memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats)); + } + pnf_p7->tick++; ++#endif + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { +@@ -724,7 +877,7 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) + if(recv_sfn_sf_dec > ((current_sfn_sf_dec + timing_window) % NFAPI_MAX_SFNSFDEC)) + { + // out of window +- //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is late %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is late %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + } + else + { +@@ -736,7 +889,7 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) + else + { + // too late +- //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in late %d (%d)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (current_sfn_sf_dec - recv_sfn_sf_dec)); ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in late %d (delta:%d)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (current_sfn_sf_dec - recv_sfn_sf_dec)); + } + + } +@@ -751,8 +904,8 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) + } + else + { +- // to far in the future +- //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (%d) [%d]\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (recv_sfn_sf_dec - current_sfn_sf_dec), timing_window); ++ // too far in the future ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_sf_dec, name, recv_sfn_sf_dec, (recv_sfn_sf_dec - current_sfn_sf_dec), timing_window); + } + + } +@@ -785,15 +938,35 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ + return; + } + +- if(is_p7_request_in_window(req->sfn_sf, "dl_config_request", pnf_p7)) +- { +- uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); +- uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; ++ if ( ++ 0 && ++ (NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 || ++ NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0 ++ ) ++ ) ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n", ++ NFAPI_SFNSF2DEC(req->sfn_sf), ++ req->dl_config_request_body.number_pdcch_ofdm_symbols, ++ req->dl_config_request_body.number_dci, ++ req->dl_config_request_body.number_pdu, ++ req->dl_config_request_body.number_pdsch_rnti, ++ req->dl_config_request_body.transmission_power_pcfich ++ ); ++ ++ if(is_p7_request_in_window(req->sfn_sf, "dl_config_request", pnf_p7)) ++ { ++ uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); ++ uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; ++ ++ struct timespec t; ++ clock_gettime(CLOCK_MONOTONIC, &t); ++ ++ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + // if there is already an dl_config_req make sure we free it. + if(pnf_p7->subframe_buffer[buffer_index].dl_config_req != 0) + { +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "HERE HERE HERE\n"); ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_sf:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), buffer_index); + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); +@@ -860,6 +1033,11 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + ++ struct timespec t; ++ clock_gettime(CLOCK_MONOTONIC, &t); ++ ++ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); ++ + if(pnf_p7->subframe_buffer[buffer_index].ul_config_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)", +@@ -876,7 +1054,7 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ + } + else + { +- //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_config_req SFN/SF %d/%d\n", pMyPhyInfo->sfnSf, SFNSF2SFN(req->sfn_sf), SFNSF2SF(req->sfn_sf)); ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_config_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SF %d\n", NFAPI_SFNSF2DEC(pnf_p7->sfn_sf), NFAPI_SFNSF2DEC(req->sfn_sf)); + deallocate_nfapi_ul_config_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) +@@ -994,6 +1172,16 @@ void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + ++ struct timespec t; ++ clock_gettime(CLOCK_MONOTONIC, &t); ++ ++ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); ++ ++ if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n", ++ __FUNCTION__, ++ NFAPI_SFNSF2DEC(req->sfn_sf), ++ req->tx_request_body.number_of_pdus); ++ + if(pnf_p7->subframe_buffer[buffer_index].tx_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing tx_req at index %d (%d/%d)", +@@ -1010,6 +1198,8 @@ void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) + } + else + { ++ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() TX_REQUEST Request is outside of window REQ:SFN_SF:%d CURR:SFN_SF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), NFAPI_SFNSF2DEC(pnf_p7->sfn_sf)); ++ + deallocate_nfapi_tx_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) +@@ -1126,12 +1316,27 @@ uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + uint32_t t2 = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + ++ if (0) ++ { ++ static uint32_t prev_t2 = 0; ++ ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(now_time_hr:%u sfn_sf:%d sf_start_time_Hr:%u) sf_time_us:%u t2:%u prev_t2:%u diff:%u\n", ++ __FUNCTION__, ++ now_time_hr, NFAPI_SFNSF2DEC(sfn_sf), sf_start_time_hr, ++ sf_time_us, ++ t2, ++ prev_t2, ++ t2-prev_t2); ++ ++ prev_t2 = t2; ++ } ++ + return t2; + } + + uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr) + { +- uint32_t now_time_hr = get_current_time_hr(); ++ uint32_t now_time_hr = pnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + +@@ -1391,6 +1596,8 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) + // read the segment + recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, header.message_length, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + ++ now_hr_time = pnf_get_current_time_hr(); //DJP - moved to here - get closer timestamp??? ++ + if(recvfrom_result > 0) + { + pnf_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time); +@@ -1417,7 +1624,10 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) + + // need to update the time as we would only use the value from the + // select +- now_hr_time = get_current_time_hr(); ++#if 0 ++// DJP - why do this here and not on return from recv??? ++ now_hr_time = pnf_get_current_time_hr(); ++#endif + } + while(recvfrom_result > 0); + } +@@ -1512,7 +1722,7 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) + + selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout); + +- uint32_t now_hr_time = get_current_time_hr(); ++ uint32_t now_hr_time = pnf_get_current_time_hr(); + + if(selectRetval == 0) + { +diff --git a/pnf_sim/src/main.cpp b/pnf_sim/src/main.cpp +index 38767d8..e2622cf 100644 +--- a/pnf_sim/src/main.cpp ++++ b/pnf_sim/src/main.cpp +@@ -1124,16 +1124,18 @@ int fapi_rx_ulsch_ind(fapi_t* fapi, fapi_rx_ulsch_ind_t* ind) + rx_ind.header.phy_id = data->p7_config->phy_id; + rx_ind.sfn_sf = ind->sfn_sf; + +- if(((pnf_info*)(data->config->user_data))->wireshark_test_mode) ++ if(1)//((pnf_info*)(data->config->user_data))->wireshark_test_mode) + { + rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; +- rx_ind.rx_indication_body.number_of_pdus = 8; ++ rx_ind.rx_indication_body.number_of_pdus = 1; + + uint8_t rx_data[1024]; + + nfapi_rx_indication_pdu_t pdus[rx_ind.rx_indication_body.number_of_pdus]; + memset(&pdus, 0, sizeof(pdus)); + ++ strcpy((char*)rx_data, (char*)"123456789"); ++ + for(int i = 0; i < rx_ind.rx_indication_body.number_of_pdus;++i) + { + +@@ -1142,13 +1144,13 @@ int fapi_rx_ulsch_ind(fapi_t* fapi, fapi_rx_ulsch_ind_t* ind) + pdus[i].rx_ue_information.rnti = rand_range(1, 65535); + + pdus[i].rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; +- pdus[i].rx_indication_rel8.length = rand_range(0, 1024); +- pdus[i].rx_indication_rel8.offset = 1; ++ pdus[i].rx_indication_rel8.length = 10;//rand_range(0, 1024); ++ pdus[i].rx_indication_rel8.offset = 0;//djp - 1; + pdus[i].rx_indication_rel8.ul_cqi = rand_range(0, 255); + pdus[i].rx_indication_rel8.timing_advance = rand_range(0, 63); + +- pdus[i].rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; +- pdus[i].rx_indication_rel9.timing_advance_r9 = rand_range(0, 7690); ++ //pdus[i].rx_indication_rel9.tl.tag = NFAPI_RX_INDICATION_REL9_TAG; ++ //pdus[i].rx_indication_rel9.timing_advance_r9 = rand_range(0, 7690); + + pdus[i].data = &rx_data[0]; + } +diff --git a/vnf/inc/vnf_p7.h b/vnf/inc/vnf_p7.h +index ab9a335..fc2ab4e 100644 +--- a/vnf/inc/vnf_p7.h ++++ b/vnf/inc/vnf_p7.h +@@ -116,7 +116,8 @@ typedef struct { + + } vnf_p7_t; + +-uint32_t get_current_time_hr(); ++uint32_t vnf_get_current_time_hr(void); ++ + uint16_t increment_sfn_sf(uint16_t sfn_sf); + int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info); + int send_mac_subframe_indications(vnf_p7_t* config); +diff --git a/vnf/public_inc/nfapi_vnf_interface.h b/vnf/public_inc/nfapi_vnf_interface.h +index 6659e5d..4629013 100644 +--- a/vnf/public_inc/nfapi_vnf_interface.h ++++ b/vnf/public_inc/nfapi_vnf_interface.h +@@ -450,7 +450,7 @@ typedef struct nfapi_vnf_config + /*! Creates and initialise the vnf config structure before use + * \return A pointer to a vnf config structure + */ +-nfapi_vnf_config_t* nfapi_vnf_config_create(); ++nfapi_vnf_config_t* nfapi_vnf_config_create(void); + + /*! Delete an vnf config + */ +@@ -864,7 +864,7 @@ typedef struct nfapi_vnf_p7_config + /*! Creates and initializes the nfapi_vnf_p7_config structure before use + * \return A pointer to an allocated vnf p7 configuration + */ +-nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create(); ++nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create(void); + + /*! Cleanup and delete nfapi_vnf_p7_config structure + * \param config A pointer to an vnf p7 configuration structure +diff --git a/vnf/src/vnf.c b/vnf/src/vnf.c +index fea3cf7..6800ee2 100644 +--- a/vnf/src/vnf.c ++++ b/vnf/src/vnf.c +@@ -82,11 +82,18 @@ void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* no + + nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx) + { ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : config->pnf_list:%p\n", __FUNCTION__, config->pnf_list); ++ + nfapi_vnf_pnf_info_t* curr = config->pnf_list; + while(curr != 0) + { + if(curr->p5_idx == p5_idx) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->p5_idx:%d p5_idx:%d\n", __FUNCTION__, curr->p5_idx, p5_idx); + return curr; ++ } ++ ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : curr->next:%p\n", __FUNCTION__, curr->next); + + curr = curr->next; + } +diff --git a/vnf/src/vnf_interface.c b/vnf/src/vnf_interface.c +index e559730..0aba0a2 100644 +--- a/vnf/src/vnf_interface.c ++++ b/vnf/src/vnf_interface.c +@@ -342,6 +342,7 @@ int nfapi_vnf_start(nfapi_vnf_config_t* config) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t)); ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf); + memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t)); + pnf->p5_sock = p5Sock; + pnf->p5_idx = p5_idx++; +@@ -663,7 +664,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy + info->p5_idx = p5_idx; + info->phy_id = vnf->next_phy_id++; + +- info->timing_window = 10; ++ info->timing_window = 30; // This seems to override what gets set by the user - why??? + info->timing_info_mode = 0x03; + info->timing_info_period = 128; + +diff --git a/vnf/src/vnf_p7.c b/vnf/src/vnf_p7.c +index 8630385..1304176 100644 +--- a/vnf/src/vnf_p7.c ++++ b/vnf/src/vnf_p7.c +@@ -15,6 +15,8 @@ + */ + + ++#include ++ + #include + #include + #include +@@ -159,7 +161,7 @@ vnf_p7_rx_message_t* vnf_p7_rx_reassembly_queue_add_segment(vnf_p7_t* vnf_p7, vn + msg->sequence_number = sequence_number; + msg->num_segments_expected = m ? 255 : segment_number + 1; + msg->num_segments_received = 1; +- msg->rx_hr_time = get_current_time_hr(); ++ msg->rx_hr_time = vnf_get_current_time_hr(); + + msg->segments[segment_number].buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, data_len); + memcpy(msg->segments[segment_number].buffer, data, data_len); +@@ -216,7 +218,7 @@ void vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7_t* vnf_p7, vnf_p7_rx_reas + vnf_p7_rx_message_t* iterator = queue->msg_queue; + vnf_p7_rx_message_t* previous = 0; + +- uint32_t rx_hr_time = get_current_time_hr(); ++ uint32_t rx_hr_time = vnf_get_current_time_hr(); + + while(iterator != 0) + { +@@ -254,7 +256,7 @@ void vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7_t* vnf_p7, vnf_p7_rx_reas + } + } + +-uint32_t get_current_time_hr() ++uint32_t vnf_get_current_time_hr() + { + struct timeval now; + (void)gettimeofday(&now, NULL); +@@ -297,7 +299,7 @@ struct timespec timespec_delta(struct timespec start, struct timespec end) + return temp; + } + +-uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) ++static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) + { + if(now_hr < sf_start_hr) + { +@@ -321,7 +323,7 @@ uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) + + uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr) + { +- uint32_t now_time_hr = get_current_time_hr(); ++ uint32_t now_time_hr = vnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + +@@ -344,7 +346,7 @@ uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t + + uint32_t calculate_transmit_timestamp(uint16_t sfn_sf, uint32_t sf_start_time_hr) + { +- uint32_t now_time_hr = get_current_time_hr(); ++ uint32_t now_time_hr = vnf_get_current_time_hr(); + + uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); + +@@ -410,6 +412,8 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea + + int len = nfapi_p7_message_pack(header, buffer, sizeof(buffer), &vnf_p7->_public.codec_config); + ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); ++ + if(len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() failed to pack p7 message phy_id:%d\n", __FUNCTION__, header->phy_id); +@@ -429,6 +433,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea + int segment = 0; + int offset = NFAPI_P7_HEADER_LENGTH; + uint8_t tx_buffer[vnf_p7->_public.segment_size]; ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); + for(segment = 0; segment < segment_count; ++segment) + { + uint8_t last = 0; +@@ -851,7 +856,7 @@ void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vn + + void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + { +- uint32_t now_time_hr = get_current_time_hr(); ++ uint32_t now_time_hr = vnf_get_current_time_hr(); + + if (pRecvMsg == NULL || vnf_p7 == NULL) + { +@@ -871,7 +876,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, ind.header.phy_id); + uint32_t t4 = calculate_t4(now_time_hr, phy->sfn_sf, vnf_p7->sf_start_time_hr); + +- uint32_t tx_2_rx = t4 - ind.t1; ++ uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSFDEC - ind.t1 ; + uint32_t pnf_proc_time = ind.t3 - ind.t2; + + // divide by 2 using shift operator +@@ -881,7 +886,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + { + phy->latency[phy->min_sync_cycle_count] = latency; + +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n", ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4, + tx_2_rx, pnf_proc_time, latency); + } +@@ -923,15 +928,27 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + + if(1) + { +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", +- NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, ++ struct timespec ts; ++ clock_gettime(CLOCK_MONOTONIC, &ts); ++ ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", ++ NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ts.tv_sec, ts.tv_nsec, ind.header.phy_id, + ind.t1, ind.t2, ind.t3, t4, +- tx_2_rx, pnf_proc_time, latency, phy->sf_offset, phy->sf_offset_filtered, ++ tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->sf_offset, phy->sf_offset_filtered, + (ind.t1previous_t1), (ind.t2previous_t2)); + } + + } + ++ if (phy->filtered_adjust && (phy->sf_offset_filtered > 1e6 || phy->sf_offset_filtered < -1e6)) ++ { ++ phy->filtered_adjust = 0; ++ phy->zero_count=0; ++ phy->min_sync_cycle_count = 2; ++ phy->in_sync = 0; ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s - ADJUST TOO BAD - go out of filtered phy->sf_offset_filtered:%d\n", __FUNCTION__, phy->sf_offset_filtered); ++ } ++ + if(phy->min_sync_cycle_count) + phy->min_sync_cycle_count--; + +@@ -954,7 +971,6 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + phy->sf_offset = ind.t2 - (ind.t1 - phy->average_latency); + + sfn_sf_dec += (phy->sf_offset / 1000); +- + } + else + { +@@ -976,12 +992,11 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + { + phy->adjustment = NFAPI_SFNSF2DEC(new_sfn_sf) - NFAPI_SFNSF2DEC(curr_sfn_sf); + +- //NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d\n", ind.header.phy_id, phy->adjustment); ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_sf_offset_filtered:%d phy->previous_sf_offset_filtered:%d phy->sf_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_sf_offset_filtered, phy->previous_sf_offset_filtered, phy->sf_offset_trend); + + phy->previous_t1 = 0; + phy->previous_t2 = 0; + +- + if(phy->previous_sf_offset_filtered > 0) + { + if( phy->sf_offset_filtered > phy->previous_sf_offset_filtered) +@@ -1083,9 +1098,14 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + + if(phy->insync_minor_adjustment != 0) + { +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d suframes (sf_offset_filtered:%d) %d %d %d\n", ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (sf_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, +- phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->sf_offset_filtered, insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend); ++ phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, ++ phy->sf_offset_filtered, ++ insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend, ++ NFAPI_SFNSF2DEC(new_sfn_sf), ++ NFAPI_SFNSF2DEC(curr_sfn_sf), ++ phy->adjustment); + } + } + } +@@ -1121,10 +1141,13 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + // out of sync? + } + +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d suframes (adjusment:%d sf_offset_filtered:%d) %d %d %d\n", ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (adjustment:%d sf_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, + phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->sf_offset_filtered, +- insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend); ++ insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend, ++ NFAPI_SFNSF2DEC(new_sfn_sf), ++ NFAPI_SFNSF2DEC(curr_sfn_sf), ++ phy->adjustment); + + } + else if(phy->adjustment < 0) +@@ -1151,7 +1174,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + // out of sync? + } + +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d suframes (adjusment:%d sf_offset_filtered:%d) %d %d %d\n", ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d subframes (adjustment:%d sf_offset_filtered:%d) %d %d %d\n", + NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ind.header.phy_id, + phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->sf_offset_filtered, + insync_minor_adjustment_1, insync_minor_adjustment_2, phy->sf_offset_trend); +@@ -1219,7 +1242,16 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) + return; + } + +- // todo : how to use this? ++ if (vnf_p7 && vnf_p7->p7_connections) ++ { ++ int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); ++ ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); ++ if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); ++ } ++ } + } + + void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +diff --git a/vnf/src/vnf_p7_interface.c b/vnf/src/vnf_p7_interface.c +index ab4f00c..a35d8e3 100644 +--- a/vnf/src/vnf_p7_interface.c ++++ b/vnf/src/vnf_p7_interface.c +@@ -142,6 +142,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n"); + + ++ //struct timespec original_pselect_timeout; + struct timespec pselect_timeout; + pselect_timeout.tv_sec = 0; + pselect_timeout.tv_nsec = 1000000; // ns in a 1 us +@@ -157,13 +158,13 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + + struct timespec sf_duration; + sf_duration.tv_sec = 0; +- sf_duration.tv_nsec = 1000000; // ns in a 1 us ++ sf_duration.tv_nsec = 1e6; // We want 1ms pause + + struct timespec sf_start; + clock_gettime(CLOCK_MONOTONIC, &sf_start); + long millisecond = sf_start.tv_nsec / 1e6; + sf_start = timespec_add(sf_start, sf_duration); +- //NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + + while(vnf_p7->terminate == 0) + { +@@ -181,6 +182,8 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + + if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) ) + { ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec); ++ + + if((pselect_start.tv_sec > sf_start.tv_sec) || + ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec))) +@@ -196,16 +199,26 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + { + // still time before the end of the subframe wait + pselect_timeout = timespec_sub(sf_start, pselect_start); ++ ++#if 0 ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sf_start:%d.%ld pselect_start:%d.%ld pseclect_timeout:%d.%ld\n", ++ __FUNCTION__, ++ sf_start.tv_sec, sf_start.tv_nsec, ++ pselect_start.tv_sec, pselect_start.tv_nsec, ++ pselect_timeout.tv_sec, pselect_timeout.tv_nsec); ++#endif + } + ++//original_pselect_timeout = pselect_timeout; ++ + // detemine how long to sleep in ns before the start of the next 1ms + //pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000); + +- //uint8_t underun_possiable =0; ++ //uint8_t underrun_possible =0; + + // if we are not sleeping until the next milisecond due to the + // insycn minor adjment flag it so we don't consider it an error +- //uint8_t underun_possiable =0; ++ //uint8_t underrun_possible =0; + /* + { + nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; +@@ -222,7 +235,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000); + + +- //underun_possiable = 1; ++ //underrun_possible = 1; + } + else if(phy->insync_minor_adjustment < 0) + { +@@ -237,41 +250,98 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + */ + + ++//long wraps = pselect_timeout.tv_nsec % 1e9; ++ ++ + selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL); + + clock_gettime(CLOCK_MONOTONIC, &pselect_stop); + ++ nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; ++ ++if (selectRetval==-1 && errno == 22) ++{ ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n", ++ pselect_timeout.tv_sec, pselect_timeout.tv_nsec, ++ phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, ++ sf_duration.tv_sec, sf_duration.tv_nsec); ++} ++#if 0 ++ if (selectRetval != 0 || phy->insync_minor_adjustment_duration != 0) ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "pselect()=%d maxSock:%d vnf_p7->socket:%d pselect_timeout:%u.%u original_pselect_timeout:%u.%u\n", ++ selectRetval, maxSock, vnf_p7->socket, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, ++ original_pselect_timeout.tv_sec, original_pselect_timeout.tv_nsec); ++#endif ++ + if(selectRetval == 0) + { +- // calcualte the start of the next subframe ++ // calculate the start of the next subframe + sf_start = timespec_add(sf_start, sf_duration); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + +- nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; + if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0) + { +- NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %dus\n", phy->insync_minor_adjustment); ++ long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000); ++ ++ sf_start.tv_nsec -= insync_minor_adjustment_ns; ++ ++#if 1 ++ if (sf_start.tv_nsec > 1e9) ++ { ++ sf_start.tv_sec++; ++ sf_start.tv_nsec-=1e9; ++ } ++ else if (sf_start.tv_nsec < 0) ++ { ++ sf_start.tv_sec--; ++ sf_start.tv_nsec+=1e9; ++ } ++#else ++ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec); + if(phy->insync_minor_adjustment > 0) + { + // decrease the subframe duration a little +- sf_start.tv_nsec = sf_start.tv_nsec - (phy->insync_minor_adjustment * 1000); ++ if (sf_start.tv_nsec > insync_minor_adjustment_ns) ++ sf_start.tv_nsec -= insync_minor_adjustment_ns; ++ else ++ { ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns); ++ sf_start.tv_sec--; ++ sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns; ++ } + } + else if(phy->insync_minor_adjustment < 0) + { + // todo check we don't go below 0 + // increase the subframe duration a little +- sf_start.tv_nsec = sf_start.tv_nsec - (phy->insync_minor_adjustment * 1000); ++ sf_start.tv_nsec += insync_minor_adjustment_ns; ++ ++ if (sf_start.tv_nsec < 0) ++ { ++ NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec); ++ sf_start.tv_sec++; ++ sf_start.tv_nsec += 1e9; ++ } + } ++#endif + + //phy->insync_minor_adjustment = 0; +- phy->insync_minor_adjustment_duration--; ++ phy->insync_minor_adjustment_duration--; ++ ++ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n", ++ phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration); ++ ++ if (phy->insync_minor_adjustment_duration==0) ++ { ++ phy->insync_minor_adjustment = 0; ++ } + } + /* + long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6; + if(millisecond == pselect_stop_millisecond) + { + // we have woke up in the same subframe +- if(underun_possiable == 0) ++ if(underrun_possible == 0) + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec); + } + else if(((millisecond + 1) % 1000) != pselect_stop_millisecond) +@@ -298,7 +368,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + + if(selectRetval == 0) + { +- vnf_p7->sf_start_time_hr = get_current_time_hr(); ++ vnf_p7->sf_start_time_hr = vnf_get_current_time_hr(); + + // pselect timed out + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; +@@ -326,14 +396,18 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) + else + { + // pselect error +- if(selectRetval == EINTR) ++ if(selectRetval == -1 && errno == EINTR) + { + // a sigal was received. + } + else + { +- NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec); ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond); + // should we exit now? ++ if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration ++ { ++ usleep(100000); ++ } + } + } + +@@ -360,10 +434,12 @@ int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config) + + int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id) + { +- NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(phy_id:%d pnf_addr:%s:%d)\n", __FUNCTION__, phy_id, pnf_p7_addr, pnf_p7_port); ++ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p phy_id:%d pnf_addr:%s pnf_p7_port:%d)\n", __FUNCTION__, config, phy_id, pnf_p7_addr, pnf_p7_port); + + if(config == 0) +- return -1; ++ { ++ return -1; ++ } + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + +@@ -411,6 +487,8 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id) + } + int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req) + { ++ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req); ++ + if(config == 0 || req == 0) + return -1; + +diff --git a/vnf_sim/src/mac.cpp b/vnf_sim/src/mac.cpp +index aa97f72..fa6f487 100644 +--- a/vnf_sim/src/mac.cpp ++++ b/vnf_sim/src/mac.cpp +@@ -743,7 +743,7 @@ extern "C" + { + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = rand_range(0, 3); +- cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size = rand_range(0, 255); ++ cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0] = rand_range(0, 255); + } + + cqi_ri_information.cqi_ri_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG; +diff --git a/vnf_sim/src/main.cpp b/vnf_sim/src/main.cpp +index b79ac40..5dc7161 100644 +--- a/vnf_sim/src/main.cpp ++++ b/vnf_sim/src/main.cpp +@@ -428,6 +428,20 @@ void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) + free(header); + } + ++//static pthread_t vnf_start_pthread; ++static pthread_t vnf_p7_start_pthread; ++void* vnf_p7_start_thread(void *ptr) ++{ ++ printf("%s()\n", __FUNCTION__); ++ ++ //std::shared_ptr config = std::shared_ptr(ptr); ++ nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; ++ ++ nfapi_vnf_p7_start(config); ++ ++ return 0; ++} ++ + void set_thread_priority(int priority) + { + //printf("%s(priority:%d)\n", __FUNCTION__, priority); +@@ -458,6 +472,8 @@ void set_thread_priority(int priority) + + void* vnf_p7_thread_start(void* ptr) + { ++ printf("%s()\n", __FUNCTION__); ++ + set_thread_priority(79); + + vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; +@@ -494,10 +510,10 @@ void* vnf_p7_thread_start(void* ptr) + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + +- nfapi_vnf_p7_start(p7_vnf->config.get()); ++ printf("[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); ++ pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config.get()); + + return 0; +- + } + + int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) +diff --git a/wireshark/packet-nfapi.c b/wireshark/packet-nfapi.c +index da0edb0..7e0f23f 100755 +--- a/wireshark/packet-nfapi.c ++++ b/wireshark/packet-nfapi.c +@@ -1,6069 +1,12284 @@ +-/* ++/* packet-nfapi.c ++* Routines for Network Function Application Platform Interface (nFAPI) dissection + * Copyright 2017 Cisco Systems, Inc. + * +-* Licensed under the Apache License, Version 2.0 (the "License"); +-* you may not use this file except in compliance with the License. +-* You may obtain a copy of the License at ++* Wireshark - Network traffic analyzer ++* By Gerald Combs ++* Copyright 1998 Gerald Combs ++* ++* This program 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 2 ++* of the License, or (at your option) any later version. ++* ++* This program 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 this program; if not, write to the Free Software ++* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +-* http://www.apache.org/licenses/LICENSE-2.0 ++* References: ++* SCF082.09.04 http://scf.io/en/documents/082_-_nFAPI_and_FAPI_specifications.php + * +-* 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. + */ +- +- +-#include "config.h" +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++void proto_register_nfapi(void); ++void proto_reg_handoff_nfapi(void); ++ + #define NFAPI_HEADER_LENGTH 8 +-#define NFAPI_P7_HEADER_LENGTH 16 +- +-typedef int(*Decode_operation)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset); +- +-static const value_string nfapi_error_vals[] = { +- { 0x0, "MSG_OK" }, +- { 0x1, "MSG_INVALID_STATE" }, +- { 0x2, "MSG_INVALID_CONFIG" }, +- { 0x3, "SFN_OUT_OF_SYNC" }, +- { 0x4, "MSG_SUBFRAME_ERR" }, +- { 0x5, "MSG_BCH_MISSING" }, +- { 0x6, "MSG_BCH_MISSING" }, +- { 0x7, "MSG_HI_ERR" }, +- { 0x8, "MSG_TX_ERR" }, +- { 0, NULL }, +-}; +- +-static const value_string nfapi_p4_error_vals[] = { +- { 100, "MSG_OK" }, +- { 101, "MSG_INVALID_STATE" }, +- { 102, "MSG_INVALID_CONFIG" }, +- { 103, "MSG_RAT_NOT_SUPPORTED" }, +- { 200, "MSG_NMM_STOP_OK" }, +- { 201, "MSG_NMM_STOP_IGNORED" }, +- { 202, "MSG_NMM_STOP_INVALID_STATE" }, +- { 300, "MSG_PROCEDURE_COMPLETE" }, +- { 301, "MSG_PROCEDURE_STOPPED" }, +- { 302, "MSG_PARTIAL_RESULTS" }, +- { 303, "MSG_TIMEOUT" }, +- { 0, NULL }, +-}; +- +-static const value_string nfapi_rat_type_vals[] = { +- { 0, "LTE" }, +- { 1, "UTRAN" }, +- { 2, "GERAN" }, +- { 0, NULL }, +-}; +- +-typedef enum{ +- UN_ALIGNED_SYNCHRONIZATION = 0, +- INTERNAL_PNF_FRAME_ALIGNMENT, +- ABSOLUTE_TIME_ALIGNED_SYNCHRONIZATION +-} nfapi_sync_mode_e; +- +-static const value_string nfapi_sync_mode_vals[] = { +- { UN_ALIGNED_SYNCHRONIZATION, "UN-ALIGNED SYNCHRONIZATION" }, +- { INTERNAL_PNF_FRAME_ALIGNMENT, "INTERNAL PNF FRAME ALIGNMENT" }, +- { ABSOLUTE_TIME_ALIGNED_SYNCHRONIZATION, "ABSOLUTE TIME ALIGNED SYNCHRONIZATION" } +-}; +- +-typedef enum { +- NONE = 0, +- GPS, +- GLONASS, +- BEIDOU +-} location_mode_e; +- +-static const value_string location_mode_vals[] = { +- { NONE, "NONE" }, +- { GPS, "GPS" }, +- { GLONASS, "GLONASS" }, +- { BEIDOU, "BeiDou" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_uplink_rs_hopping_vals[] = { +- { 0, "RS_NO_HOPPING" }, +- { 1, "RS_GROUP_HOPPING" }, +- { 2, "RS_SEQUENCE_HOPPING" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_laa_carrier_type_vals[] = { +- { 0, "No multi carrier support" }, +- { 1, "Mode A1" }, +- { 2, "Mode A12" }, +- { 3, "Mode B1" }, +- { 4, "Mode B2" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_mutli_carrier_lbt_support_vals[] = { +- { 0, "Multi carrier Mode A1" }, +- { 1, "Multi carrier Mode A2" }, +- { 2, "Multi carrier Mode B1" }, +- { 3, "Multi carrier Mode B2" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_lbt_dl_req_pdu_type[] = { +- { 0, "LBT_PDSCH_REQ PDU" }, +- { 1, "LBT_DRS_REQ PDU" }, +- { 0, NULL } +-}; +- +- +-static const value_string nfapi_lbt_dl_ind_pdu_type[] = { +- { 0, "LBT_PDSCH_RSP PDU" }, +- { 1, "LBT_DRS_RSP PDU" }, +- +- { 0, NULL } +-}; +- +- +- +- +-/* These are definitions where data 0 & 1 represent/provide a string name*/ +- +-static const true_false_string true_false_strname = { +- "TRUE", +- "FALSE" +-}; +- +-static const true_false_string nfapi_csi_report_type_strname = { +- "Periodic", +- "Aperiodic", +-}; +- +-static const true_false_string nfapi_control_type_string_name = { +- "CQI/PMI", +- "RI", +-}; +- +-static const true_false_string transport_block_to_codeword_swap_flag = { +- "NO_SWAPPING", +- "SWAPPED" +-}; +- +-static const true_false_string virtual_resource_block_assignment_flag = { +- "LOCALIZED", +- "DISTRIBUTED" +-}; +- +-static const true_false_string ngap_string_name = { +- "N-GAP 1", +- "N-GAP 2" +-}; +- +-static const true_false_string nprb_strname = { +- "= 2", +- "= 3", +-}; +- +-static const true_false_string cyclic_prefix_type_strname = { +- "CP_NORMAL", +- "CP_EXTENDED" +-}; +- +-static const true_false_string support_strname = { +- "No Support", +- "Support" +-}; +- +-static const true_false_string partial_sf_support_strname = +-{ +- "Start partial SF support", +- "End partial SF support" +-}; +- +-static const true_false_string phich_duration_strname = { +- "PHICH_D_NORMAL", +- "PHICH_D_EXTENDED" +-}; +- +-static const true_false_string high_speed_flag_strname = { +- "HS_UNRESTRICTED_SET", +- "HS_RESTRICTED_SET" +-}; +- +-static const true_false_string hopping_mode_strname = { +- "HM_INTER_SF", +- "HM_INTRA_INTER_SF" +-}; +- +-static const true_false_string enabled_disabled_strname = { +- "Enabled", +- "Disabled" +-}; +- +-static const true_false_string srs_simult_tx_strname = { +- "No Simultaneous Transmission", +- "Simultaneous Transmission" +-}; +- +-static const true_false_string crc_flag_strname = { +- "CRC_CORRECT", +- "CRC_ERROR" +-}; +- +-static const true_false_string hi_value_strname = { +- "HI_NACK", +- "HI_ACK" +-}; +- +-static const true_false_string flag_tb2_strname = { +- "HI_NOT_PRESENT", +- "HI_PRESENT" +-}; +- +-static const true_false_string nfapi_multi_carrier_tx_strname = { +- "Mutual transmission (self-deferral support for current carrier)", +- "Transmit on channel access win (no self-deferral)" +-}; +- +-static const true_false_string nfapi_multi_carrier_freeze_strname = { +- "Absence of other technology isn’t guaranteed", +- "Absence of other technology is guaranteed" +-}; +- +-static const value_string nfapi_dl_config_pdu_type_vals[] = { +- { 0, "DL_CONFIG_DCI_DL_PDU" }, +- { 1, "DL_CONFIG_BCH_PDU" }, +- { 2, "DL_CONFIG_MCH_PDU" }, +- { 3, "DL_CONFIG_DLSCH_PDU" }, +- { 4, "DL_CONFIG_PCH_PDU" }, +- { 5, "DL_CONFIG_PRS_PDU" }, +- { 6, "DL_CONFIG_CSI_RS_PDU" }, +- { 7, "DL_CONFIG_EPDCCH_DL_PDU" }, +- { 8, "DL_CONFIG_EPDCCH_DL_PDU" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_duplex_mode_vals[] = { +- { 0, "TDD" }, +- { 1, "FDD" }, +- { 2, "HD-FDD" }, +- { 0, NULL } +-}; +- +-static const value_string modulation_vals[] = { +- { 2, "QPSK" }, +- { 4, "16QAM" }, +- { 6, "64QAM" }, +- { 8, "256QAM" }, +- { 0, NULL } +-}; +- +-static const value_string pch_modulation_vals[] = { +- { 0, "QPSK" }, +- { 0, NULL } +-}; +- +-static const value_string ue_mode_vals[] = { +- { 0, "non LC/CE UE" }, +- { 1, "LC/CE UE" }, +- { 0, NULL } +-}; +- +-static const value_string csi_rs_class_vals[] = { +- { 0, "not used" }, +- { 1, "Class A" }, +- { 1, "Class B" }, +- { 0, NULL } +-}; +- +-static const value_string csi_rs_cdm_type_vals[] = { +- { 0, "cdm 2" }, +- { 1, "cdm 4" }, +- { 0, NULL } +-}; +- +-static const value_string antenna_ports_vals[] = { +- { 0, "1 antenna ports" }, +- { 1, "2 antenna ports" }, +- { 2, "4 antenna ports" }, +- { 0, NULL } +-}; +- +-static const value_string combs_vals[] = { +- { 0, "2 TC" }, +- { 1, "4 TC" }, +- { 0, NULL } +-}; +- +-static const value_string resource_allocation_type_vals[] = { +- { 0, "type 0" }, +- { 1, "type 1" }, +- { 2, "type 2 1A/1B/1D" }, +- { 3, "type 2 1C" }, +- { 4, "type 2 6-1A" }, +- { 5, "type UEModeB" }, +- { 0, NULL } +-}; +- +-static const value_string transmission_scheme_vals[] = { +- { 0, "SINGLE_ANTENNA_PORT_0" }, +- { 1, "TX_DIVERSITY" }, +- { 2, "LARGE_DELAY_CDD" }, +- { 3, "CLOSED_LOOP_SPATIAL_MULTIPLEXING" }, +- { 4, "MULTI_USER_MIMO" }, +- { 5, "CLOSED_LOOP_RANK_1_PRECODING" }, +- { 6, "SINGLE_ANTENNA_PORT_5" }, +- { 7, "SINGLE_ANTENNA_PORT_7" }, +- { 8, "SINGLE_ANTENNA_PORT_8" }, +- { 9, "DUAL_LAYER_TX_PORT_7_AND_8" }, +- { 10, "UP_TO_8_LAYER_TX" }, +- { 11, "SINGLE_ANTENNA_PORT_11" }, +- { 12, "SINGLE_ANTENNA_PORT_13" }, +- { 13, "SINGLE_ANTENNA_PORT_11_13" }, +- { 0, NULL } +-}; +- +-static const value_string ul_transmission_scheme_vals[] = { +- { 0, "SINGLE_ANTENNA_PORT_10" }, +- { 1, "CLOSED_LOOP_SPATIAL_MULTIPLEXING" }, +-}; +- +-static const value_string dci_format_vals[] = { +- { 0, "1" }, +- { 1, "1A" }, +- { 2, "1B" }, +- { 3, "1C" }, +- { 4, "1D" }, +- { 5, "2" }, +- { 6, "2A" }, +- { 7, "2B" }, +- { 8, "2C" }, +- { 9, "2D" }, +- { 0, NULL } +-}; +- +-static const value_string pa_vals[] = { +- { 0, "-6dB" }, +- { 1, "-4.77dB" }, +- { 2, "-3dB" }, +- { 3, "-1.77dB" }, +- { 4, "0dB" }, +- { 5, "1dB" }, +- { 6, "2dB" }, +- { 7, "3dB" }, +- { 0, NULL } +-}; +- +-static const value_string transmission_mode_vals[] = { +- { 1, "Mode 1" }, +- { 2, "Mode 2" }, +- { 3, "Mode 3" }, +- { 4, "Mode 4" }, +- { 5, "Mode 5" }, +- { 6, "Mode 6" }, +- { 7, "Mode 7" }, +- { 8, "Mode 8" }, +- { 9, "Mode 9" }, +- { 10, "Mode 10" }, +- { 0, NULL } +-}; +- +-static const value_string nfapi_ul_config_pdu_type_vals[] = { +- { 0, "ULSCH" }, +- { 1, "ULSCH_CQI_RI" }, +- { 2, "ULSCH_HARQ" }, +- { 3, "ULSCH_CQI_HARQ_RI" }, +- { 4, "UCI_CQI" }, +- { 5, "UCI_SR" }, +- { 6, "UCI_HARQ" }, +- { 7, "UCI_SR_HARQ" }, +- { 8, "UCI_CQI_HARQ" }, +- { 9, "UCI_CQI_SR" }, +- { 10, "UCI_CQI_SR_HARQ" }, +- { 11, "SRS" }, +- { 12, "HARQ_BUFFER" }, +- { 13, "ULSCH_UCI_CSI" }, +- { 14, "ULSCH_UCI_HARQ" }, +- { 15, "ULSCH_CSI_UCI_HARQ" }, +- { 0, NULL } +-}; +- +-typedef enum { +- NFAPI_ACK_NACK_MODE_BUNDLING = 0, +- NFAPI_ACK_NACK_MODE_MULTIPLEXING, +- NFAPI_ACK_NACK_MODE_FORMAT_1B_WITH_CHAN_SEL, +- NFAPI_ACK_NACK_MODE_FORMAT_3, +-} nfapi_ack_nack_mode_e; +- +-static const value_string nfapi_ack_nack_mode_vals[] = { +- { NFAPI_ACK_NACK_MODE_BUNDLING, "Bundling" }, +- { NFAPI_ACK_NACK_MODE_MULTIPLEXING, "Multiplexing" }, +- { NFAPI_ACK_NACK_MODE_FORMAT_1B_WITH_CHAN_SEL, "Format 1b with channel selection" }, +- { NFAPI_ACK_NACK_MODE_FORMAT_3, "Format 3" }, +- { 0, NULL } +-}; +- +-typedef enum { +- NFAPI_ANTENNA_PORT1 = 0, +- NFAPI_ANTENNA_PORT2, +- NFAPI_ANTENNA_PORT4, +-} nfapi_ack_nack_mode_e; +- +-static const value_string nfapi_antenna_port_vals[] = { +- { NFAPI_ANTENNA_PORT1, "1 " }, +- { NFAPI_ANTENNA_PORT2, "2 " }, +- { NFAPI_ANTENNA_PORT4, "4 " }, +- { 0, NULL } +-}; +- +-typedef enum{ +- PHICH_R_ONE_SIXTH = 0, +- PHICH_R_HALF, +- PHICH_R_ONE, +- PHICH_R_TWO +-} nfapi_phich_resource_e; +- +-static const value_string nfapi_phich_resource_vals[] = { +- { PHICH_R_ONE_SIXTH, "PHICH_R_ONE_SIXTH " }, +- { PHICH_R_HALF, "PHICH_R_HALF" }, +- { PHICH_R_ONE, "PHICH_R_ONE" }, +- { PHICH_R_TWO, "PHICH_R_TWO" }, +- { 0, NULL } +-}; +- +-static const value_string local_distributed_vals[] = { +- { 0, "localized" }, +- { 1, "distributed" }, +- { 0, NULL } +-}; +- +-static const value_string transport_block_to_codeword_swap_flag_vals[] = { +- { 0, "no swapping" }, +- { 1, "swapped" }, +- { 0, NULL } +-}; +- +-static const value_string ngap_vals[] = { +- { 0, "Ngap1" }, +- { 1, "Ngap2" }, +- { 0, NULL } +-}; +- +-static const value_string true_false_vals[] = { +- { 0, "false" }, +- { 1, "true" }, +- { 0, NULL } +-}; +- +-static const value_string exhustive_search_vals[] = { +- { 0, "non-exhaustive search" }, +- { 1, "exhaustive search" }, +- { 0, NULL } +-}; +- +-static const value_string not_used_enabled_vals[] = { +- { 0, "not used" }, +- { 1, "enabled" }, +- { 0, NULL } +-}; +- +-static const value_string hopping_vals[] = { +- { 0, "no hopping" }, +- { 1, "hopping enabled" }, +- { 0, NULL } +-}; +- +- +-static const value_string rnti_type_vals[] = { +- { 1, "C-RNTI" }, +- { 2, "RA-RNTI, P-RNTI, SI-RNTI, SC-RNTI, G-RNTI" }, +- { 3, "SPS-CRNTI" }, +- { 0, NULL } +-}; +- +-static const value_string primary_cells_type_vals[] = { +- { 1, "TDD" }, +- { 2, "FDD" }, +- { 3, "HD_FDD" }, +- { 0, NULL } +-}; +- +-static const value_string ul_rssi_supported_vals[] = { +- { 0, "Uplink RSSI not supported" }, +- { 1, "Uplink RSSI supported" }, +- { 0, NULL} +-}; +- +- +-typedef enum +-{ +- NMM_NONE = 0, +- NMM_ONLY, +- NMM_IN_CONFIGURED_STATE, +- NMM_IN_RUNNING_STATE, +- NMM_IN_CONFIGURED_AND_RUNNING_STATE +-} nmm_modes_supported_e; +- +-static const value_string nmm_modes_supported_vals[] = +-{ +- { NMM_NONE, "NONE" }, +- { NMM_ONLY, "NMM_ONLY" }, +- { NMM_IN_CONFIGURED_STATE, "NMM_IN_CONFIGURED_STATE" }, +- { NMM_IN_RUNNING_STATE, "NMM_IN_RUNNING_STATE" }, +- { NMM_IN_CONFIGURED_AND_RUNNING_STATE, "NMM_IN_CONFIGURED_AND_RUNNING_STAT" }, +- { 0, NULL } +-}; +- +- +- +- +- +-static int proto_nfapi = -1; +- +-/* These are for the subtrees */ +-static gint ett_nfapi_message_tree = -1; +-static gint ett_nfapi_p4_p5_message_header = -1; +-static gint ett_nfapi_p7_message_header = -1; +-static gint ett_nfapi_tlv_tree = -1; +-static gint ett_nfapi_tl = -1; +-static gint ett_nfapi_pnf_param_response = -1; +-static gint ett_nfapi_pnf_phy = -1; +-static gint ett_nfapi_pnf_phy_rel10 = -1; +-static gint ett_nfapi_pnf_phy_rel11 = -1; +-static gint ett_nfapi_pnf_phy_rel12 = -1; +-static gint ett_nfapi_pnf_phy_rel13 = -1; +-static gint ett_nfapi_pnf_rf = -1; +-static gint ett_nfapi_phy_rf_config_info = -1; +-static gint ett_nfapi_pnf_phy_rf_config = -1; +-static gint ett_nfapi_pnf_phy_rf_config_instance = -1; +-static gint ett_nfapi_phy_state = -1; +-static gint ett_nfapi_l1_status = -1; +-static gint ett_nfapi_rf_bands = -1; +-static gint ett_nfapi_tx_antenna_ports = -1; +-static gint ett_nfapi_harq_ack_nack_data = -1; +-static gint ett_nfapi_harq_data = -1; +-static gint ett_nfapi_cc = -1; +-static gint ett_nfapi_rbs = -1; +-static gint ett_nfapi_antennas = -1; +-static gint ett_nfapi_dl_config_dci_dl_pdu_rel8 = -1; +-static gint ett_nfapi_dl_config_dci_dl_pdu_rel9 = -1; +-static gint ett_nfapi_dl_config_dci_dl_pdu_rel10 = -1; +-static gint ett_nfapi_dl_config_dci_dl_pdu = -1; +-static gint ett_nfapi_dl_config_request_pdu = -1; +-static gint ett_nfapi_dl_config_request_body = -1; +-static gint ett_nfapi_dl_config_request_pdu_list = -1; +-static gint ett_nfapi_ul_config_request_pdu_list = -1; +-static gint ett_nfapi_hi_dci0_request_pdu_list = -1; +-static gint ett_nfapi_tx_request_pdu_list = -1; +-static gint ett_nfapi_rx_indication_pdu_list = -1; +-static gint ett_nfapi_harq_indication_pdu_list = -1; +-static gint ett_nfapi_crc_indication_pdu_list = -1; +-static gint ett_nfapi_sr_indication_pdu_list = -1; +-static gint ett_nfapi_cqi_indication_pdu_list = -1; +-static gint ett_nfapi_preamble_indication_pdu_list = -1; +-static gint ett_nfapi_srs_indication_pdu_list = -1; +-static gint ett_nfapi_lbt_dl_config_pdu_list = -1; +-static gint ett_nfapi_lbt_dl_indication_pdu_list = -1; +-static gint ett_nfapi_dl_node_sync = -1; +-static gint ett_nfapi_ul_node_sync = -1; +-static gint ett_nfapi_timing_info = -1; +-static gint ett_nfapi_dl_config_request_dlsch_pdu_rel8 = -1; +-static gint ett_nfapi_subbands = -1; +-static gint ett_nfapi_dl_config_request_dlsch_pdu_rel9 = -1; +-static gint ett_nfapi_dl_config_request_dlsch_pdu_rel10 = -1; +-static gint ett_nfapi_dl_config_bch_pdu_rel8 = -1; +-static gint ett_nfapi_dl_config_mch_pdu_rel8 = -1; +-static gint ett_nfapi_dl_config_pch_pdu_rel8 = -1; +-static gint ett_nfapi_dl_config_prs_pdu_rel9 = -1; +-static gint ett_nfapi_dl_config_csi_rs_pdu_rel10 = -1; +-static gint ett_nfapi_ul_config_request_body = -1; +-static gint ett_nfapi_ul_config_harq_buffer_pdu = -1; +-static gint ett_nfapi_ul_config_ue_information_rel8 = -1; +-static gint ett_nfapi_ul_config_sr_information_pdu_rel8 = -1; +-static gint ett_nfapi_ul_config_ulsch_pdu_rel8 = -1; +-static gint ett_nfapi_ul_config_ulsch_pdu_rel10 = -1; +-static gint ett_nfapi_ul_config_cqi_ri_information_rel8 = -1; +-static gint ett_nfapi_ul_config_cqi_ri_information_rel9 = -1; +-static gint ett_nfapi_ul_config_ulsch_harq_information_rel10 = -1; +-static gint ett_nfapi_ul_config_initial_transmission_parameters_rel8 = -1; +-static gint ett_nfapi_ul_config_cqi_information_rel8 = -1; +-static gint ett_nfapi_ul_config_cqi_information_rel10 = -1; +-static gint ett_nfapi_ul_config_sr_information_rel8 = -1; +-static gint ett_nfapi_ul_config_sr_information_rel10 = -1; +-static gint ett_nfapi_ul_config_harq_information_rel10_tdd = -1; +-static gint ett_nfapi_ul_config_harq_information_rel8_fdd = -1; +-static gint ett_nfapi_ul_config_harq_information_rel9_fdd = -1; +-static gint ett_nfapi_ul_config_srs_pdu_rel8 = -1; +-static gint ett_nfapi_ul_config_srs_pdu_rel10 = -1; +-static gint ett_nfapi_crc_indication_body = -1; +-static gint ett_nfapi_bf_vector_antennas = -1; +-static gint ett_nfapi_bf_vectors = -1; +-static gint ett_nfapi_csi_rs_resource_configs = -1; +-static gint ett_nfapi_csi_rs_bf_vector = -1; +-static gint ett_nfapi_epdcch_prbs = -1; +-static gint ett_nfapi_precoding = -1; +-static gint ett_nfapi_earfcn_list = -1; +-static gint ett_nfapi_uarfcn_list = -1; +-static gint ett_nfapi_arfcn_list = -1; +-static gint ett_nfapi_rssi_list = -1; +-static gint ett_nfapi_pci_list = -1; +-static gint ett_nfapi_psc_list = -1; +-static gint ett_nfapi_lte_cells_found_list = -1; +-static gint ett_nfapi_utran_cells_found_list = -1; +-static gint ett_nfapi_geran_cells_found_list = -1; +-static gint ett_nfapi_si_periodicity_list = -1; +- +-static expert_field ei_invalid_range = EI_INIT; +-static expert_field ei_power_invalid = EI_INIT; +-static expert_field ei_ref_sig_power_invalid = EI_INIT; +- +- +-static int hf_nfapi_message_tree = -1; +- +-static int hf_nfapi_p4_p5_message_header = -1; +-static int hf_nfapi_p4_p5_message_header_phy_id = -1; +-static int hf_nfapi_p4_p5_message_header_message_id = -1; +-static int hf_nfapi_p4_p5_message_header_message_length = -1; +-static int hf_nfapi_p4_p5_message_header_spare = -1; +- +-static int hf_nfapi_p7_message_header = -1; +-static int hf_nfapi_p7_message_header_phy_id = -1; +-static int hf_nfapi_p7_message_header_message_id = -1; +-static int hf_nfapi_p7_message_header_message_length = -1; +-static int hf_nfapi_p7_message_header_m = -1; +-static int hf_nfapi_p7_message_header_segment = -1; +-static int hf_nfapi_p7_message_header_sequence_number = -1; +-static int hf_nfapi_p7_message_header_checksum = -1; +-static int hf_nfapi_p7_message_header_transmit_timestamp = -1; +- +-static int hf_nfapi_tlv_tree = -1; +- +-static int hf_nfapi_tl = -1; +-static int hf_nfapi_tl_tag = -1; +-static int hf_nfapi_tl_length = -1; +-static int hf_nfapi_tag_uint8_value = -1; +-static int hf_nfapi_tag_uint16_value = -1; +- +-static int hf_nfapi_pnf_param_general = -1; +-static int hf_nfapi_sync_mode = -1; +-static int hf_nfapi_location_mode = -1; +-static int hf_nfapi_location_coordinates = -1; +-static int hf_nfapi_location_coordinates_length = -1; +-static int hf_nfapi_dl_config_timing = -1; +-static int hf_nfapi_tx_timing = -1; +-static int hf_nfapi_ul_config_timing = -1; +-static int hf_nfapi_hi_dci0_timing = -1; +-static int hf_nfapi_maximum_number_phys = -1; +-static int hf_nfapi_maximum_total_bandwidth = -1; +-static int hf_nfapi_maximum_total_number_dl_layers = -1; +-static int hf_nfapi_maximum_total_number_ul_layers = -1; +-static int hf_nfapi_shared_bands = -1; +-static int hf_nfapi_shared_pa = -1; +-static int hf_nfapi_maximum_total_power = -1; +-static int hf_nfapi_oui= -1; +- +-static int hf_nfapi_pdu = -1; +- +-static int hf_nfapi_pnf_phy = -1; +-static int hf_nfapi_pnf_phy_nfapi_tl = -1; /* structure hf_nfapi_tl*/ +-static int hf_nfapi_pnf_phy_number_phy = -1; +-static int hf_nfapi_pnf_phy_config_index = -1; +-static int hf_nfapi_number_of_rf_exclusions = -1; +-static int hf_nfapi_dl_bandwidth_support = -1; +-static int hf_nfapi_ul_bandwidth_support = -1; +-static int hf_nfapi_downlink_channel_bandwidth_supported = -1; +-static int hf_nfapi_uplink_channel_bandwidth_supported = -1; +-static int hf_nfapi_number_of_dl_layers_supported = -1; +-static int hf_nfapi_number_of_ul_layers_supported = -1; +-static int hf_nfapi_maximum_3gpp_release_supported = -1; +-static int hf_nfapi_nmm_modes_supported = -1; +- +- +-static int hf_nfapi_pnf_rf = -1; +-static int hf_nfapi_pnf_rf_nfapi_tl = -1; +-static int hf_nfapi_number_of_rfs = -1; +-static int hf_nfapi_rf_config_index = -1; +-static int hf_nfapi_band = -1; +-static int hf_nfapi_maximum_transmit_power = -1; +-static int hf_nfapi_earfcn = -1; +-static int hf_nfapi_minimum_transmit_power = -1; +-static int hf_nfapi_number_of_antennas_suppported = -1; +-static int hf_nfapi_minimum_downlink_frequency = -1; +-static int hf_nfapi_maximum_downlink_frequency = -1; +-static int hf_nfapi_minimum_uplink_frequency = -1; +-static int hf_nfapi_maximum_uplink_frequency = -1; +- +-static int hf_nfapi_number_of_rf_bands = -1; +-static int hf_nfapi_nmm_uplink_rssi_supported = -1; +- +-static int hf_nfapi_phy_rf_config_info = -1; +-static int hf_nfapi_phy_rf_config_info_phy_id = -1; +-static int hf_nfapi_phy_rf_config_info_band = -1; +- +-static int hf_nfapi_pnf_phy_rf_config = -1; +-static int hf_nfapi_pnf_phy_rf_config_number_phy_rf_config_info = -1; +-static int hf_nfapi_pnf_phy_rf_config_array_phy_rf_config_info = -1; +- +-static int hf_nfapi_pnf_phy_rel10 = -1; +-static int hf_nfapi_transmission_mode7_supported = -1; +-static int hi_nfapi_transmission_mode8_supported = -1; +-static int hi_nfapi_two_antennas_ports_for_pucch = -1; +-static int hi_nfapi_transmission_mode_9_supported = -1; +-static int hi_nfapi_simultaneous_pucch_pusch = -1; +-static int hi_nfapi_for_layer_tx_with_tm3_and_tm4 = -1; +- +-static int hf_nfapi_pnf_phy_rel11 = -1; +-static int hf_nfapi_epdcch_supported = -1; +-static int hi_nfapi_multi_ack_csi_reporting = -1; +-static int hi_nfapi_pucch_tx_diversity_with_channel_selection = -1; +-static int hi_nfapi_ul_comp_supported = -1; +-static int hi_nfapi_transmission_mode_5_supported = -1; +- +-static int hf_nfapi_pnf_phy_rel12 = -1; +-static int hf_nfapi_csi_subframe_set = -1; +-static int hi_nfapi_enhanced_4tx_codebook = -1; +-static int hi_nfapi_drs_supported = -1; +-static int hi_nfapi_ul_64qam_supported = -1; +-static int hi_nfapi_transmission_mode_10_supported = -1; +-static int hi_nfapi_alternative_tbs_indices = -1; +- +-static int hf_nfapi_pnf_phy_rel13 = -1; +-static int hf_nfapi_pucch_format_4_supported = -1; +-static int hf_nfapi_pucch_format_5_supported = -1; +-static int hf_nfapi_more_than_5_ca_supported = -1; +-static int hf_nfapi_laa_supported = -1; +-static int hf_nfapi_laa_ending_in_dwpts_supported = -1; +-static int hf_nfapi_laa_starting_in_second_slot_supported = -1; +-static int hf_nfapi_beamforming_supported = -1; +-static int hf_nfapi_csi_rs_enhancements_supported = -1; +-static int hf_nfapi_drms_enhancements_supported = -1; +-static int hf_nfapi_srs_enhancements_supported = -1; +- +- +-// P5 Message Structures +-static int hf_nfapi_pnf_param_response_pnf_param_general = -1; +-static int hf_nfapi_pnf_param_response_pnf_phy = -1; +-static int hf_nfapi_pnf_param_response_pnf_rf = -1; +- +-static int hf_nfapi_pnf_param_request = -1; +-static int hf_nfapi_pnf_param_response = -1; +-static int hf_nfapi_pnf_config_request = -1; +-static int hf_nfapi_pnf_config_response = -1; +-static int hf_nfapi_pnf_start_request = -1; +-static int hf_nfapi_pnf_start_response = -1; +-static int hf_nfapi_pnf_stop_request = -1; +-static int hf_nfapi_pnf_stop_response = -1; +-static int hf_nfapi_param_response = -1; +-static int hf_nfapi_start_request = -1; +-static int hf_nfapi_start_response = -1; +-static int hf_nfapi_stop_request = -1; +-static int hf_nfapi_stop_response = -1; +- +-static int hf_nfapi_uint8_tag = -1; +-static int hf_nfapi_uint16_tag = -1; +- +-static int hf_nfapi_error_code = -1; +-static int hf_nfapi_p4_error_code = -1; +-static int hf_nfapi_rat_type = -1; +-static int hf_nfapi_num_tlv = -1; +-static int hf_nfapi_phy_state = -1; +-// static int hf_nfapi_bandwidth_support = -1; +- +-static int hf_nfapi_modulation_support = -1; +-static int hf_nfapi_phy_antenna_capability = -1; +-static int hf_nfapi_release_capability = -1; +-static int hf_nfapi_mbsfn_capability = -1; +- +-static int hf_nfapi_laa_capability = -1; +-static int hf_nfapi_pd_sensing_lbt_support = -1; +-static int hf_nfapi_multi_carrier_lbt_support = -1; +-static int hf_nfapi_partial_sf_support = -1; +- +-/* nfapi nfapi */ +-static int hf_nfapi_pnf_address = -1; +-static int hf_nfapi_pnf_address_ipv4 = -1; +-static int hf_nfapi_pnf_address_ipv6 = -1; +- +-static int hf_nfapi_vnf_address = -1; +-static int hf_nfapi_vnf_address_ipv4 = -1; +-static int hf_nfapi_vnf_address_ipv6 = -1; +- +-static int hf_nfapi_pnf_port = -1; +-static int hf_nfapi_vnf_port = -1; +-static int hf_nfapi_dl_ue_per_sf = -1; +-static int hf_nfapi_ul_ue_per_sf = -1; +- +-static int hf_nfapi_rf_bands = -1; +-static int hf_nfapi_rf_bands_nfapi_tl = -1; +-static int hf_nfapi_rf_bands_count = -1; +-static int hf_nfapi_rf_bands_value = -1; +- +-static int hf_nfapi_timing_window = -1; +-static int hf_nfapi_timing_info_mode = -1; +-static int hf_nfapi_timing_info_period = -1; +-static int hf_nfapi_max_transmit_power = -1; +- +-/* subframe config */ +-static int hf_nfapi_duplex_mode = -1; +-static int hf_nfapi_pcfich_power_offset = -1; +-static int hf_nfapi_pb = -1; +-static int hf_nfapi_dl_cyclic_prefix_type = -1; +-static int hf_nfapi_ul_cyclic_prefix_type = -1; +- +-static int hf_nfapi_tx_antenna_ports = -1; +-static int hf_nfapi_rx_antenna_ports = -1; +- +- +- +-/* RF Config */ +-static int hf_nfapi_downlink_channel_bandwidth = -1; +-static int hf_nfapi_uplink_channel_bandwidth = -1; +-static int hf_nfapi_reference_signal_power = -1; +- +-/* PHICH config*/ +-static int hf_nfapi_phich_resource = -1; +-static int hf_nfapi_phich_duration = -1; +-static int hf_nfapi_phich_power_offset = -1; +- +-static int hf_nfapi_value_float = -1; +- +-/* SCH Config */ +-static int hf_nfapi_primary_synchronization_signal_epre_eprers = -1; +-static int hf_nfapi_secondary_synchronization_signal_epre_eprers = -1; +-static int hf_nfapi_physical_cell_id = -1; +- +-/* PRACH config */ +-static int hf_nfapi_configuration_index = -1; +-static int hf_nfapi_root_sequence_index = -1; +-static int hf_nfapi_zero_correlation_zone_configuration = -1; +-static int hf_nfapi_high_speed_flag = -1; +-static int hf_nfapi_frequency_offset = -1; +- +-/* PUSCH config */ +-static int hf_nfapi_hopping_mode = -1; +-static int hf_nfapi_hopping_offset = -1; +- +-/* PUCCH config */ +-static int hf_nfapi_delta_pucch_shift = -1; +-static int hf_nfapi_n_cqi_rb = -1; +-static int hf_nfapi_n_an_cs = -1; +-static int hf_nfapi_n1_pucch_an = -1; +- +-/* SRS config */ +-static int hf_nfapi_bandwidth_configuration = -1; +-static int hf_nfapi_max_up_pts = -1; +-static int hf_nfapi_srs_subframe_configuration = -1; +-static int hf_nfapi_srs_acknack_srs_simultaneous_transmission = -1; +- +-/* uplink reference signal config */ +-static int hf_nfapi_uplink_rs_hopping = -1; +-static int hf_nfapi_group_assignment = -1; +-static int hf_nfapi_cyclic_shift_1_for_drms = -1; +- +-/* tdd frame structure */ +-static int hf_nfapi_subframe_assignment = -1; +-static int hf_nfapi_special_subframe_patterns = -1; +- +-/* laa config */ +-static int hf_nfapi_ed_threshold_for_lbt_for_pdsch = -1; +-static int hf_nfapi_ed_threshold_for_lbt_for_drs = -1; +-static int hf_nfapi_pd_threshold = -1; +-static int hf_nfapi_multi_carrier_type = -1; +-static int hf_nfapi_multi_carrier_tx = -1; +-static int hf_nfapi_multi_carrier_freeze = -1; +-static int hf_nfapi_tx_antenna_ports_for_drs = -1; +-static int hf_nfapi_transmission_power_for_drs = -1; +- +-/* eMTC config */ +-static int hf_nfapi_pbch_repetitions_enabled_r13 = -1; +-static int hf_nfapi_prach_cat_m_root_sequence_index = -1; +-static int hf_nfapi_prach_cat_m_zero_correlation_zone_configuration = -1; +-static int hf_nfapi_prach_cat_m_high_speed_flag = -1; +- +-static int hf_nfapi_prach_ce_level_0_enable = -1; +-static int hf_nfapi_prach_ce_level_0_configuration_index = -1; +-static int hf_nfapi_prach_ce_level_0_frequency_offset = -1; +-static int hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt = -1; +-static int hf_nfapi_prach_ce_level_0_starting_subframe_periodicity = -1; +-static int hf_nfapi_prach_ce_level_0_hopping_enabled = -1; +-static int hf_nfapi_prach_ce_level_0_hopping_offset = -1; +- +-static int hf_nfapi_prach_ce_level_1_enable = -1; +-static int hf_nfapi_prach_ce_level_1_configuration_index = -1; +-static int hf_nfapi_prach_ce_level_1_frequency_offset = -1; +-static int hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt = -1; +-static int hf_nfapi_prach_ce_level_1_starting_subframe_periodicity = -1; +-static int hf_nfapi_prach_ce_level_1_hopping_enabled = -1; +-static int hf_nfapi_prach_ce_level_1_hopping_offset = -1; +- +-static int hf_nfapi_prach_ce_level_2_enable = -1; +-static int hf_nfapi_prach_ce_level_2_configuration_index = -1; +-static int hf_nfapi_prach_ce_level_2_frequency_offset = -1; +-static int hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt = -1; +-static int hf_nfapi_prach_ce_level_2_starting_subframe_periodicity = -1; +-static int hf_nfapi_prach_ce_level_2_hopping_enabled = -1; +-static int hf_nfapi_prach_ce_level_2_hopping_offset = -1; +- +-static int hf_nfapi_prach_ce_level_3_enable = -1; +-static int hf_nfapi_prach_ce_level_3_configuration_index = -1; +-static int hf_nfapi_prach_ce_level_3_frequency_offset = -1; +-static int hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt = -1; +-static int hf_nfapi_prach_ce_level_3_starting_subframe_periodicity = -1; +-static int hf_nfapi_prach_ce_level_3_hopping_enabled = -1; +-static int hf_nfapi_prach_ce_level_3_hopping_offset = -1; +-static int hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b = -1; +-static int hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a = -1; +- +-static int hf_nfapi_dl_modulation_support = -1; +-static int hf_nfapi_ul_modulation_support = -1; +- +-/* 123 config */ +-static int hf_nfapi_data_report_mode = -1; +-static int hf_nfapi_sfnsf = -1; +- +-// P7 Sub Structures +-static int hf_nfapi_dl_config_dci_dl_pdu_rel8 = -1; +-static int hf_nfapi_dci_format = -1; +-static int hf_nfapi_cce_idx = -1; +-static int hf_nfapi_aggregation_level = -1; +-static int hf_nfapi_mcs_1 = -1; +-static int hf_nfapi_redundancy_version_1 = -1; +-static int hf_nfapi_new_data_indicator_1 = -1; +-static int hf_nfapi_mcs_2 = -1; +-static int hf_nfapi_redundancy_version_2 = -1; +-static int hf_nfapi_new_data_indicator_2 = -1; +-static int hf_nfapi_harq_process = -1; +-static int hf_nfapi_tpmi = -1; +-static int hf_nfapi_pmi = -1; +-static int hf_nfapi_precoding_information = -1; +-static int hf_nfapi_tpc = -1; +-static int hf_nfapi_downlink_assignment_index = -1; +-static int hf_nfapi_transport_block_size_index = -1; +-static int hf_nfapi_downlink_power_offset = -1; +-static int hf_nfapi_allocate_prach_flag = -1; +-static int hf_nfapi_preamble_index = -1; +-static int hf_nfapi_prach_mask_index = -1; +-static int hf_nfapi_rnti_type = -1; +- +-static int hf_nfapi_dl_config_dci_dl_pdu_rel9 = -1; +-static int hf_nfapi_mcch_flag = -1; +-static int hf_nfapi_mcch_change_notification = -1; +-static int hf_nfapi_scrambling_identity = -1; +- +-static int hf_nfapi_dl_config_dci_dl_pdu_rel10 = -1; +-static int hf_nfapi_cross_carrier_scheduling_flag = -1; +-static int hf_nfapi_carrier_indicator = -1; +-static int hf_nfapi_srs_flag = -1; +-static int hf_nfapi_srs_request = -1; +-static int hf_nfapi_antenna_ports_scrambling_and_layers = -1; +-static int hf_nfapi_total_dci_length_including_padding = -1; +-static int hf_nfapi_n_dl_rb = -1; +- +-static int hf_nfapi_dl_config_dci_dl_pdu_rel11 = -1; +-static int hf_nfapi_harq_ack_resource_offset = -1; +-static int hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator = -1; +-static int hf_nfapi_dl_config_dci_dl_pdu_rel12 = -1; +-static int hf_nfapi_primary_cell_type = -1; +-static int hf_nfapi_ul_dl_configuration_flag = -1; +-static int hf_nfapi_number_of_ul_dl_configurations = -1; +-static int hf_nfapi_ul_dl_configuration_index = -1; +-static int hf_nfapi_dl_config_dci_dl_pdu_rel13 = -1; +-static int hf_nfapi_laa_end_partial_sf_flag = -1; +-static int hf_nfapi_laa_end_partial_sf_configuration = -1; +-static int hf_nfapi_initial_lbt_sf = -1; +-static int hf_nfapi_codebooksize_determination_r13 = -1; +-static int hf_nfapi_rel13_drms_table_flag = -1; +- +- +-static int hf_nfapi_dl_config_dci_dl_pdu = -1; +-static int hf_nfapi_dl_config_dci_dl_pdu_nfapi_dl_config_dci_dl_pdu_rel8 = -1; +-static int hf_nfapi_dl_config_dci_dl_pdu_nfapi_dl_config_dci_dl_pdu_rel9 = -1; +-static int hf_nfapi_dl_config_dci_dl_pdu_nfapi_dl_config_dci_dl_pdu_rel10 = -1; +- +-static int hf_nfapi_bf_vector_antennas = -1; +-static int hf_nfapi_subbands = -1; +-static int hf_nfapi_bf_vectors = -1; +-static int hf_nfapi_csi_rs_resource_config = -1; +-static int hf_nfapi_csi_rs_number_if_nzp_configurations = -1; +-static int hf_nfapi_csi_rs_resource_configs = -1; +-static int hf_nfapi_pdsch_start = -1; +-static int hf_nfapi_drms_config_flag = -1; +-static int hf_nfapi_drms_scrambling = -1; +-static int hf_nfapi_csi_config_flag = -1; +-static int hf_nfapi_csi_scrambling = -1; +-static int hf_nfapi_pdsch_re_mapping_flag = -1; +-static int hf_nfapi_pdsch_re_mapping_antenna_ports = -1; +-static int hf_nfapi_pdsch_re_mapping_freq_shift = -1; +-static int hf_nfapi_alt_cqi_table_r12 = -1; +-static int hf_nfapi_max_layers = -1; +-static int hf_nfapi_n_dl_harq = -1; +-static int hf_nfapi_dwpts_symbols = -1; +-static int hf_nfapi_ue_type = -1; +-static int hf_nfapi_pdsch_payload_type = -1; +-static int hf_nfapi_initial_transmission_sf = -1; +-static int hf_nfapi_req13_drms_table_flag = -1; +-static int hf_nfapi_prnti = -1; +-static int hf_nfapi_mcs = -1; +-static int hf_nfapi_number_of_transport_blocks = -1; +-static int hf_nfapi_ue_mode = -1; +-static int hf_prs_bandwidth = -1; +-static int hf_prs_cyclic_prefix_type = -1; +-static int hf_prs_muting = -1; +-static int hf_nfapi_csi_rs_number_of_nzp_configuration = -1; +-static int hf_nfapi_csi_rs_resource_index = -1; +-static int hf_nfapi_csi_rs_class = -1; +-static int hf_nfapi_cdm_type = -1; +-static int hf_nfapi_csi_rs_bf_vector = -1; +-static int hf_nfapi_edpcch_prb_index = -1; +-static int hf_nfapi_epdcch_resource_assignment_flag = -1; +-static int hf_nfapi_epdcch_id = -1; +-static int hf_nfapi_epdcch_start_symbol = -1; +-static int hf_nfapi_epdcch_num_prb = -1; +-static int hf_nfapi_epdcch_prbs = -1; +-static int hf_nfapi_precoding_value = -1; +-static int hf_nfapi_mpdcch_narrowband = -1; +-static int hf_nfapi_number_of_prb_pairs = -1; +-static int hf_nfapi_resource_block_assignment = -1; +-static int hf_nfapi_start_symbol = -1; +-static int hf_nfapi_ecce_index = -1; +-static int hf_nfapi_ce_mode = -1; +-static int hf_nfapi_drms_scrabmling_init = -1; +-static int hf_nfapi_pdsch_reception_levels = -1; +-static int hf_nfapi_new_data_indicator = -1; +-static int hf_nfapi_tpmi_length = -1; +-static int hf_nfapi_pmi_flag = -1; +-static int hf_nfapi_harq_resource_offset = -1; +-static int hf_nfapi_dci_subframe_repetition_number = -1; +-static int hf_nfapi_downlink_assignment_index_length = -1; +-static int hf_nfapi_starting_ce_level = -1; +-static int hf_nfapi_antenna_ports_and_scrambling_identity_flag = -1; +-static int hf_nfapi_antenna_ports_and_scrambling_identity = -1; +-static int hf_nfapi_paging_direct_indication_differentiation_flag = -1; +-static int hf_nfapi_direct_indication = -1; +-static int hf_nfapi_number_of_tx_antenna_ports = -1; +-static int hf_nfapi_precoding = -1; +- +- +- +-// P7 Message Structures +-static int hf_nfapi_dl_node_sync = -1; +-static int hf_nfapi_dl_node_sync_nfapi_p7_message_header = -1; +-static int hf_nfapi_dl_node_sync_t1 = -1; +-static int hf_nfapi_dl_node_sync_delta_sfn_sf = -1; +- +-static int hf_nfapi_ul_node_sync = -1; +-static int hf_nfapi_ul_node_sync_nfapi_p7_message_header = -1; +-static int hf_nfapi_ul_node_sync_t1 = -1; +-static int hf_nfapi_ul_node_sync_t2 = -1; +-static int hf_nfapi_ul_node_sync_t3 = -1; +- +-static int hf_nfapi_timing_info = -1; +-static int hf_nfapi_timing_info_nfapi_p7_message_header = -1; +-static int hf_nfapi_timing_info_last_sfn_sf = -1; +-static int hf_nfapi_timing_info_time_since_last_timing_info = -1; +-static int hf_nfapi_timing_info_dl_config_jitter = -1; +-static int hf_nfapi_timing_info_tx_request_jitter = -1; +-static int hf_nfapi_timing_info_ul_config_jitter = -1; +-static int hf_nfapi_timing_info_hi_dci0_jitter = -1; +-static int hf_nfapi_timing_info_dl_config_latest_delay = -1; +-static int hf_nfapi_timing_info_tx_request_latest_delay = -1; +-static int hf_nfapi_timing_info_ul_config_latest_delay = -1; +-static int hf_nfapi_timing_info_hi_dci0_latest_delay = -1; +-static int hf_nfapi_timing_info_dl_config_earliest_arrival = -1; +-static int hf_nfapi_timing_info_tx_request_earliest_arrival = -1; +-static int hf_nfapi_timing_info_ul_config_earliest_arrival = -1; +-static int hf_nfapi_timing_info_hi_dci0_earliest_arrival = -1; +- +-static int hf_nfapi_dl_config_request = -1; +-static int hf_nfapi_sfn_sf = -1; +- +-static int hf_nfapi_dl_config_request_body = -1; +-static int hf_nfapi_number_pdcch_ofdm_symbols = -1; +-static int hf_nfapi_number_dci = -1; +-static int hf_nfapi_number_pdus = -1; +-static int hf_nfapi_number_pdsch_rnti = -1; +-static int hf_nfapi_transmission_power_pcfich = -1; +- +-static int hf_nfapi_number_of_harqs = -1; +-static int hf_nfapi_number_of_crcs = -1; +-static int hf_nfapi_number_of_srs = -1; +-static int hf_nfapi_number_of_cqi = -1; +-static int hf_nfapi_number_of_preambles = -1; +-static int hf_nfapi_number_of_srss = -1; +-static int hf_nfapi_lbt_dl_req_pdu_type = -1; +-static int hf_nfapi_lbt_dl_ind_pdu_type = -1; +- +-static int hf_nfapi_dl_config_request_pdu_list = -1; +-static int hf_nfapi_ul_config_request_pdu_list = -1; +-static int hf_nfapi_hi_dci0_request_pdu_list = -1; +-static int hf_nfapi_tx_request_pdu_list = -1; +-static int hf_nfapi_rx_indication_pdu_list = -1; +-static int hf_nfapi_harq_indication_pdu_list = -1; +-static int hf_nfapi_crc_indication_pdu_list = -1; +-static int hf_nfapi_sr_indication_pdu_list = -1; +-static int hf_nfapi_cqi_indication_pdu_list = -1; +-static int hf_nfapi_preamble_indication_pdu_list = -1; +-static int hf_nfapi_srs_indication_pdu_list = -1; +-static int hf_nfapi_lbt_dl_config_pdu_list = -1; +-static int hf_nfapi_lbt_dl_indication_pdu_list = -1; +- +- +-static int hf_nfapi_dl_config_pdu_type = -1; +-static int hf_nfapi_pdu_size = -1; +-static int hf_nfapi_instance_length = -1; +- +-static int hf_nfapi_dl_config_dlsch_pdu_rel8 = -1; +-static int hf_nfapi_length; +-static int hf_nfapi_pdu_index = -1; +-static int hf_nfapi_rnti = -1; +-static int hf_nfapi_resource_allocation_type = -1; +-static int hf_nfapi_virtual_resource_block_assignment_flag = -1; +-static int hf_nfapi_resource_block_coding = -1; +-static int hf_nfapi_modulation = -1; +-static int hf_nfapi_redundancy_version = -1; +-static int hf_nfapi_transport_blocks = -1; +-static int hf_nfapi_transport_block_to_codeword_swap_flag = -1; +-static int hf_nfapi_transmission_scheme = -1; +-static int hf_nfapi_ul_transmission_scheme = -1; +-static int hf_nfapi_number_of_layers = -1; +-static int hf_nfapi_number_of_subbands = -1; +-static int hf_nfapi_codebook_index = -1; +-static int hf_nfapi_ue_category_capacity = -1; +-static int hf_nfapi_pa = -1; +-static int hf_nfapi_delta_power_offset_index = -1; +-static int hf_nfapi_ngap = -1; +-static int hf_nfapi_nprb = -1; +-static int hf_nfapi_transmission_mode = -1; +-static int hf_nfapi_num_bf_prb_per_subband = -1; +- +-static int hf_nfapi_num_bf_vector = -1; +-static int hf_nfapi_bf_vector_subband_index = -1; +-static int hf_nfapi_bf_vector_num_antennas = -1; +-static int hf_nfapi_bf_vector_bf_value = -1; +- +-static int hf_nfapi_dl_config_dlsch_pdu_rel9 = -1; +-static int hf_nfapi_nscid = -1; +- +-static int hf_nfapi_dl_config_dlsch_pdu_rel10 = -1; +-static int hf_nfapi_csi_rs_flag = -1; +-static int hf_nfapi_csi_rs_resource_config_r10 = -1; +-static int hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10 = -1; +- +-static int hf_nfapi_dl_config_bch_pdu_rel8 = -1; +-static int hf_nfapi_transmission_power = -1; +- +-static int hf_nfapi_dl_config_mch_pdu_rel8 = -1; +-static int hf_nfapi_mbsfn_area_id = -1; +- +-static int hf_nfapi_dl_config_pch_pdu_rel8 = -1; +- +-static int hf_nfapi_dl_config_prs_pdu_rel9 = -1; +-static int hf_nfapi_prs_bandwidth = -1; +-static int hf_nfapi_prs_cyclic_prefix_type = -1; +- +-static int hf_nfapi_dl_config_csi_rs_pdu_rel10 = -1; +-static int hf_nfapi_csi_rs_antenna_port_count_r10 = -1; +- +-static int hf_nfapi_ul_config_request = -1; +-static int hf_nfapi_ul_config_request_body = -1; +-static int hf_nfapi_ul_config_pdu_type = -1; +- +-static int hf_nfapi_rach_prach_frequency_resources = -1; +-static int hf_nfapi_srs_present = -1; +-static int hf_nfapi_ul_config_harq_buffer_pdu = -1; +- +-static int hf_nfapi_ul_config_ue_information_rel8 = -1; +-static int hf_nfapi_handle = -1; +-static int hf_nfapi_ul_config_sr_information_pdu_rel8 = -1; +-static int hf_nfapi_pucch_index = -1; +-static int hf_nfapi_size = -1; +-static int hf_nfapi_resource_block_start = -1; +-static int hf_nfapi_number_of_resource_blocks = -1; +-static int hf_nfapi_cyclic_shift_2_for_drms = -1; +-static int hf_nfapi_frequency_hopping_enabled_flag = -1; +-static int hf_nfapi_frequency_hopping_bits = -1; +-static int hf_nfapi_new_data_indication = -1; +-static int hf_nfapi_harq_process_number = -1; +-static int hf_nfapi_ul_tx_mode = -1; +-static int hf_nfapi_current_tx_nb = -1; +-static int hf_nfapi_n_srs = -1; +-static int hf_nfapi_disable_sequence_hopping_flag = -1; +-static int hf_nfapi_dl_cqi_pmi_size_rank_1 = -1; +-static int hf_nfapi_dl_cqi_pmi_size_rank_greater_1 = -1; +-static int hf_nfapi_ri_size = -1; +-static int hf_nfapi_delta_offset_cqi = -1; +-static int hf_nfapi_delta_offset_ri = -1; +-static int hf_nfapi_harq_size = -1; +-static int hf_nfapi_delta_offset_harq = -1; +-static int hf_nfapi_ack_nack_mode = -1; +-static int hf_nfapi_n_srs_initial = -1; +-static int hf_nfapi_initial_number_of_resource_blocks = -1; +-static int hf_nfapi_dl_cqi_pmi_size = -1; +-static int hf_nfapi_report_type = -1; +-static int hf_nfapi_dl_cqi_ri_pmi_size = -1; +-static int hf_nfapi_control_type = -1; +-static int hf_nfapi_number_of_cc = -1; +-static int hf_nfapi_virtual_cell_id_enabled_flag = -1; +-static int hf_nfapi_npusch_identity = -1; +-static int hf_nfapi_ndrms_csh_identity = -1; +-static int hf_nfapi_total_number_of_repetitions = -1; +-static int hf_nfapi_repetition_number = -1; +-static int hf_nfapi_initial_sf_io = -1; +-static int hf_nfapi_empty_symbols_due_to_retunning = -1; +-static int hf_nfapi_dl_cqi_ri_pmi_size_2 = -1; +-static int hf_nfapi_npucch_identity = -1; +-static int hf_nfapi_harq_size_2 = -1; +-static int hf_nfapi_delta_offset_harq_2 = -1; +-static int hf_nfapi_empty_symbols = -1; +-static int hf_nfapi_total_number_of_repetitons = -1; +-static int hf_nfapi_csi_mode = -1; +-static int hf_nfapi_dl_cqi_pmi_size_2 = -1; +-static int hf_nfapi_statring_prb = -1; +-static int hf_nfapi_cdm_index = -1; +-static int hf_nfapi_nsrs = -1; +-static int hf_nfapi_num_ant_ports = -1; +-static int hf_nfapi_n_pucch_2_0 = -1; +-static int hf_nfapi_n_pucch_2_1 = -1; +-static int hf_nfapi_n_pucch_2_2 = -1; +-static int hf_nfapi_n_pucch_2_3 = -1; +-static int hf_nfapi_starting_prb = -1; +-static int hf_nfapi_antenna_port = -1; +-static int hf_nfapi_number_of_combs = -1; +- +- +- +-static int hf_nfapi_number_of_pucch_resource = -1; +-static int hf_nfapi_pucch_index_p1 = -1; +-static int hf_nfapi_n_pucch_1_0 = -1; +-static int hf_nfapi_n_pucch_1_1 = -1; +-static int hf_nfapi_n_pucch_1_2 = -1; +-static int hf_nfapi_n_pucch_1_3 = -1; +-static int hf_nfapi_srs_bandwidth = -1; +-static int hf_nfapi_frequency_domain_position = -1; +-static int hf_nfapi_srs_hopping_bandwidth = -1; +-static int hf_nfapi_transmission_comb = -1; +-static int hf_nfapi_i_srs = -1; +-static int hf_nfapi_sounding_reference_cyclic_shift = -1; +-static int hf_nfapi_antenna_ports = -1; +-static int hf_nfapi_ul_config_srs_pdu_rel10 = -1; +-static int hf_nfapi_ul_config_srs_pdu_rel8 = -1; +-static int hf_nfapi_ul_config_harq_information_rel9_fdd = -1; +-static int hf_nfapi_ul_config_harq_information_rel8_fdd = -1; +-static int hf_nfapi_ul_config_harq_information_rel10_tdd = -1; +-static int hf_nfapi_ul_config_sr_information_rel10 = -1; +-static int hf_nfapi_ul_config_sr_information_rel8 = -1; +-static int hf_nfapi_ul_config_cqi_information_rel10 = -1; +-static int hf_nfapi_ul_config_cqi_information_rel8 = -1; +-static int hf_nfapi_ul_config_initial_transmission_parameters_rel8 = -1; +-static int hf_nfapi_ul_config_ulsch_harq_information_rel10 = -1; +- +-/* Tx request */ +-static int hf_nfapi_pdu_length = -1; +-static int hf_nfapi_num_segments = -1; +-static int hf_nfapi_segment_length = -1; +-static int hf_nfapi_segment_data = -1; +- +-/* CRC Indication */ +-static int hf_nfapi_crc_indication_body = -1; +-static int hf_nfapi_crc_flag = -1; +- +-static int hf_nfapi_number_of_hi_pdus = -1; +-static int hf_nfapi_number_of_dci_pdus = -1; +-static int hf_nfapi_pdu_type = -1; +-static int hf_nfapi_hi_value = -1; +-static int hf_nfapi_i_phich = -1; +-static int hf_nfapi_flag_tb2 = -1; +-static int hf_nfapi_hi_value_2 = -1; +-static int hf_nfapi_ue_tx_antenna_selection = -1; +-static int hf_nfapi_cqi_csi_request = -1; +-static int hf_nfapi_ul_index = -1; +-static int hf_nfapi_dl_assignment_index = -1; +-static int hf_nfapi_tpc_bitmap = -1; +-static int hf_nfapi_new_data_indication_two = -1; +-static int hf_nfapi_size_of_cqi_csi_feild = -1; +-static int hf_nfapi_resource_allocation_flag = -1; +-static int hf_nfapi_number_of_antenna_ports =-1 ; +- +-static int hf_nfapi_n_ul_rb = -1; +-static int hf_nfapi_pscch_resource = -1; +-static int hf_nfapi_time_resource_pattern = -1; +-static int hf_nfapi_mpdcch_transmission_type = -1; +-static int hf_nfapi_drms_scrambling_init = -1; +-static int hf_nfapi_pusch_repetition_levels = -1; +-static int hf_nfapi_frequency_hopping_flag = -1; +-static int hf_nfapi_csi_request = -1; +-static int hf_nfapi_dai_presence_flag = -1; +-static int hf_nfapi_total_dci_length_include_padding = -1; +-static int hf_nfapi_data_offset = -1; +-static int hf_nfapi_ul_cqi = -1; +-static int hf_nfapi_timing_advance_r9 = -1; +-static int hf_nfapi_timing_advance = -1; +-static int hf_nfapi_harq_data_value_0 = -1; +-static int hf_nfapi_harq_data_value_1 = -1; +-static int hf_nfapi_harq_data_value_2 = -1; +-static int hf_nfapi_harq_data_value_3 = -1; +-static int hf_nfapi_harq_mode = -1; +-static int hf_nfapi_number_of_ack_nack = -1; +-static int hf_nfapi_harq_ack_nack_data = -1; +-static int hf_nfapi_harq_tb_1 = -1; +-static int hf_nfapi_harq_tb_2 = -1; +-static int hf_nfapi_harq_tb_n = -1; +-static int hf_nfapi_harq_data = -1; +-static int hf_nfapi_channel = -1; +-static int hf_nfapi_ri = -1; +-static int hf_nfapi_number_of_cc_reported = -1; +-static int hf_nfapi_cc = -1; +-static int hf_nfapi_preamble = -1; +-static int hf_nfapi_rach_resource_type = -1; +-static int hf_nfapi_snr = -1; +-static int hf_nfapi_doppler_estimation = -1; +-static int hf_nfapi_rb_start = -1; +-static int hf_nfapi_rbs = -1; +-static int hf_nfapi_up_pts_symbol = -1; +-static int hf_nfapi_number_prb_per_subband = -1; +-static int hf_nfapi_number_antennas = -1; +-static int hf_nfapi_subband_index = -1; +-static int hf_nfapi_antennas = -1; +-static int hf_nfapi_channel_coefficient = -1; +-static int hf_nfapi_ul_rtoa = -1; +-static int hf_nfapi_mp_cca = -1; +-static int hf_nfapi_n_cca = -1; +-static int hf_nfapi_offset = -1; +-static int hf_nfapi_lte_txop_sf = -1; +-static int hf_nfapi_txop_sfn_sf_end = -1; +-static int hf_nfapi_lbt_mode = -1; +-static int hf_nfapi_sfn_sf_end = -1; +-static int hf_nfapi_result = -1; +-static int hf_nfapi_txop_symbols = -1; +-static int hf_nfapi_initial_partial_sf = -1; +- +- +-static int hf_nfapi_frequency_band_indicator = -1; +-static int hf_nfapi_measurement_period = -1; +-static int hf_nfapi_bandwidth = -1; +-static int hf_nfapi_timeout = -1; +-static int hf_nfapi_number_of_earfcns = -1; +-static int hf_nfapi_earfcn_list = -1; +-static int hf_nfapi_uarfcn = -1; +-static int hf_nfapi_number_of_uarfcns = -1; +-static int hf_nfapi_uarfcn_list = -1; +-static int hf_nfapi_arfcn = -1; +-static int hf_nfapi_arfcn_direction = -1; +-static int hf_nfapi_number_of_arfcns = -1; +-static int hf_nfapi_arfcn_list = -1; +-static int hf_nfapi_rssi = -1; +-static int hf_nfapi_number_of_rssi = -1; +-static int hf_nfapi_rssi_list = -1; +-static int hf_nfapi_pci = -1; +-static int hf_nfapi_measurement_bandwidth = -1; +-static int hf_nfapi_exhaustive_search = -1; +-static int hf_nfapi_number_of_pci = -1; +-static int hf_nfapi_pci_list = -1; +-static int hf_nfapi_psc = -1; +-static int hf_nfapi_number_of_psc = -1; +-static int hf_nfapi_psc_list = -1; +-static int hf_nfapi_rsrp = -1; +-static int hf_nfapi_rsrq = -1; +-static int hf_nfapi_number_of_lte_cells_found = -1; +-static int hf_nfapi_lte_cells_found_list = -1; +-static int hf_nfapi_rscp = -1; +-static int hf_nfapi_enco = -1; +-static int hf_nfapi_number_of_utran_cells_found = -1; +-static int hf_nfapi_utran_cells_found_list = -1; +-static int hf_nfapi_bsic = -1; +-static int hf_nfapi_rxlev = -1; +-static int hf_nfapi_rxqual = -1; +-static int hf_nfapi_sfn_offset = -1; +-static int hf_nfapi_number_of_geran_cells_found = -1; +-static int hf_nfapi_geran_cells_found_list = -1; +-static int hf_nfapi_number_of_tx_antenna = -1; +-static int hf_nfapi_mib_length = -1; +-static int hf_nfapi_mib = -1; +-static int hf_nfapi_phich_configuration = -1; +-static int hf_nfapi_retry_count = -1; +-static int hf_nfapi_sib1 = -1; +-static int hf_nfapi_si_periodicity = -1; +-static int hf_nfapi_si_index = -1; +-static int hf_nfapi_number_of_si_periodicity = -1; +-static int hf_nfapi_si_periodicity_list = -1; +-static int hf_nfapi_si_window_length = -1; +-static int hf_nfapi_sib_type = -1; +-static int hf_nfapi_sib_len = -1; +-static int hf_nfapi_sib = -1; +-static int hf_nfapi_si_len = -1; +-static int hf_nfapi_si = -1; +- +-static int hf_nfapi_pnf_search_state = -1; +-static int hf_nfapi_pnf_broadcast_state = -1; +- +-static const value_string message_id_vals[] = { { 0x80, "DL_CONFIG.request"}, +- { 0x81, "UL_CONFIG.request"}, +- { 0x82, "SUBFRAME_INDICATION"}, +- { 0x83, "HI_DCI0.request"}, +- { 0x84, "TX.request"}, +- { 0x85, "HARQ.indication"}, +- { 0x86, "CRC.indication"}, +- { 0x87, "RX_ULSCH.indication"}, +- { 0x88, "RACH.indication" }, +- { 0x89, "SRS.indication" }, +- { 0x8A, "RX_SR.indication" }, +- { 0x8B, "RX_CQI.indication" }, +- { 0x8C, "LBT_DL_CONFIG.request" } , +- { 0x8D, "LBT_DL.indication" } , +- +- { 0x0100, "PNF_PARAM.request" }, +- { 0x0101, "PNF_PARAM.response" }, +- { 0x0102, "PNF_CONFIG.request" }, +- { 0x0103, "PNF_CONFIG.response" }, +- { 0x0104, "PNF_START.request" }, +- { 0x0105, "PNF_START.response" }, +- { 0x0106, "PNF_STOP.request" }, +- { 0x0107, "PNF_STOP.response" }, +- { 0x0108, "PARAM.request" }, +- { 0x0109, "PARAM.response" }, +- { 0x010A, "CONFIG.request" }, +- { 0x010B, "CONFIG.response" }, +- { 0x010C, "START.request" }, +- { 0x010D, "START.response" }, +- { 0x010E, "STOP.request" }, +- { 0x010F, "STOP.response" }, +- { 0x0110, "MEASUREMENT.request" }, +- { 0x0111, "MEASUREMENT.response" }, +- +- { 0x0180, "UL_NODE_SYNC" }, +- { 0x0181, "DL_NODE_SYNC" }, +- { 0x0182, "TIMING_INFO" }, +- +- { 0x0200, "RSSI.request" }, +- { 0x0201, "RSSI.response" }, +- { 0x0202, "RSSI.indication" }, +- { 0x0203, "CELL_SEARCH.request" }, +- { 0x0204, "CELL_SEARCH.response" }, +- { 0x0205, "CELL_SEARCH.indication" }, +- { 0x0206, "BROADCAST_DETECT.request" }, +- { 0x0207, "BROADCAST_DETECT.response" }, +- { 0x0208, "BROADCAST_DETECT.indication" }, +- { 0x0209, "SYSTEM_INFORMATION_SCHEDULE.request" }, +- { 0x020A, "SYSTEM_INFORMATION_SCHEDULE.response" }, +- { 0x020B, "SYSTEM_INFORMATION_SCHEDULE.indication" }, +- { 0x020C, "SYSTEM_INFORMATION.request" }, +- { 0x020D, "SYSTEM_INFORMATION.response" }, +- { 0x020E, "SYSTEM_INFORMATION.indication" }, +- { 0x020F, "NMM_STOP.request" }, +- { 0x0210, "NMM_STOP.response" }, +- +- { 0 , NULL }, +-}; +- +- +-typedef int(*tlv_decode)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end); +- +-typedef struct +-{ +- uint16_t tag_id; +- char* name; +- tlv_decode decode; +-} tlv_t; +- +-static int dissect_tlv_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint end); +- +- +- +- +-static guint8 proto_tree_add_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, char* units) +-{ +- guint8 value = tvb_get_guint8(tvb, *offset); +- proto_item * item = proto_tree_add_item(tree, hfindex, tvb, *offset, 1, ENC_NA); +- +- if (units != NULL) +- { +- proto_item_append_text(item, " "); +- proto_item_append_text(item, units); +- } +- +- *offset += 1; +- +- return value; +-} +- +-static guint8 proto_tree_add_uint8_with_range(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, packet_info *pinfo, guint8 min, guint8 max, char* units) +-{ +- guint8 value = tvb_get_guint8(tvb, *offset); +- proto_item * item = proto_tree_add_item(tree, hfindex, tvb, *offset, 1, ENC_NA); +- +- if (units != NULL) +- { +- proto_item_append_text(item, " "); +- proto_item_append_text(item, units); +- } +- +- *offset += 1; +- +- if (value < min || value > max) +- { +- expert_add_info(pinfo, tree, &ei_invalid_range); +- } +- +- +- return value; +-} +- +-static guint16 proto_tree_add_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, char* units) +-{ +- guint16 value = tvb_get_guint16(tvb, *offset, ENC_NA); +- proto_item * item = proto_tree_add_item(tree, hfindex, tvb, *offset, 2, ENC_NA); +- +- if (units != NULL) +- { +- proto_item_append_text(item, " "); +- proto_item_append_text(item, units); +- } +- +- *offset += 2; +- +- return value; +-} +- +-static void proto_tree_add_int16(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, char* units) +-{ +- proto_item * item = proto_tree_add_item(tree, hfindex, tvb, *offset, 2, ENC_NA); +- +- if (units != NULL) +- { +- proto_item_append_text(item, " "); +- proto_item_append_text(item, units); +- } +- +- *offset += 2; +-} +- +-typedef int(*uint8_value_conversion)(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint8 value); +- +-static guint8 proto_tree_add_uint8_with_conversion(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, uint8_value_conversion conversion) +-{ +- guint8 value = tvb_get_guint8(tvb, *offset); +- +- conversion(tree, hfindex, tvb, offset, value); +- +- *offset += 1; +- +- return value; +-} +- +-typedef int(*uint16_value_conversion)(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value); +- +-static guint16 proto_tree_add_uint16_with_conversion(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, uint16_value_conversion conversion) +-{ +- guint16 value = tvb_get_guint16(tvb, *offset, ENC_NA); +- +- conversion(tree, hfindex, tvb, offset, value); +- +- *offset += 2; +- +- return value; +-} +- +-typedef int(*int16_value_conversion)(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, gint16 value); +- +-static gint16 proto_tree_add_int16_with_conversion(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, int16_value_conversion conversion) +-{ +- gint16 value = (gint16)(tvb_get_guint16(tvb, *offset, ENC_NA)); +- +- conversion(tree, hfindex, tvb, offset, value); +- +- *offset += 2; +- +- return value; +-} +- +- +-static void proto_tree_add_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb, guint* offset, char* units) +-{ +- proto_item * item = proto_tree_add_item(tree, hfindex, tvb, *offset, 4, ENC_NA); +- +- if (units != NULL) +- { +- proto_item_append_text(item, " "); +- proto_item_append_text(item, units); +- } +- +- *offset += 4; +-} +- +-static void proto_tree_add_uint8_array(proto_tree *tree, int hfindex, guint len, tvbuff_t *tvb, guint* offset) +-{ +- proto_tree_add_item(tree, hfindex, tvb, *offset, len, ENC_NA); +- +- *offset += len; +-} +- +- +- +- +- +-int dissect_array_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end, const char* name, guint32 hf_idx, guint32 ett_idx, guint32 count, tlv_decode decode) +-{ +- guint16 i = 0; +- +- if (count > 0) +- { +- proto_item *list_ti = proto_tree_add_string_format(tree, hf_idx, tvb, *offset, 2, "", name); +- proto_tree *list_tree = proto_item_add_subtree(list_ti, ett_idx); +- +- gint start_of_list = *offset; +- +- for (i = 0; i < count; ++i) +- { +- proto_item *item_ti = proto_tree_add_string_format(list_tree, hf_idx, tvb, *offset, 2, "", "[%d]", i); +- proto_tree *item_tree = proto_item_add_subtree(item_ti, ett_idx); +- +- gint start_of_item = *offset; +- +- decode(tvb, pinfo, item_tree, data, offset, end); +- +- if (item_ti != NULL) +- item_ti->finfo->length = *offset - start_of_item; +- } +- +- if (list_ti != NULL) +- list_ti->finfo->length = *offset - start_of_list; +- } +- +- return 0; +-} +- +-int dissect_pnf_param_general_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_sync_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_location_mode, tvb, offset, 0); +- guint16 len = proto_tree_add_uint16(tree, hf_nfapi_location_coordinates_length, tvb, offset, 0); +- if (len > 0) +- proto_tree_add_uint8_array(tree, hf_nfapi_location_coordinates, len, tvb, offset); +- proto_tree_add_uint32(tree, hf_nfapi_dl_config_timing, tvb, offset, "milliseconds"); +- proto_tree_add_uint32(tree, hf_nfapi_tx_timing, tvb, offset, "milliseconds"); +- proto_tree_add_uint32(tree, hf_nfapi_ul_config_timing, tvb, offset, "milliseconds"); +- proto_tree_add_uint32(tree, hf_nfapi_hi_dci0_timing, tvb, offset, "milliseconds"); +- proto_tree_add_uint16(tree, hf_nfapi_maximum_number_phys, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_maximum_total_bandwidth, tvb, offset, "(100 khz)"); +- proto_tree_add_uint8(tree, hf_nfapi_maximum_total_number_dl_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_maximum_total_number_ul_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_shared_bands, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_shared_pa, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_maximum_total_power, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_oui, 3, tvb, offset); +- +- return 0; +-} +- +-int dissect_pnf_rf_config_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_rf_config_index, tvb, offset, 0); +- return 0; +-} +- +-int dissect_pnf_phy_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- guint16 num_rf_configs = proto_tree_add_uint16(tree, hf_nfapi_number_of_rfs, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Config List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy, num_rf_configs, dissect_pnf_rf_config_instance_value); +- guint16 num_rf_exclusions = proto_tree_add_uint16(tree, hf_nfapi_number_of_rf_exclusions, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Exclustion List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy, num_rf_exclusions, dissect_pnf_rf_config_instance_value); +- proto_tree_add_uint16(tree, hf_nfapi_downlink_channel_bandwidth_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_uplink_channel_bandwidth_supported, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_dl_layers_supported, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_ul_layers_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_maximum_3gpp_release_supported, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nmm_modes_supported, tvb, offset, 0); +- return 0; +-} +- +-int dissect_pnf_phy_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_phy = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy, num_phy, dissect_pnf_phy_instance_value); +- +- +- return 0; +- +-} +- +- +-int dissect_pnf_rf_config_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_rf_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_band, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_maximum_transmit_power, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_minimum_transmit_power, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_antennas_suppported, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_minimum_downlink_frequency, tvb, offset, "(100 khz)"); +- proto_tree_add_uint32(tree, hf_nfapi_maximum_downlink_frequency, tvb, offset, "(100 khz)"); +- proto_tree_add_uint32(tree, hf_nfapi_minimum_uplink_frequency, tvb, offset, "(100 khz)"); +- proto_tree_add_uint32(tree, hf_nfapi_maximum_uplink_frequency, tvb, offset, "(100 khz)"); +- +- return 0; +-} +- +- +-int dissect_pnf_rf_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_rf = proto_tree_add_uint16(tree, hf_nfapi_number_of_rfs, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF List", hf_nfapi_pnf_phy_rf_config_array_phy_rf_config_info, ett_nfapi_pnf_phy_rf_config, num_rf, dissect_pnf_rf_config_value); +- +- return 0; +- +-} +- +-int dissect_pnf_phy_rel10_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_transmission_mode7_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_transmission_mode8_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_two_antennas_ports_for_pucch, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_transmission_mode_9_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_simultaneous_pucch_pusch, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_for_layer_tx_with_tm3_and_tm4, tvb, offset, 0); +- +- return 0; +-} +- +-int dissect_pnf_phy_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_phy = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY Rel 10 List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy_rel10, num_phy, dissect_pnf_phy_rel10_instance_value); +- +- return 0; +-} +- +-int dissect_pnf_phy_rel11_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_epdcch_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_multi_ack_csi_reporting, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_pucch_tx_diversity_with_channel_selection, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_ul_comp_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_transmission_mode_5_supported, tvb, offset, 0); +- return 0; +-} +- +-int dissect_pnf_phy_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_phy = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY Rel 11 List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy_rel11, num_phy, dissect_pnf_phy_rel11_instance_value); +- return 0; +-} +- +-int dissect_pnf_phy_rel12_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_csi_subframe_set, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_enhanced_4tx_codebook, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_drs_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_ul_64qam_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_transmission_mode_10_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hi_nfapi_alternative_tbs_indices, tvb, offset, 0); +- return 0; +-} +- +-int dissect_pnf_phy_rel12_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_phy = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY Rel 12 List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy_rel12, num_phy, dissect_pnf_phy_rel12_instance_value); +- return 0; +-} +- +-int dissect_pnf_phy_rel13_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pucch_format_4_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pucch_format_5_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_more_than_5_ca_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_laa_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_laa_ending_in_dwpts_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_laa_starting_in_second_slot_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_beamforming_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_csi_rs_enhancements_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_drms_enhancements_supported, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_srs_enhancements_supported, tvb, offset, 0); +- return 0; +-} +- +-int dissect_pnf_phy_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_phy = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY Rel 13 List", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy_rel13, num_phy, dissect_pnf_phy_rel13_instance_value); +- return 0; +-} +- +-int dissect_pnf_phy_rf_config_instance_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_phy_rf_config_info_phy_id, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_config_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rf_config_index, tvb, offset, 0); +- return 0; +-} +- +- +-int dissect_pnf_phy_rf_config_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_configs = proto_tree_add_uint16(tree, hf_nfapi_pnf_phy_number_phy, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PHY RF Config List", hf_nfapi_pnf_phy_rf_config, ett_nfapi_pnf_phy_rf_config, num_configs, dissect_pnf_phy_rf_config_instance_value); +- return 0; +-} +- +-int bandwidth_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- /* +- guint8 comma = 0; +- +- proto_item_append_text(item, "("); +- +- if (value & 0x1) +- { +- proto_item_append_text(item, "6 Mhz"); +- comma = 1; +- } +- +- if (comma) +- proto_item_append_text(item, ", "); +- +- if (value & 0x2) +- { +- proto_item_append_text(item, "15 Mhz"); +- comma = 1; +- } +- +- if (comma) +- proto_item_append_text(item, ", "); +- +- if (value & 0x4) +- { +- proto_item_append_text(item, "25 Mhz"); +- comma = 1; +- } +- +- if (comma) +- proto_item_append_text(item, ", "); +- +- if (value & 0x8) +- { +- proto_item_append_text(item, "50 Mhz"); +- comma = 1; +- } +- +- if (comma) +- proto_item_append_text(item, ", "); +- +- if (value & 0x10) +- { +- proto_item_append_text(item, "75 Mhz"); +- comma = 1; +- } +- +- if (comma) +- proto_item_append_text(item, ", "); +- +- if (value & 0x20) +- { +- proto_item_append_text(item, "100 Mhz"); +- comma = 1; +- } +- +- proto_item_append_text(item, ")"); +- */ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "?? (%d)", value); +- return 0; +- +-} +- +-int sfn_sf_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "%d/%d (%d)", value >> 3, value & 0x0007, value); +- return 0; +-} +- +- +-int dissect_duplex_mode_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_duplex_mode, tvb, offset, 0); +- return 0; +-} +- +-int power_offset_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "%.2f dB (%d)", (((float)value * 0.001) - 6.0), value); +- return 0; +-} +- +-int dissect_pcfich_power_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 value = proto_tree_add_uint16_with_conversion(tree, hf_nfapi_pcfich_power_offset, tvb, offset, power_offset_conversion); +- +- if (value > 10000) +- { +- expert_add_info(pinfo, tree, &ei_power_invalid); +- } +- +- return 0; +-} +- +-int dissect_pb_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 value = proto_tree_add_uint16(tree, hf_nfapi_pb, tvb, offset, 0); +- +- if (value > 3) +- { +- expert_add_info(pinfo, tree, &ei_power_invalid); +- } +- return 0; +-} +- +-int dissect_dl_cyclic_prefix_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_dl_cyclic_prefix_type, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_cyclic_prefix_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_ul_cyclic_prefix_type, tvb, offset, 0); +- return 0; +-} +-int dissect_dl_channel_bandwidth_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_downlink_channel_bandwidth, tvb, offset, bandwidth_conversion); +- return 0; +-} +-int dissect_ul_channel_bandwidth_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_uplink_channel_bandwidth, tvb, offset, bandwidth_conversion); +- return 0; +-} +- +- +-int reference_signal_power_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "%.2f dB (%d)", (((float)value * 0.25) - 63.75), value); +- return 0; +-} +- +-int dissect_reference_signal_power_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_reference_signal_power, tvb, offset, reference_signal_power_conversion); +- return 0; +-} +-int dissect_tx_antenna_ports_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_tx_antenna_ports, tvb, offset, 0); +- return 0; +-} +-int dissect_rx_antenna_ports_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_rx_antenna_ports, tvb, offset, 0); +- return 0; +-} +-int dissect_phich_resource_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_phich_resource, tvb, offset, 0); +- return 0; +-} +-int dissect_phich_duration_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_phich_duration, tvb, offset, 0); +- return 0; +-} +-int dissect_phich_power_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_phich_power_offset, tvb, offset, power_offset_conversion); +- return 0; +-} +-int dissect_psch_synch_signal_epre_eprers_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_primary_synchronization_signal_epre_eprers, tvb, offset, power_offset_conversion); +- return 0; +-} +-int dissect_physical_cell_id_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_physical_cell_id, tvb, offset, 0); +- return 0; +-} +-int dissect_ssch_synch_signal_epre_eprers_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_secondary_synchronization_signal_epre_eprers, tvb, offset, power_offset_conversion); +- return 0; +-} +-int dissect_prach_configuration_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_configuration_index, tvb, offset, 0); +- return 0; +-} +-int dissect_prach_root_sequence_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_root_sequence_index, tvb, offset, 0); +- return 0; +-} +-int dissect_prach_zero_correlation_zone_configuration_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_zero_correlation_zone_configuration, tvb, offset, 0); +- return 0; +-} +-int dissect_prach_high_speed_flag_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_high_speed_flag, tvb, offset, 0); +- return 0; +-} +-int dissect_prach_frequency_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_frequency_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_pusch_hopping_mode_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_hopping_mode, tvb, offset, 0); +- return 0; +-} +-int dissect_pusch_hopping_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_hopping_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_pusch_number_of_subbands_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_number_of_subbands, tvb, offset, 0); +- return 0; +-} +-int dissect_pucch_delta_pucch_shift_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_delta_pucch_shift, tvb, offset, 0); +- return 0; +-} +-int dissect_pucch_n_cqi_rb_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_n_cqi_rb, tvb, offset, 0); +- return 0; +-} +-int dissect_pucch_n_an_cs_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_n_an_cs, tvb, offset, 0); +- return 0; +-} +-int dissect_pucch_n1_pucch_an_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_n1_pucch_an, tvb, offset, 0); +- return 0; +-} +-int dissect_srs_bandwidth_configuration_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_bandwidth_configuration, tvb, offset, 0); +- return 0; +-} +-int dissect_srs_max_uppts_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_max_up_pts, tvb, offset, 0); +- return 0; +-} +-int dissect_srs_subframe_configuration_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_srs_subframe_configuration, tvb, offset, 0); +- return 0; +-} +-int dissect_srs_acknack_srs_sim_tx_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_srs_acknack_srs_simultaneous_transmission, tvb, offset, 0); +- return 0; +-} +-int dissect_uplink_rs_hopping_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_uplink_rs_hopping, tvb, offset, 0); +- return 0; +-} +-int dissect_group_assignment_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_group_assignment, tvb, offset, 0); +- return 0; +-} +-int dissect_cyclic_shift_1_for_drms_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_cyclic_shift_1_for_drms, tvb, offset, 0); +- return 0; +-} +-int dissect_tdd_subframe_assignement_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_subframe_assignment, tvb, offset, 0); +- return 0; +-} +-int dissect_tdd_subframe_patterns_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_special_subframe_patterns, tvb, offset, 0); +- return 0; +-} +- +-int laa_threshold_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "%.2f dB (%d)", (float)(value * -100.00), value); +- return 0; +-} +- +-int dissect_laa_ed_threashold_for_lbt_for_pdsch_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_ed_threshold_for_lbt_for_pdsch, tvb, offset, laa_threshold_conversion); +- return 0; +-} +-int dissect_laa_ed_threashold_for_lbt_for_drs_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_ed_threshold_for_lbt_for_drs, tvb, offset, laa_threshold_conversion); +- return 0; +-} +-int dissect_laa_pd_threshold_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_pd_threshold, tvb, offset, laa_threshold_conversion); +- return 0; +-} +-int dissect_laa_multi_carrier_type_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_multi_carrier_type, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_multi_carrier_tx_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_multi_carrier_tx, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_multi_carrier_freeze_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_multi_carrier_freeze, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_tx_antenna_port_for_drs_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_tx_antenna_ports_for_drs, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_transmission_power_for_drs_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power_for_drs, tvb, offset, power_offset_conversion); +- return 0; +-} +- +-int dissect_emtc_pbch_repeitions_enabled_r13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pbch_repetitions_enabled_r13, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_cat_m_root_sequence_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_cat_m_root_sequence_index, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_cat_m_zero_correlation_zone_configuration_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_cat_m_zero_correlation_zone_configuration, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_cat_m_high_speed_flag_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_cat_m_high_speed_flag, tvb, offset, 0); +- return 0; +-} +- +-int dissect_emtc_prach_ce_level_0_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_enable, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_0_configuration_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_configuration_index, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_0_frequency_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_frequency_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_0_num_of_repeitions_per_attempt_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_ce_level_0_starting_subframe_periodicity_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_starting_subframe_periodicity, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_0_hopping_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_hopping_enabled, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_0_hopping_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_0_hopping_offset, tvb, offset, 0); +- return 0; +-} +- +-int dissect_emtc_prach_ce_level_1_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_enable, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_1_configuration_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_configuration_index, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_1_frequency_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_frequency_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_1_num_of_repeitions_per_attempt_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_ce_level_1_starting_subframe_periodicity_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_starting_subframe_periodicity, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_1_hopping_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_hopping_enabled, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_1_hopping_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_1_hopping_offset, tvb, offset, 0); +- return 0; +-} +- +-int dissect_emtc_prach_ce_level_2_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_enable, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_2_configuration_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_configuration_index, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_2_frequency_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_frequency_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_2_num_of_repeitions_per_attempt_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_ce_level_2_starting_subframe_periodicity_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_starting_subframe_periodicity, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_2_hopping_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_hopping_enabled, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_2_hopping_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_2_hopping_offset, tvb, offset, 0); +- return 0; +-} +- +-int dissect_emtc_prach_ce_level_3_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_enable, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_3_configuration_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_configuration_index, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_prach_ce_level_3_frequency_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_frequency_offset, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_3_num_of_repeitions_per_attempt_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_ce_level_3_starting_subframe_periodicity_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_starting_subframe_periodicity, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_3_hopping_enabled_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_hopping_enabled, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_preach_ce_level_3_hopping_offset_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_prach_ce_level_3_hopping_offset, tvb, offset, 0); +- return 0; +-} +- +-int dissect_emtc_pucch_interval_ul_hopping_config_common_mode_a_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a, tvb, offset, 0); +- return 0; +-} +-int dissect_emtc_pucch_interval_ul_hopping_config_common_mode_b_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b, tvb, offset, 0); +- return 0; +-} +- +- +-int dissect_dl_bandwidth_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_dl_bandwidth_support, tvb, offset, bandwidth_conversion); +- return 0; +-} +- +-int dissect_ul_bandwidth_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_ul_bandwidth_support, tvb, offset, bandwidth_conversion); +- return 0; +-} +- +-int dl_modulation_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "?? (%d)", value); +- return 0; +-} +- +-int dissect_dl_modulation_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_dl_modulation_support, tvb, offset, dl_modulation_conversion); +- return 0; +-} +- +-int ul_modulation_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "?? (%d)", value); +- return 0; +-} +-int dissect_ul_modulation_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_ul_modulation_support, tvb, offset, ul_modulation_conversion); +- return 0; +-} +-int dissect_phy_antenna_capability_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_phy_antenna_capability, tvb, offset, 0); +- return 0; +-} +- +-int release_capability_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint16 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 2, value, "?? (%d)", value); +- return 0; +-} +-int dissect_release_capability_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_release_capability, tvb, offset, release_capability_conversion); +- return 0; +-} +-int dissect_mbsfn_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_mbsfn_capability, tvb, offset, 0); +- return 0; +-} +- +-int dissect_laa_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_laa_capability, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_pd_sensing_lbt_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pd_sensing_lbt_support, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_multi_carrier_lbt_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_multi_carrier_lbt_support, tvb, offset, 0); +- return 0; +-} +-int dissect_laa_partial_sf_support_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_partial_sf_support, tvb, offset, 0); +- return 0; +-} +- +-int dissect_data_report_mode_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_data_report_mode, tvb, offset, 0); +- return 0; +-} +-int dissect_sfn_sf_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_sfnsf, tvb, offset, 0); +- return 0; +-} +-int dissect_phy_state_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_phy_state, tvb, offset, 0); +- return 0; +-} +- +- +- +-int dissect_p7_vnf_address_ipv4_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_vnf_address_ipv4, 4, tvb, offset); +- return 0; +-} +-int dissect_p7_vnf_address_ipv6_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_vnf_address_ipv4, 16, tvb, offset); +- return 0; +-} +-int dissect_p7_vnf_port_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_vnf_port, tvb, offset, 0); +- return 0; +-} +- +-int dissect_p7_pnf_address_ipv4_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_pnf_address_ipv4, 4, tvb, offset); +- return 0; +-} +-int dissect_p7_pnf_address_ipv6_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_pnf_address_ipv4, 16, tvb, offset); +- return 0; +-} +-int dissect_p7_pnf_port_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pnf_port, tvb, offset, 0); +- return 0; +-} +- +-int dissect_downlink_ues_per_subframe_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dl_ue_per_sf, tvb, offset, 0); +- return 0; +-} +- +-int dissect_uplink_ues_per_subframe_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ul_ue_per_sf, tvb, offset, 0); +- return 0; +-} +- +-int dissect_rf_band_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_band, tvb, offset, 0); +- return 0; +-} +- +-int dissect_rf_bands_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 count = proto_tree_add_uint16(tree, hf_nfapi_number_of_rf_bands, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Band List", hf_nfapi_rf_bands, ett_nfapi_rf_bands, count, dissect_rf_band_value); +- return 0; +-} +- +-int dissect_timing_window_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_timing_window, tvb, offset, 0); +- return 0; +-} +-int dissect_timing_info_mode_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_timing_info_mode, tvb, offset, 0); +- return 0; +-} +-int dissect_timing_info_period_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_timing_info_period, tvb, offset, 0); +- return 0; +-} +- +-int dissect_maximum_transmit_power_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_maximum_transmit_power, tvb, offset, 0); +- return 0; +-} +-int dissect_earfcn_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_earfcn, tvb, offset, 0); +- return 0; +-} +- +-int dissect_nmm_gsm_frequency_bands_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 count = proto_tree_add_uint16(tree, hf_nfapi_number_of_rf_bands, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Band List", hf_nfapi_rf_bands, ett_nfapi_rf_bands, count, dissect_rf_band_value); +- return 0; +-} +-int dissect_nmm_umts_frequency_bands_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 count = proto_tree_add_uint16(tree, hf_nfapi_number_of_rf_bands, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Band List", hf_nfapi_rf_bands, ett_nfapi_rf_bands, count, dissect_rf_band_value); +- return 0; +-} +-int dissect_nmm_lte_frequency_bands_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 count = proto_tree_add_uint16(tree, hf_nfapi_number_of_rf_bands, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RF Band List", hf_nfapi_rf_bands, ett_nfapi_rf_bands, count, dissect_rf_band_value); +- return 0; +-} +-int dissect_nmm_uplink_rssi_supported_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_nmm_uplink_rssi_supported, tvb, offset, 0); +- return 0; +-} +- +-int dissect_dl_config_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dl_config_pdu_type, tvb, offset, 0); +- guint8 size = proto_tree_add_uint8(tree, hf_nfapi_pdu_size, tvb, offset, 0); +- +- guint pdu_end = (*offset + size - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- +- return 0; +-} +- +- +-static int dissect_dl_config_request_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_pdcch_ofdm_symbols, tvb, offset, 0); +- guint16 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_dci, tvb, offset, 0); +- num_pdu += proto_tree_add_uint16(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_pdsch_rnti, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power_pcfich, tvb, offset, power_offset_conversion); +- +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "DL Config PDU List", hf_nfapi_dl_config_request_pdu_list, ett_nfapi_dl_config_request_pdu_list, num_pdu, dissect_dl_config_pdu); +- +- +- return 0; +-} +- +-static int dissect_dl_config_request_bch_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pdu_index, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- return 0; +-} +- +-static int dissect_dl_config_request_dl_dci_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dci_format, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cce_idx, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_aggregation_level, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_virtual_resource_block_assignment_flag, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indicator_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_block_to_codeword_swap_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indicator_2, tvb, offset, 0); +- proto_tree_add_uint8_with_range(tree, hf_nfapi_harq_process, tvb, offset, pinfo, 0, 15, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpmi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_precoding_information, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpc, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_downlink_assignment_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ngap, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_block_size_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_downlink_power_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_allocate_prach_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_preamble_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_prach_mask_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rnti_type, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- return 0; +-} +-static int dissect_dl_config_request_dl_dci_pdu_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_mcch_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcch_change_notification, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_scrambling_identity, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_dl_dci_pdu_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_cross_carrier_scheduling_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_carrier_indicator, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_size_of_cqi_csi_feild, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_antenna_ports_scrambling_and_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_total_dci_length_including_padding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_n_dl_rb, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_dl_dci_pdu_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_ack_resource_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator, tvb, offset, 0); +- return 0; +-} +- +-int dissect_ul_dl_configuration_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ul_dl_configuration_index, tvb, offset, 0); +- return 0; +-} +- +- +-static int dissect_dl_config_request_dl_dci_pdu_rel12_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_primary_cell_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_dl_configuration_flag, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_ul_dl_configurations, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "UL/DL Configurations", hf_nfapi_pnf_phy, ett_nfapi_pnf_phy, count, dissect_ul_dl_configuration_index_value); +- +- return 0; +-} +-static int dissect_dl_config_request_dl_dci_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_laa_end_partial_sf_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_laa_end_partial_sf_configuration, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_initial_lbt_sf, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_codebooksize_determination_r13, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rel13_drms_table_flag, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_dl_config_request_mch_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pdu_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_modulation, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- proto_tree_add_uint16(tree, hf_nfapi_mbsfn_area_id, tvb, offset, 0); +- +- return 0; +-} +- +-int dissect_codebook_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_codebook_index, tvb, offset, 0); +- return 0; +-} +- +-int dissect_bf_vector_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_bf_vector_bf_value, tvb, offset, 0); +- return 0; +-} +- +-int dissect_bf_vector_type_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_bf_vector_subband_index, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_bf_vector_num_antennas, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Antennas", hf_nfapi_bf_vector_antennas, ett_nfapi_bf_vector_antennas, count, dissect_bf_vector_value); +- return 0; +-} +- +-static int dissect_dl_config_request_dlsch_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pdu_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_virtual_resource_block_assignment_flag, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_modulation, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_block_to_codeword_swap_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transmission_scheme, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_layers, tvb, offset, 0); +- guint8 num_subbands = proto_tree_add_uint8(tree, hf_nfapi_number_of_subbands, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Subbands", hf_nfapi_subbands, ett_nfapi_subbands, num_subbands, dissect_codebook_index_value); +- proto_tree_add_uint8(tree, hf_nfapi_ue_category_capacity, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pa, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_power_offset_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ngap, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nprb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transmission_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_num_bf_prb_per_subband, tvb, offset, 0); +- guint8 num_vectors = proto_tree_add_uint8(tree, hf_nfapi_num_bf_vector, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Beamforming Vectors", hf_nfapi_bf_vectors, ett_nfapi_bf_vectors, num_vectors, dissect_bf_vector_type_value); +- +- +- return 0; +-} +- +-int dissect_csi_rs_resource_config_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_resource_config, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_dl_config_request_dlsch_pdu_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_nscid, tvb, offset, 0); +- +- return 0; +-} +-static int dissect_dl_config_request_dlsch_pdu_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_resource_config_r10, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_csi_rs_number_if_nzp_configurations, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "CSI-RS Resource Configs", hf_nfapi_csi_rs_resource_configs, ett_nfapi_csi_rs_resource_configs, count, dissect_csi_rs_resource_config_value); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_start, tvb, offset, 0); +- +- return 0; +-} +-static int dissect_dl_config_request_dlsch_pdu_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_drms_config_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_drms_scrambling, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_csi_config_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_csi_scrambling, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_re_mapping_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_re_mapping_antenna_ports, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_re_mapping_freq_shift, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_dlsch_pdu_rel12_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_alt_cqi_table_r12, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_max_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_n_dl_harq, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_dlsch_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dwpts_symbols, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_initial_lbt_sf, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ue_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_payload_type, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_initial_transmission_sf, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_req13_drms_table_flag, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_pch_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pdu_index, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_prnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_virtual_resource_block_assignment_flag, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_transport_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_block_to_codeword_swap_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transmission_scheme, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_codebook_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ue_category_capacity, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pa, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- proto_tree_add_uint8(tree, hf_nfapi_nprb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ngap, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_pch_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ue_mode, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_initial_transmission_sf, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_prs_pdu_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- proto_tree_add_uint8(tree, hf_prs_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_prs_cyclic_prefix_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_prs_muting, tvb, offset, 0); +- return 0; +-} +-static int dissect_dl_config_request_csi_rs_pdu_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_antenna_port_count_r10, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_resource_config_r10, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- proto_tree_add_uint16(tree, hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_csi_rs_number_if_nzp_configurations, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "CSI-RS Resource Configs", hf_nfapi_csi_rs_resource_configs, ett_nfapi_csi_rs_resource_configs, count, dissect_csi_rs_resource_config_value); +- return 0; +-} +- +- +-int dissect_csi_rs_bf_vector_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_resource_index, tvb, offset, 0); +- //proto_tree_add_uint8(tree, hf_nfapi_csi_rs_resource_config, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_dl_config_request_csi_rs_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_rs_class, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cdm_type, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_num_bf_vector, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Beamforming Vector", hf_nfapi_csi_rs_bf_vector, ett_nfapi_csi_rs_bf_vector, count, dissect_csi_rs_bf_vector_value); +- return 0; +-} +- +-int dissect_epdcch_prb_index_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_edpcch_prb_index, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_dl_config_request_edpcch_params_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_epdcch_resource_assignment_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_epdcch_id, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_epdcch_start_symbol, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_epdcch_num_prb, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PRBs", hf_nfapi_epdcch_prbs, ett_nfapi_epdcch_prbs, count, dissect_epdcch_prb_index_value); +- dissect_bf_vector_type_value(tvb, pinfo, tree, data, offset, end); +- +- return 0; +-} +-static int dissect_dl_config_request_edpcch_params_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dwpts_symbols, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_initial_lbt_sf, tvb, offset, 0); +- return 0; +-} +- +-int dissect_precoding_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_precoding_value, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_dl_config_request_mpdpcch_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_mpdcch_narrowband, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_prb_pairs, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_block_assignment, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_start_symbol, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ecce_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_aggregation_level, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rnti_type, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ce_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_drms_scrabmling_init, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_initial_transmission_sf, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_transmission_power, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dci_format, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_resource_block_coding , tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pdsch_reception_levels , tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indicator, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_process, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpmi_length, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpmi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pmi_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_resource_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dci_subframe_repetition_number, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpc, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_downlink_assignment_index_length, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_downlink_assignment_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_allocate_prach_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_preamble_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_prach_mask_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_starting_ce_level, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_antenna_ports_and_scrambling_identity_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_antenna_ports_and_scrambling_identity, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_enabled_flag , tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_paging_direct_indication_differentiation_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_direct_indication, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_total_dci_length_including_padding, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_tx_antenna_ports, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Precoding", hf_nfapi_precoding, ett_nfapi_precoding, count, dissect_precoding_value); +- +- return 0; +-} +- +-int dissect_ul_config_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ul_config_pdu_type, tvb, offset, 0); +- guint8 size = proto_tree_add_uint8(tree, hf_nfapi_pdu_size, tvb, offset, 0); +- +- guint pdu_end = (*offset + size - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- +- return 0; +-} +- +-static int dissect_ul_config_request_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rach_prach_frequency_resources, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_present, tvb, offset, 0); +- +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "UL Config PDU List", hf_nfapi_ul_config_request_pdu_list, ett_nfapi_ul_config_request_pdu_list, num_pdu, dissect_ul_config_pdu); +- +- return 0; +-} +- +- +-int dissect_ul_config_ulsch_pdu_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_size, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_block_start, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_resource_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_modulation, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cyclic_shift_2_for_drms, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_enabled_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_bits, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indication, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_process_number, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_tx_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_current_tx_nb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_n_srs, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ulsch_pdu_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transport_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_transmission_scheme, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_layers, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_codebook_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_disable_sequence_hopping_flag, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ulsch_pdu_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_virtual_cell_id_enabled_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_npusch_identity, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_drms_config_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_ndrms_csh_identity, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ulsch_pdu_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ue_type, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_total_number_of_repetitions, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_repetition_number, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_initial_sf_io, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_empty_symbols_due_to_retunning, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_init_tx_params_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_n_srs_initial, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_initial_number_of_resource_blocks, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_cqi_ri_info_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dl_cqi_pmi_size_rank_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dl_cqi_pmi_size_rank_greater_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ri_size, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_cqi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_ri, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_cqi_ri_info_rel9_later_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 type = proto_tree_add_uint8(tree, hf_nfapi_report_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_cqi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_ri, tvb, offset, 0); +- +- switch (type) +- { +- case 0: +- { +- proto_tree_add_uint8(tree, hf_nfapi_dl_cqi_ri_pmi_size, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_control_type, tvb, offset, 0); +- break; +- } +- case 1: +- { +- /*guint8 num_cc = */proto_tree_add_uint8(tree, hf_nfapi_number_of_cc, tvb, offset, 0); +- +- // todo ... +- +- break; +- } +- } +- return 0; +-} +-int dissect_ul_config_cqi_ri_info_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_dl_cqi_ri_pmi_size_2, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_ulsch_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_size, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_harq, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ack_nack_mode, tvb, offset, 0); +- +- return 0; +-} +-int dissect_ul_config_harq_info_ulsch_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_harq_size_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_delta_offset_harq_2, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ue_info_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ue_info_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_virtual_cell_id_enabled_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_npucch_identity, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_ue_info_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ue_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_empty_symbols, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_total_number_of_repetitions, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_repetition_number, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_cqi_info_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pucch_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dl_cqi_pmi_size, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_cqi_info_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_of_pucch_resource, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pucch_index_p1, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_cqi_info_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_csi_mode, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_dl_cqi_pmi_size_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_statring_prb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nprb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cdm_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nsrs, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_sr_info_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_pucch_index, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_sr_info_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_of_pucch_resource, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pucch_index_p1, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_uci_rel10_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_size, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ack_nack_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_pucch_resource, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_0, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_1, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_2, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_3, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_uci_rel8_fdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_0, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_size, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_uci_rel9_later_fdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_size, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ack_nack_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_pucch_resource, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_0, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_1, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_2, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_1_3, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_uci_rel11_fdd_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_num_ant_ports, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_2_0, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_2_1, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_2_2, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_n_pucch_2_3, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_harq_info_uci_rel13_fdd_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_harq_size_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_starting_prb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nprb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cdm_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_nsrs, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_srs_info_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_size, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_domain_position, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_hopping_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_transmission_comb, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_i_srs, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_sounding_reference_cyclic_shift, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_srs_info_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_antenna_port, tvb, offset, 0); +- return 0; +-} +-int dissect_ul_config_srs_info_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_of_combs, tvb, offset, 0); +- return 0; +-} +- +-int dissect_hi_dci0_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_pdu_type, tvb, offset, 0); +- guint8 size = proto_tree_add_uint8(tree, hf_nfapi_pdu_size, tvb, offset, 0); +- +- guint pdu_end = (*offset + size - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- +- return 0; +-} +- +-static int dissect_hi_dci0_request_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_sfn_sf, tvb, offset, 0); +- guint8 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_of_dci_pdus, tvb, offset, 0); +- num_pdu += proto_tree_add_uint8(tree, hf_nfapi_number_of_hi_pdus, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "HI DCI0 PDU List", hf_nfapi_hi_dci0_request_pdu_list, ett_nfapi_hi_dci0_request_pdu_list, num_pdu, dissect_hi_dci0_pdu); +- return 0; +-} +- +-static int dissect_hi_dci0_hi_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_resource_block_start, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cyclic_shift_2_for_drms, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_hi_value, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_i_phich, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- return 0; +-} +-static int dissect_hi_dci0_hi_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_flag_tb2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_hi_value_2, tvb, offset, 0); +- return 0; +-} +-static int dissect_hi_dci0_dci_ul_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_dci_format, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cce_idx, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_aggregation_level, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_block_start, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_resource_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cyclic_shift_2_for_drms, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_enabled_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_bits, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indication, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ue_tx_antenna_selection, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpc, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_cqi_csi_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dl_assignment_index, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_tpc_bitmap, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- return 0; +-} +-static int dissect_hi_dci0_dci_ul_rel10_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_cross_carrier_scheduling_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_carrier_indicator, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_size_of_cqi_csi_feild, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_resource_allocation_type, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_coding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indication_two, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_antenna_ports, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpmi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_total_dci_length_including_padding, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_n_ul_rb, tvb, offset, 0); +- return 0; +-} +-static int dissect_hi_dci0_dci_ul_rel12_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_pscch_resource, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_time_resource_pattern, tvb, offset, 0); +- return 0; +-} +-static int dissect_hi_dci0_edpcch_dci_ul_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_epdcch_resource_assignment_flag, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_epdcch_id, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_epdcch_start_symbol, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_epdcch_num_prb, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PRBs", hf_nfapi_epdcch_prbs, ett_nfapi_epdcch_prbs, count, dissect_epdcch_prb_index_value); +- dissect_bf_vector_type_value(tvb, pinfo, tree, data, offset, end); +- return 0; +-} +- +-static int dissect_hi_dci0_mdpcch_dci_ul_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_mpdcch_narrowband, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_prb_pairs, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_resource_block_assignment, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mpdcch_transmission_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_start_symbol, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ecce_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_aggregation_level, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rnti_type, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ce_mode, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_drms_scrambling_init, tvb, offset, 0); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_transmission_power, tvb, offset, power_offset_conversion); +- proto_tree_add_uint8(tree, hf_nfapi_dci_format, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_resource_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_mcs, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_pusch_repetition_levels, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_frequency_hopping_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_new_data_indication, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_process, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_redundancy_version, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_tpc, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_csi_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dai_presence_flag, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dl_assignment_index, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_srs_request, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_dci_subframe_repetition_number, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_tpc_bitmap, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_total_dci_length_include_padding, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_tx_antenna_ports, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "TX Antenna Ports", hf_nfapi_tx_antenna_ports, ett_nfapi_tx_antenna_ports, count, dissect_precoding_value); +- +- +- return 0; +-} +-static int dissect_rx_ue_info_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- return 0; +-} +-static int dissect_rx_indication_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- int data_offset = proto_tree_add_uint16(tree, hf_nfapi_data_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_cqi, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance, tvb, offset, 0); +- return data_offset; +-} +-static int dissect_rx_indication_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance_r9, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_bundling_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_1, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_multplexing_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_2, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_3, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_special_bundling_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_channel_selection_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_format_3_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_harq_indication_data_format_4_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- return 0; +-} +- +- +-static int dissect_harq_indication_data_format_5_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_data_value_0, tvb, offset, 0); +- return 0; +-} +- +- +- +-static int dissect_harq_indication_rel8_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 mode = proto_tree_add_uint8(tree, hf_nfapi_harq_mode, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_ack_nack, tvb, offset, 0); +- +- switch (mode) +- { +- case 0: +- { +- dissect_harq_indication_data_bundling_value(tvb, pinfo, tree, data, offset, end); +- break; +- } +- case 1: +- { +- dissect_harq_indication_data_multplexing_value(tvb, pinfo, tree, data, offset, end); +- break; +- } +- case 2: +- { +- dissect_harq_indication_data_special_bundling_value(tvb, pinfo, tree, data, offset, end); +- break; +- } +- }; +- +- return 0; +-} +-static int dissect_harq_indication_rel9_later_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 mode = proto_tree_add_uint8(tree, hf_nfapi_harq_mode, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_ack_nack, tvb, offset, 0); +- +- // Have to do this as the mode value is need to decode the value +- guint16 i = 0; +- +- proto_item *list_ti = proto_tree_add_string_format(tree, hf_nfapi_harq_ack_nack_data, tvb, *offset, 2, "", "ACK/NACK Data"); +- proto_tree *list_tree = proto_item_add_subtree(list_ti, ett_nfapi_harq_ack_nack_data); +- +- for (i = 0; i < count; ++i) +- { +- +- proto_item *item_ti = proto_tree_add_string_format(list_tree, hf_nfapi_harq_ack_nack_data, tvb, *offset, 2, "", "[%d]", i); +- proto_tree *item_tree = proto_item_add_subtree(item_ti, ett_nfapi_harq_ack_nack_data); +- +- switch (mode) +- { +- case 0: +- { +- dissect_harq_indication_data_bundling_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 1: +- { +- dissect_harq_indication_data_multplexing_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 2: +- { +- dissect_harq_indication_data_special_bundling_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 3: +- { +- dissect_harq_indication_data_channel_selection_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 4: +- { +- dissect_harq_indication_data_format_3_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- }; +- } +- +- return 0; +-} +-static int dissect_harq_indication_rel13_later_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 mode = proto_tree_add_uint8(tree, hf_nfapi_harq_mode, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_ack_nack, tvb, offset, 0); +- +- // Have to do this as the mode value is need to decode the value +- guint16 i = 0; +- +- proto_item *list_ti = proto_tree_add_string_format(tree, hf_nfapi_harq_ack_nack_data, tvb, *offset, 2, "", "ACK/NACK Data"); +- proto_tree *list_tree = proto_item_add_subtree(list_ti, ett_nfapi_harq_ack_nack_data); +- +- for (i = 0; i < count; ++i) +- { +- proto_item *item_ti = proto_tree_add_string_format(list_tree, hf_nfapi_harq_ack_nack_data, tvb, *offset, 2, "", "[%d]", i); +- proto_tree *item_tree = proto_item_add_subtree(item_ti, ett_nfapi_harq_ack_nack_data); +- +- switch (mode) +- { +- case 0: +- { +- dissect_harq_indication_data_bundling_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 1: +- { +- dissect_harq_indication_data_multplexing_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 2: +- { +- dissect_harq_indication_data_special_bundling_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 3: +- { +- dissect_harq_indication_data_channel_selection_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 4: +- { +- dissect_harq_indication_data_format_3_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 5: +- { +- dissect_harq_indication_data_format_4_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- case 6: +- { +- dissect_harq_indication_data_format_5_value(tvb, pinfo, item_tree, data, offset, end); +- break; +- } +- }; +- } +- +- return 0; +-} +-static int dissect_harq_indication_rel8_fdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_tb_1, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_harq_tb_2, tvb, offset, 0); +- return 0; +-} +- +-int dissect_harq_tb_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_harq_tb_n, tvb, offset, 0); +- return 0; +-} +- +- +-static int dissect_harq_indication_rel9_later_fdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_mode, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_ack_nack, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "HARQ TB List", hf_nfapi_harq_data, ett_nfapi_harq_data, count, dissect_harq_tb_value); +- return 0; +-} +-static int dissect_harq_indication_rel13_later_fdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_harq_mode, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_ack_nack, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "HARQ TB List", hf_nfapi_harq_data, ett_nfapi_harq_data, count, dissect_harq_tb_value); +- return 0; +-} +-static int dissect_ul_cqi_information_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ul_cqi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_channel, tvb, offset, 0); +- return 0; +-} +-static int dissect_crc_indication_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_crc_flag, tvb, offset, 0); +- return 0; +-} +-static int dissect_rx_cqi_indication_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_data_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_cqi, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ri, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance, tvb, offset, 0); +- return 0; +-} +- +-int dissect_ri_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_ri, tvb, offset, 0); +- return 0; +-} +-static int dissect_rx_cqi_indication_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_data_offset, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_ul_cqi, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_cc_reported, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "CC List", hf_nfapi_cc, ett_nfapi_cc, count, dissect_ri_value); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance_r9, tvb, offset, 0); +- +- return 0; +-} +-static int dissect_rach_indication_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_rnti, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_preamble, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance, tvb, offset, 0); +- return 0; +-} +-static int dissect_rach_indication_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance_r9, tvb, offset, 0); +- return 0; +-} +-static int dissect_rach_indication_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_rach_resource_type, tvb, offset, 0); +- return 0; +-} +- +-int dissect_snr_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_snr, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_srs_indication_rel8_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_doppler_estimation, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance, tvb, offset, 0); +- guint8 count = proto_tree_add_uint8(tree, hf_nfapi_number_of_resource_blocks, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rb_start, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "RB List", hf_nfapi_rbs, ett_nfapi_rbs, count, dissect_snr_value); +- +- +- return 0; +-} +-static int dissect_srs_indication_rel9_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_timing_advance_r9, tvb, offset, 0); +- return 0; +-} +-static int dissect_srs_indication_rel10_tdd_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_up_pts_symbol, tvb, offset, 0); +- return 0; +-} +-static int dissect_tdd_channel_measuerment_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_prb_per_subband, tvb, offset, 0); +- guint8 num_subbands = proto_tree_add_uint8(tree, hf_nfapi_number_of_subbands, tvb, offset, 0); +- guint8 num_phy_ant = proto_tree_add_uint8(tree, hf_nfapi_number_antennas, tvb, offset, 0); +- +- guint16 i = 0; +- guint16 j = 0; +- +- proto_item *sb_list_ti = proto_tree_add_string_format(tree, hf_nfapi_subbands, tvb, *offset, 2, "", "Subbands"); +- proto_tree *sb_list_tree = proto_item_add_subtree(sb_list_ti, ett_nfapi_subbands); +- +- for (i = 0; i < num_subbands; ++i) +- { +- proto_item *sb_item_ti = proto_tree_add_string_format(sb_list_tree, hf_nfapi_subbands, tvb, *offset, 2, "", "[%d]", i); +- proto_tree *sb_item_tree = proto_item_add_subtree(sb_item_ti, ett_nfapi_subbands); +- +- proto_tree_add_uint8(sb_item_ti, hf_nfapi_subband_index, tvb, offset, 0); +- +- +- proto_item *ant_list_ti = proto_tree_add_string_format(sb_item_tree, hf_nfapi_antennas, tvb, *offset, 2, "", "Physical Antennas"); +- proto_tree *ant_list_tree = proto_item_add_subtree(ant_list_ti, ett_nfapi_antennas); +- +- for (j = 0; j < num_phy_ant; ++j) +- { +- proto_item *ant_item_ti = proto_tree_add_string_format(ant_list_tree, hf_nfapi_antennas, tvb, *offset, 2, "", "[%d]", j); +- proto_tree *ant_item_tree = proto_item_add_subtree(ant_item_ti, ett_nfapi_antennas); +- +- proto_tree_add_uint16(ant_item_tree, hf_nfapi_channel_coefficient, tvb, offset, 0); +- } +- } +- +- return 0; +-} +- +-static int dissect_srs_indication_rel11_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_ul_rtoa, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_lbt_dl_config_request_pdsch_req_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_mp_cca, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_n_cca, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_offset, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_lte_txop_sf, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_txop_sfn_sf_end, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_lbt_mode, tvb, offset, 0); +- return 0; +-} +-static int dissect_lbt_dl_config_request_drs_req_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_offset, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_sfn_sf_end, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_lbt_mode, tvb, offset, 0); +- return 0; +-} +-static int dissect_lbt_dl_config_request_pdsch_resp_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_result, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_txop_symbols, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_initial_partial_sf, tvb, offset, 0); +- return 0; +-} +-static int dissect_lbt_dl_config_request_drs_resp_rel13_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_handle, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_result, tvb, offset, 0); +- return 0; +-} +- +-int dissect_tx_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 len = proto_tree_add_uint16(tree, hf_nfapi_pdu_length, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pdu_index, tvb, offset, 0); +- +- proto_tree_add_uint8_array(tree, hf_nfapi_pdu, len, tvb, offset); +- +- return 0; +-} +- +-static int dissect_tx_request_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "TX PDU List", hf_nfapi_tx_request_pdu_list, ett_nfapi_tx_request_pdu_list, num_pdu, dissect_tx_pdu); +- return 0; +- +-} +- +-int dissect_rx_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- //guint end = (*offset + size - 2); +- //dissect_tlv_list(tvb, pinfo, tree, data, offset, end); +- return 0; +-} +- +- +- +-int dissect_harq_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +- +-static int dissect_harq_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_of_harqs, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "HARQ PDU List", hf_nfapi_harq_indication_pdu_list, ett_nfapi_harq_indication_pdu_list, num_pdu, dissect_harq_indication_pdu); +- return 0; +-} +- +-int dissect_crc_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +- +- +-static int dissect_crc_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_of_crcs, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "CRC PDU List", hf_nfapi_crc_indication_pdu_list, ett_nfapi_crc_indication_pdu_list, num_pdu, dissect_crc_indication_pdu); +- return 0; +-} +-int dissect_sr_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +- +-static int dissect_rx_sr_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_of_srs, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "SR PDU List", hf_nfapi_sr_indication_pdu_list, ett_nfapi_sr_indication_pdu_list, num_pdu, dissect_sr_indication_pdu); +- return 0; +-} +-int dissect_cqi_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +-static int dissect_rx_cqi_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_of_cqi, tvb, offset, 0); +- +- guint16* lengths = malloc(num_pdu * 2); +- memset(lengths, 0, num_pdu * 2); +- +- guint8 tmp_offset = *offset; +- +- int i = 0; +- for (i = 0; i < num_pdu; ++i) +- { +- guint16 instance_len = tvb_get_guint16(tvb, tmp_offset, ENC_NA); +- tmp_offset += 2; +- guint8 pdu_end = tmp_offset + instance_len; +- +- while (tmp_offset < pdu_end) +- { +- guint16 tlv_id = tvb_get_guint16(tvb, tmp_offset, ENC_NA); +- tmp_offset += 2; +- guint16 tlv_len = tvb_get_guint16(tvb, tmp_offset, ENC_NA); +- tmp_offset += 2; +- +- if (tlv_id == 0x202F) +- { +- lengths[i] = tvb_get_guint16(tvb, tmp_offset, ENC_NA); +- } +- else if (tlv_id == 0x2030) +- { +- lengths[i] = tvb_get_guint16(tvb, tmp_offset, ENC_NA); +- } +- +- tmp_offset += tlv_len; +- } +- +- } +- +- +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "CQI PDU List", hf_nfapi_cqi_indication_pdu_list, ett_nfapi_cqi_indication_pdu_list, num_pdu, dissect_cqi_indication_pdu); +- +- +- for (i = 0; i < num_pdu; ++i) +- { +- proto_tree_add_uint8_array(tree, hf_nfapi_pdu, lengths[i], tvb, offset); +- } +- +- free(lengths); +- +- return 0; +-} +-int dissect_preamble_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +-static int dissect_rach_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_pdu = proto_tree_add_uint16(tree, hf_nfapi_number_of_preambles, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Preamble PDU List", hf_nfapi_preamble_indication_pdu_list, ett_nfapi_preamble_indication_pdu_list, num_pdu, dissect_preamble_indication_pdu); +- return 0; +-} +-int dissect_srs_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 pdu_len = proto_tree_add_uint16(tree, hf_nfapi_instance_length, tvb, offset, 0); +- guint pdu_end = (*offset + pdu_len - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +-static int dissect_srs_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- +- guint8 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_of_srss, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "SRS PDU List", hf_nfapi_srs_indication_pdu_list, ett_nfapi_srs_indication_pdu_list, num_pdu, dissect_srs_indication_pdu); +- return 0; +-} +-int dissect_lbt_dl_config_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_lbt_dl_req_pdu_type, tvb, offset, 0); +- guint8 size = proto_tree_add_uint8(tree, hf_nfapi_pdu_size, tvb, offset, 0); +- guint pdu_end = (*offset + size - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +-static int dissect_lbt_dl_config_request_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "LBT DL PDU List", hf_nfapi_lbt_dl_config_pdu_list, ett_nfapi_lbt_dl_config_pdu_list, num_pdu, dissect_lbt_dl_config_pdu); +- +- return 0; +-} +-int dissect_lbt_dl_indication_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_lbt_dl_ind_pdu_type, tvb, offset, 0); +- guint8 size = proto_tree_add_uint8(tree, hf_nfapi_pdu_size, tvb, offset, 0); +- guint pdu_end = (*offset + size - 2); +- dissect_tlv_list(tvb, pinfo, tree, data, offset, pdu_end); +- return 0; +-} +-static int dissect_lbt_indication_message_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint8 num_pdu = proto_tree_add_uint8(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "LBT DL PDU List", hf_nfapi_lbt_dl_indication_pdu_list, ett_nfapi_lbt_dl_indication_pdu_list, num_pdu, dissect_lbt_dl_indication_pdu); +- return 0; +-} +- +-static int dissect_lte_rssi_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_frequency_band_indicator, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_measurement_period, tvb, offset, "ms"); +- proto_tree_add_uint8(tree, hf_nfapi_bandwidth, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_earfcns = proto_tree_add_uint8(tree, hf_nfapi_number_of_earfcns, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "EARFCNs", hf_nfapi_earfcn_list, ett_nfapi_earfcn_list, num_earfcns, dissect_earfcn_value); +- return 0; +-} +- +-int dissect_uarfcn_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_uarfcn, tvb, offset, 0); +- return 0; +-} +-static int dissect_utran_rssi_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_frequency_band_indicator, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_measurement_period, tvb, offset, "ms"); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_uarfcns = proto_tree_add_uint8(tree, hf_nfapi_number_of_uarfcns, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "UARFCNs", hf_nfapi_uarfcn_list, ett_nfapi_uarfcn_list, num_uarfcns, dissect_uarfcn_value); +- return 0; +-} +- +-int dissect_arfcn_dir_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_arfcn, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_arfcn_direction, tvb, offset, 0); +- return 0; +-} +-static int dissect_geran_rssi_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_frequency_band_indicator, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_measurement_period, tvb, offset, "ms"); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_arfcns = proto_tree_add_uint8(tree, hf_nfapi_number_of_arfcns, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "ARFCNs", hf_nfapi_arfcn_list, ett_nfapi_arfcn_list, num_arfcns, dissect_arfcn_dir_value); +- return 0; +-} +- +- +-int rssi_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, gint16 value) +-{ +- proto_tree_add_int_format_value(tree, hfindex, tvb, *offset, 2, value, "%.2f dB (%d)", ((float)value * 0.1), value); +- return 0; +-} +-int dissect_rssi_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_int16_with_conversion(tree, hf_nfapi_rssi, tvb, offset, rssi_conversion); +- return 0; +-} +-static int dissect_rssi_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_rssi = proto_tree_add_uint16(tree, hf_nfapi_number_of_rssi, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "ARFCNs", hf_nfapi_rssi_list, ett_nfapi_rssi_list, num_rssi, dissect_rssi_value); +- return 0; +-} +- +-int dissect_pci_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pci, tvb, offset, 0); +- return 0; +-} +-static int dissect_lte_cell_search_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_earfcn, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_measurement_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_exhaustive_search, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_pci = proto_tree_add_uint8(tree, hf_nfapi_number_of_pci, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PCIs", hf_nfapi_pci_list, ett_nfapi_pci_list, num_pci, dissect_pci_value); +- return 0; +-} +- +-int dissect_psc_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_psc, tvb, offset, 0); +- return 0; +-} +-static int dissect_utran_cell_search_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_uarfcn, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_exhaustive_search, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_psc = proto_tree_add_uint8(tree, hf_nfapi_number_of_psc, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "PSCs", hf_nfapi_psc_list, ett_nfapi_psc_list, num_psc, dissect_psc_value); +- return 0; +-} +- +-int dissect_arfcn_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_arfcn, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_geran_cell_search_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- guint8 num_arfcn = proto_tree_add_uint8(tree, hf_nfapi_number_of_arfcns, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "ARFCNs", hf_nfapi_arfcn_list, ett_nfapi_arfcn_list, num_arfcn, dissect_arfcn_value); +- return 0; +-} +- +-int neg_pow_conversion(proto_item* tree, int hfindex, tvbuff_t *tvb, guint* offset, guint8 value) +-{ +- proto_tree_add_uint_format_value(tree, hfindex, tvb, *offset, 1, value, "%d dB (%d)", ((gint16)value * (-1)), value); +- return 0; +-} +- +-int dissect_lte_cell_found_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_pci, tvb, offset, 0); +- proto_tree_add_uint8_with_conversion(tree, hf_nfapi_rsrp, tvb, offset, neg_pow_conversion); +- proto_tree_add_uint8_with_conversion(tree, hf_nfapi_rsrq, tvb, offset, neg_pow_conversion); +- proto_tree_add_int16(tree, hf_nfapi_frequency_offset, tvb, offset, 0); +- return 0; +-} +-static int dissect_lte_cell_search_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_lte_cells = proto_tree_add_uint16(tree, hf_nfapi_number_of_lte_cells_found, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "LTE Cells Found", hf_nfapi_lte_cells_found_list, ett_nfapi_lte_cells_found_list, num_lte_cells, dissect_lte_cell_found_value); +- return 0; +-} +-int dissect_utran_cell_found_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_psc, tvb, offset, 0); +- proto_tree_add_uint8_with_conversion(tree, hf_nfapi_rscp, tvb, offset, neg_pow_conversion); +- proto_tree_add_uint8_with_conversion(tree, hf_nfapi_enco, tvb, offset, neg_pow_conversion); +- proto_tree_add_int16(tree, hf_nfapi_frequency_offset, tvb, offset, 0); +- return 0; +-} +-static int dissect_utran_cell_search_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_utran_cells = proto_tree_add_uint16(tree, hf_nfapi_number_of_utran_cells_found, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "UTRAN Cells Found", hf_nfapi_utran_cells_found_list, ett_nfapi_utran_cells_found_list, num_utran_cells, dissect_utran_cell_found_value); +- return 0; +-} +- +-int dissect_geran_cell_found_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_arfcn, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_bsic, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rxlev, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_rxqual, tvb, offset, 0); +- proto_tree_add_int16(tree, hf_nfapi_frequency_offset, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_sfn_offset, tvb, offset, 0); +- return 0; +-} +-static int dissect_geran_cell_search_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 num_geran_cells = proto_tree_add_uint16(tree, hf_nfapi_number_of_geran_cells_found, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "GERAN Cells Found", hf_nfapi_geran_cells_found_list, ett_nfapi_geran_cells_found_list, num_geran_cells, dissect_geran_cell_found_value); +- +- return 0; +-} +-static int dissect_pnf_cell_search_state_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_pnf_search_state, *end - *offset, tvb, offset); +- return 0; +-} +- +-static int dissect_pnf_cell_broadcast_state_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8_array(tree, hf_nfapi_pnf_broadcast_state, *end - *offset, tvb, offset); +- return 0; +-} +-static int dissect_lte_broadcast_detect_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_earfcn, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pci, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- return 0; +-} +-static int dissect_utran_broadcast_detect_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_uarfcn, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_psc, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, "ms"); +- return 0; +-} +- +-static int dissect_lte_broadcast_detect_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_number_of_tx_antenna, tvb, offset, 0); +- guint16 mib_len = proto_tree_add_uint16(tree, hf_nfapi_mib_length, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_mib, mib_len, tvb, offset); +- proto_tree_add_uint32(tree, hf_nfapi_sfn_offset, tvb, offset, 0); +- return 0; +-} +-static int dissect_utran_broadcast_detect_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 mib_len = proto_tree_add_uint16(tree, hf_nfapi_mib_length, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_mib, mib_len, tvb, offset); +- proto_tree_add_uint32(tree, hf_nfapi_sfn_offset, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_lte_system_information_schedule_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_earfcn, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pci, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_downlink_channel_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_phich_configuration, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_tx_antenna, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_retry_count, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, 0); +- return 0; +-} +-//static int dissect_pnf_cell_broadcast_state_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-//{ +-// return 0; +-//} +-static int dissect_lte_system_information_schedule_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- // this needs to be SIB 1 +- proto_tree_add_uint8_array(tree, hf_nfapi_sib1, (*end - *offset), tvb, offset); +- return 0; +-} +- +-int dissect_si_periodicity_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_si_periodicity, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_si_index, tvb, offset, 0); +- return 0; +-} +- +-static int dissect_lte_system_information_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_earfcn, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_pci, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_downlink_channel_bandwidth, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_phich_configuration, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_number_of_tx_antenna, tvb, offset, 0); +- guint8 si_priodicity = proto_tree_add_uint8(tree, hf_nfapi_number_of_si_periodicity, tvb, offset, 0); +- dissect_array_value(tvb, pinfo, tree, data, offset, end, "Number SI Periodicity", hf_nfapi_si_periodicity_list, ett_nfapi_si_periodicity_list, si_priodicity, dissect_si_periodicity_value); +- proto_tree_add_uint8(tree, hf_nfapi_si_window_length, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, 0); +- +- return 0; +-} +-static int dissect_utran_system_information_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_uarfcn, tvb, offset, 0); +- proto_tree_add_uint16(tree, hf_nfapi_psc, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, 0); +- return 0; +-} +-static int dissect_geran_system_information_request_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint16(tree, hf_nfapi_arfcn, tvb, offset, 0); +- proto_tree_add_uint8(tree, hf_nfapi_bsic, tvb, offset, 0); +- proto_tree_add_uint32(tree, hf_nfapi_timeout, tvb, offset, 0); +- return 0; +-} +-//static int dissect_pnf_cell_broadcast_state_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-//{ +-// return 0; +-//} +-static int dissect_lte_system_information_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- proto_tree_add_uint8(tree, hf_nfapi_sib_type, tvb, offset, 0); +- guint16 sib_len = proto_tree_add_uint16(tree, hf_nfapi_sib_len, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_sib, sib_len, tvb, offset); +- return 0; +-} +-static int dissect_utran_system_information_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 sib_len = proto_tree_add_uint16(tree, hf_nfapi_sib_len, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_sib, sib_len, tvb, offset); +- return 0; +-} +-static int dissect_geran_system_information_indication_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint16 si_len = proto_tree_add_uint16(tree, hf_nfapi_si_len, tvb, offset, 0); +- proto_tree_add_uint8_array(tree, hf_nfapi_si, si_len, tvb, offset); +- return 0; +-} +- +-static int dissect_rx_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end); +- +-const tlv_t tags[] = +-{ +- { 0x1000, "PNF Param General", dissect_pnf_param_general_value }, +- { 0x1001, "PNF PHY", dissect_pnf_phy_value }, +- { 0x1002, "PNF RF", dissect_pnf_rf_value }, +- { 0x100A, "PNF PHY Rel 10", dissect_pnf_phy_rel10_value }, +- { 0x100B, "PNF PHY Rel 11", dissect_pnf_phy_rel11_value }, +- { 0x100C, "PNF PHY Rel 12", dissect_pnf_phy_rel12_value }, +- { 0x100D, "PNF PHY Rel 13", dissect_pnf_phy_rel13_value }, +- { 0x1003, "PNF PHY RF Config", dissect_pnf_phy_rf_config_value }, +- +- { 0x0001, "Subframe config - Duplex Mode", dissect_duplex_mode_value }, +- { 0x0002, "Subframe config - PCFICH power offset TLV", dissect_pcfich_power_offset_value }, +- { 0x0003, "Subframe config - P-B", dissect_pb_value }, +- { 0x0004, "Subframe config - DL cyclic prefix type", dissect_dl_cyclic_prefix_value }, +- { 0x0005, "Subframe config - UL cyclic prefix type", dissect_ul_cyclic_prefix_value }, +- { 0x000A, "RF config - Downlink channel bandwidth", dissect_dl_channel_bandwidth_value }, +- { 0x000B, "RF config - Uplink channel bandwidth", dissect_ul_channel_bandwidth_value }, +- { 0x000C, "RF config - Reference signal power", dissect_reference_signal_power_value }, +- { 0x000D, "RF config - Tx antenna ports", dissect_tx_antenna_ports_value }, +- { 0x000E, "RF config - Rx Antenna ports", dissect_rx_antenna_ports_value }, +- { 0x0014, "PHICH config - PHICH resource", dissect_phich_resource_value }, +- { 0x0015, "PHICH config - PHICH duration", dissect_phich_duration_value }, +- { 0x0016, "PHICH config - PHICH power offset", dissect_phich_power_offset_value }, +- { 0x001E, "SCH config - Primary synchronization signal EPRE/EPRERS", dissect_psch_synch_signal_epre_eprers_value }, +- { 0x001F, "SCH config - Secondary synchronization signal EPRE/EPRERS", dissect_ssch_synch_signal_epre_eprers_value }, +- { 0x0020, "SCH config - Physical Cell Id", dissect_physical_cell_id_value }, +- { 0x0028, "PRACH config - Configuration index", dissect_prach_configuration_index_value }, +- { 0x0029, "PRACH config - Root sequence index", dissect_prach_root_sequence_index_value }, +- { 0x002A, "PRACH config - Zero correlation zone configuration", dissect_prach_zero_correlation_zone_configuration_value }, +- { 0x002B, "PRACH config - High speed flag", dissect_prach_high_speed_flag_value }, +- { 0x002C, "PRACH config - Frequency offset", dissect_prach_frequency_offset_value }, +- { 0x0032, "PUSCH config - Hopping mode", dissect_pusch_hopping_mode_value }, +- { 0x0033, "PUSCH config - Hopping offset", dissect_pusch_hopping_offset_value }, +- { 0x0034, "PUSCH config - Number of sub-bands", dissect_pusch_number_of_subbands_value }, +- { 0x003C, "PUCCH config - Delta PUCCH Shift", dissect_pucch_delta_pucch_shift_value }, +- { 0x003D, "PUCCH config - N_CQI RB", dissect_pucch_n_cqi_rb_value }, +- { 0x003E, "PUCCH config - N_AN CS", dissect_pucch_n_an_cs_value }, +- { 0x003F, "PUCCH config - N1Pucch-AN", dissect_pucch_n1_pucch_an_value }, +- { 0x0046, "SRS config - Bandwidth configuration", dissect_srs_bandwidth_configuration_value }, +- { 0x0047, "SRS config - MaxUpPTS", dissect_srs_max_uppts_value }, +- { 0x0048, "SRS config - SRS subframe configuration", dissect_srs_subframe_configuration_value }, +- { 0x0049, "SRS config - SRS AckNack SRS simultaneous transmission", dissect_srs_acknack_srs_sim_tx_value }, +- { 0x0050, "Uplink reference signal config - Uplink RS hopping", dissect_uplink_rs_hopping_value }, +- { 0x0051, "Uplink reference signal config - Group assignment (delta sequence-shift pattern)", dissect_group_assignment_value }, +- { 0x0052, "Uplink reference signal config - Cyclic Shift 1 for DMRS", dissect_cyclic_shift_1_for_drms_value }, +- { 0x005A, "TDD frame structure config - Subframe assignment", dissect_tdd_subframe_assignement_value }, +- { 0x005B, "TDD frame structure config - Special sub-frame patterns", dissect_tdd_subframe_patterns_value }, +- { 0x0064, "LAA config - ED Threshold for LBT for PDSCH", dissect_laa_ed_threashold_for_lbt_for_pdsch_value }, +- { 0x0065, "LAA config - ED Threshold for LBT for DRS", dissect_laa_ed_threashold_for_lbt_for_drs_value }, +- { 0x0066, "LAA config - PD Threshold", dissect_laa_pd_threshold_value }, +- { 0x0067, "LAA config - Multi carrier type", dissect_laa_multi_carrier_type_value }, +- { 0x0068, "LAA config - Multi carrier TX", dissect_laa_multi_carrier_tx_value }, +- { 0x0069, "LAA config - Multi carrier freeze ", dissect_laa_multi_carrier_freeze_value }, +- { 0x006A, "LAA config - Tx antenna ports for DRS", dissect_laa_tx_antenna_port_for_drs_value }, +- { 0x006B, "LAA config - Transmission power for DRS", dissect_laa_transmission_power_for_drs_value }, +- +- { 0x0078, "eMTC config - PBCH Repetitions enable R13", dissect_emtc_pbch_repeitions_enabled_r13_value }, +- { 0x0079, "eMTC config - PRACH CAT-M Root sequence index", dissect_emtc_prach_cat_m_root_sequence_index_value }, +- { 0x007A, "eMTC config - PRACH CAT-M Zero correlation zone configuration", dissect_emtc_prach_cat_m_zero_correlation_zone_configuration_value }, +- { 0x007B, "eMTC config - PRACH CAT-M High speed flag", dissect_emtc_prach_cat_m_high_speed_flag_value }, +- { 0x007C, "eMTC config - PRACH CE level #0 Enable", dissect_emtc_prach_ce_level_0_enabled_value }, +- { 0x007D, "eMTC config - PRACH CE level #0 Configuration index", dissect_emtc_prach_ce_level_0_configuration_offset_value }, +- { 0x007E, "eMTC config - PRACH CE level #0 Frequency offset", dissect_emtc_prach_ce_level_0_frequency_offset_value }, +- { 0x007F, "eMTC config - PRACH CE level #0 Number of repetitions per attempt", dissect_emtc_preach_ce_level_0_num_of_repeitions_per_attempt_value }, +- { 0x0080, "eMTC config - CE level #0 Starting subframe periodicity", dissect_emtc_ce_level_0_starting_subframe_periodicity_value }, +- { 0x0081, "eMTC config - PRACH CE level #0 Hopping Enable", dissect_emtc_preach_ce_level_0_hopping_enabled_value }, +- { 0x0082, "eMTC config - PRACH CE level #0 Hopping Offset", dissect_emtc_preach_ce_level_0_hopping_offset_value }, +- { 0x0083, "eMTC config - PRACH CE level #1 Enable", dissect_emtc_prach_ce_level_1_enabled_value }, +- { 0x0084, "eMTC config - PRACH CE level #1 Configuration index", dissect_emtc_prach_ce_level_1_configuration_offset_value }, +- { 0x0085, "eMTC config - PRACH CE level #1 Frequency offset", dissect_emtc_prach_ce_level_1_frequency_offset_value }, +- { 0x0086, "eMTC config - PRACH CE level #1 Number of repetitions per attempt", dissect_emtc_preach_ce_level_1_num_of_repeitions_per_attempt_value }, +- { 0x0087, "eMTC config - CE level #1 Starting subframe periodicity", dissect_emtc_ce_level_1_starting_subframe_periodicity_value }, +- { 0x0088, "eMTC config - PRACH CE level #1 Hopping Enable", dissect_emtc_preach_ce_level_1_hopping_enabled_value }, +- { 0x0089, "eMTC config - PRACH CE level #1 Hopping Offset", dissect_emtc_preach_ce_level_1_hopping_offset_value }, +- { 0x008A, "eMTC config - PRACH CE level #2 Enable", dissect_emtc_prach_ce_level_2_enabled_value }, +- { 0x008B, "eMTC config - PRACH CE level #2 Configuration index", dissect_emtc_prach_ce_level_2_configuration_offset_value }, +- { 0x008C, "eMTC config - PRACH CE level #2 Frequency offset", dissect_emtc_prach_ce_level_2_frequency_offset_value }, +- { 0x008D, "eMTC config - PRACH CE level #2 Number of repetitions per attempt", dissect_emtc_preach_ce_level_2_num_of_repeitions_per_attempt_value }, +- { 0x008E, "eMTC config - CE level #2 Starting subframe periodicity", dissect_emtc_ce_level_2_starting_subframe_periodicity_value }, +- { 0x008F, "eMTC config - PRACH CE level #2 Hopping Enable", dissect_emtc_preach_ce_level_2_hopping_enabled_value }, +- { 0x0090, "eMTC config - PRACH CE level #2 Hopping Offset", dissect_emtc_preach_ce_level_2_hopping_offset_value }, +- { 0x0091, "eMTC config - PRACH CE level #3 Enable", dissect_emtc_prach_ce_level_3_enabled_value }, +- { 0x0092, "eMTC config - PRACH CE level #3 Configuration index", dissect_emtc_prach_ce_level_3_configuration_offset_value }, +- { 0x0093, "eMTC config - PRACH CE level #3 Frequency offset", dissect_emtc_prach_ce_level_3_frequency_offset_value }, +- { 0x0094, "eMTC config - PRACH CE level #3 Number of repetitions per attempt", dissect_emtc_preach_ce_level_3_num_of_repeitions_per_attempt_value }, +- { 0x0095, "eMTC config - CE level #3 Starting subframe periodicity", dissect_emtc_ce_level_3_starting_subframe_periodicity_value }, +- { 0x0096, "eMTC config - PRACH CE level #3 Hopping Enable", dissect_emtc_preach_ce_level_3_hopping_enabled_value }, +- { 0x0097, "eMTC config - PRACH CE level #3 Hopping Offset", dissect_emtc_preach_ce_level_3_hopping_offset_value }, +- { 0x0098, "eMTC config - PUCCH Interval - ULHoppingConfigCommonModeA", dissect_emtc_pucch_interval_ul_hopping_config_common_mode_a_value }, +- { 0x0099, "eMTC config - PUCCH Interval - ULHoppingConfigCommonModeB", dissect_emtc_pucch_interval_ul_hopping_config_common_mode_b_value }, +- +- { 0x00C8, "Layer 2/3 - Downlink Bandwidth Support", dissect_dl_bandwidth_support_value }, +- { 0x00C9, "Layer 2/3 - Uplink Bandwidth Support", dissect_ul_bandwidth_support_value }, +- { 0x00CA, "Layer 2/3 - Downlink modulation support", dissect_dl_modulation_value }, +- { 0x00CB, "Layer 2/3 - Uplink modulation support", dissect_ul_modulation_value }, +- { 0x00CC, "Layer 2/3 - PHY antenna capability", dissect_phy_antenna_capability_value }, +- { 0x00CD, "Layer 2/3 - Release capability", dissect_release_capability_value }, +- { 0x00CE, "Layer 2/3 - MBSFN capability", dissect_mbsfn_value }, +- +- { 0x00D1, "LAA Capability - LAA support", dissect_laa_support_value }, +- { 0x00D1, "LAA Capability - PD sensing LBT support", dissect_laa_pd_sensing_lbt_support_value }, +- { 0x00D1, "LAA Capability - Multi carrier LBT support", dissect_laa_multi_carrier_lbt_support_value }, +- { 0x00D1, "LAA Capability - Partial SF support", dissect_laa_partial_sf_support_value }, +- +- { 0x00F0, "Layer 2/3 - Data report mode", dissect_data_report_mode_value }, +- { 0x00F1, "Layer 2/3 - SFN/SF", dissect_sfn_sf_value }, +- { 0x00FA, "Layer 1 - PHY state", dissect_phy_state_value }, +- +- { 0x0100, "NFAPI - P7 VNF Address IPv4", dissect_p7_vnf_address_ipv4_value }, +- { 0x0101, "NFAPI - P7 VNF Address IPv4", dissect_p7_vnf_address_ipv6_value }, +- { 0x0102, "NFAPI - P7 Port", dissect_p7_vnf_port_value }, +- { 0x0103, "NFAPI - P7 PNF Address IPv4", dissect_p7_pnf_address_ipv4_value }, +- { 0x0104, "NFAPI - P7 PNF Address IPv4", dissect_p7_pnf_address_ipv6_value }, +- { 0x0105, "NFAPI - P7 Port", dissect_p7_pnf_port_value }, +- { 0x010A, "NFAPI - Downlink UEs per Subframe", dissect_downlink_ues_per_subframe_value }, +- { 0x010B, "NFAPI - Uplink UEs per Subframe", dissect_uplink_ues_per_subframe_value }, +- +- { 0x0114, "NFAPI - nFAPI RF Bands", dissect_rf_bands_value }, +- +- { 0x011E, "NFAPI - Timing window", dissect_timing_window_value }, +- { 0x011F, "NFAPI - Timing info mode", dissect_timing_info_mode_value }, +- { 0x0120, "NFAPI - Timing info period", dissect_timing_info_period_value }, +- { 0x0128, "NFAPI - Maximum Transmit Power", dissect_maximum_transmit_power_value }, +- { 0x0129, "NFAPI - EARFCN", dissect_earfcn_value }, +- { 0x0130, "NFAPI - NMM GSM Frequency Bands", dissect_nmm_gsm_frequency_bands_value }, +- { 0x0131, "NFAPI - NMM UMTS Frequency Bands", dissect_nmm_umts_frequency_bands_value }, +- { 0x0132, "NFAPI - NMM LTE Frequency Bands", dissect_nmm_lte_frequency_bands_value }, +- { 0x0133, "NFAPI - NMM Uplink RSSI supported", dissect_nmm_uplink_rssi_supported_value }, +- +- { 0x2000, "DL Config Request Body", dissect_dl_config_request_body_value }, +- +- { 0x2001, "DL DCI PDU Release 8", dissect_dl_config_request_dl_dci_pdu_rel8_value }, +- { 0x2002, "DL DCI PDU Release 9", dissect_dl_config_request_dl_dci_pdu_rel9_value }, +- { 0x2003, "DL DCI PDU Release 10", dissect_dl_config_request_dl_dci_pdu_rel10_value }, +- { 0x2039, "DL DCI PDU Release 11", dissect_dl_config_request_dl_dci_pdu_rel11_value }, +- { 0x203A, "DL DCI PDU Release 12", dissect_dl_config_request_dl_dci_pdu_rel12_value }, +- { 0x203B, "DL DCI PDU Release 13", dissect_dl_config_request_dl_dci_pdu_rel13_value }, +- +- +- { 0x2004, "BCH PDU Release 8", dissect_dl_config_request_bch_pdu_rel8_value }, +- +- { 0x2005, "MCH PDU Release 8", dissect_dl_config_request_mch_pdu_rel8_value }, +- +- { 0x2006, "DLSCH PDU Release 8", dissect_dl_config_request_dlsch_pdu_rel8_value }, +- { 0x2007, "DLSCH PDU Release 9", dissect_dl_config_request_dlsch_pdu_rel9_value }, +- { 0x2008, "DLSCH PDU Release 10", dissect_dl_config_request_dlsch_pdu_rel10_value }, +- { 0x203C, "DLSCH PDU Release 11", dissect_dl_config_request_dlsch_pdu_rel11_value }, +- { 0x203D, "DLSCH PDU Release 12", dissect_dl_config_request_dlsch_pdu_rel12_value }, +- { 0x203E, "DLSCH PDU Release 13", dissect_dl_config_request_dlsch_pdu_rel13_value }, +- +- { 0x2009, "PCH PDU Release 8", dissect_dl_config_request_pch_pdu_rel8_value }, +- { 0x203F, "PCH PDU Release 13", dissect_dl_config_request_pch_pdu_rel13_value }, +- +- { 0x200A, "PRS PDU Release 9", dissect_dl_config_request_prs_pdu_rel9_value }, +- +- { 0x200B, "CSI-RS PDU Release 10", dissect_dl_config_request_csi_rs_pdu_rel10_value }, +- { 0x2040, "CSI-RS PDU Release 13", dissect_dl_config_request_csi_rs_pdu_rel13_value }, +- +- //{ 0x2001, "EDPCCH PDU Release 8", ?? }, +- //{ 0x2002, "EDPCCH PDU Release 8", ?? }, +- //{ 0x2003, "EDPCCH PDU Release 8", ?? }, +- //{ 0x2039, "EDPCCH PDU Release 11", ?? }, +- //{ 0x203A, "EDPCCH PDU Release 12", ?? }, +- //{ 0x203B, "EDPCCH PDU Release 13", ?? }, +- { 0x2041, "EDPCCH PDU Release 11 Parameters", dissect_dl_config_request_edpcch_params_rel11_value }, +- { 0x2042, "EDPCCH PDU Release 13 Parameters", dissect_dl_config_request_edpcch_params_rel13_value }, +- +- { 0x205B, "MPDCCH PDU Release 13", dissect_dl_config_request_mpdpcch_pdu_rel13_value }, +- +- +- { 0x200C, "UL Config Request Body", dissect_ul_config_request_body_value }, +- { 0x200D, "ULSCH PDU Release 8", dissect_ul_config_ulsch_pdu_rel8_value }, +- { 0x200E, "ULSCH PDU Release 10", dissect_ul_config_ulsch_pdu_rel10_value }, +- { 0x2043, "ULSCH PDU Release 11", dissect_ul_config_ulsch_pdu_rel11_value }, +- { 0x2044, "ULSCH PDU Release 13", dissect_ul_config_ulsch_pdu_rel13_value }, +- { 0x200F, "Initial Transmission Paramters Release 8", dissect_ul_config_init_tx_params_rel8_value }, +- { 0x2010, "CQI RI Information Release 8", dissect_ul_config_cqi_ri_info_rel8_value }, +- { 0x2011, "CQI RI Information Release 9 or later", dissect_ul_config_cqi_ri_info_rel9_later_value }, +- { 0x2045, "CQI RI Information Release 13", dissect_ul_config_cqi_ri_info_rel13_value }, +- { 0x2012, "HARQ Information (ULSCH) Release 10", dissect_ul_config_harq_info_ulsch_rel10_value }, +- { 0x2046, "HARQ Information (ULSCH) Release 13", dissect_ul_config_harq_info_ulsch_rel13_value }, +- { 0x2013, "UE Information Release 8", dissect_ul_config_ue_info_rel8_value }, +- { 0x2047, "UE Information Release 11", dissect_ul_config_ue_info_rel11_value }, +- { 0x2048, "UE Information Release 13", dissect_ul_config_ue_info_rel13_value }, +- { 0x2014, "CQI Information Release 8", dissect_ul_config_cqi_info_rel8_value }, +- { 0x2015, "CQI Information Release 10", dissect_ul_config_cqi_info_rel10_value }, +- { 0x2049, "CQI Information Release 13", dissect_ul_config_cqi_info_rel13_value }, +- { 0x2016, "SR Information Release 8", dissect_ul_config_sr_info_rel8_value }, +- { 0x2017, "SR Information Release 10", dissect_ul_config_sr_info_rel10_value }, +- { 0x2018, "HARQ Information (UCI) Release 10 TDD", dissect_ul_config_harq_info_uci_rel10_tdd_value }, +- { 0x2019, "HARQ Information (UCI) Release 8 FDD", dissect_ul_config_harq_info_uci_rel8_fdd_value }, +- { 0x201A, "HARQ Information (UCI) Release 9 or later FDD", dissect_ul_config_harq_info_uci_rel9_later_fdd_value }, +- { 0x204A, "HARQ Information (UCI) Release 11 FDD/TDD", dissect_ul_config_harq_info_uci_rel11_fdd_tdd_value }, +- { 0x204B, "HARQ Information (UCI) Release 13 FDD/TDD", dissect_ul_config_harq_info_uci_rel13_fdd_tdd_value }, +- { 0x201B, "SRS Information Release 8", dissect_ul_config_srs_info_rel8_value }, +- { 0x201C, "SRS Information Release 10", dissect_ul_config_srs_info_rel10_value }, +- { 0x204C, "SRS Information Release 13", dissect_ul_config_srs_info_rel13_value }, +- +- { 0x201D, "HI DCI0 Request Body", dissect_hi_dci0_request_body_value }, +- { 0x201E, "HI PDU Release 8", dissect_hi_dci0_hi_rel8_value }, +- { 0x201F, "HI PDU Release 10", dissect_hi_dci0_hi_rel10_value }, +- { 0x2020, "DCI UL PDU Release 8", dissect_hi_dci0_dci_ul_rel8_value }, +- { 0x2021, "DCI UL PDU Release 10", dissect_hi_dci0_dci_ul_rel10_value }, +- { 0x204D, "DCI UL PDU Release 12", dissect_hi_dci0_dci_ul_rel12_value }, +- //{ 0x2041, "EDPCCH DCI UL PDU Release 11", dissect_hi_dci0_edpcch_dci_ul_rel11_value }, +- { 0x204E, "MDPCCH DCI UL PDU Release 13", dissect_hi_dci0_mdpcch_dci_ul_rel13_value }, +- +- { 0x2022, "Tx Request Body", dissect_tx_request_body_value }, +- +- { 0x2038, "RX UE Information", dissect_rx_ue_info_value }, +- +- { 0x2023, "RX Indication Body", dissect_rx_indication_body_value }, +- { 0x2024, "RX PDU Release 8", dissect_rx_indication_rel8_value }, +- { 0x2025, "RX PDU Release 9", dissect_rx_indication_rel9_value }, +- +- { 0x2026, "HARQ Indication Body", dissect_harq_indication_body_value }, +- { 0x2027, "HARQ PDU Release 8 TDD", dissect_harq_indication_rel8_tdd_value }, +- { 0x2028, "HARQ PDU Release 9 or later TDD", dissect_harq_indication_rel9_later_tdd_value }, +- { 0x204F, "HARQ PDU Release 13 or later TDD", dissect_harq_indication_rel13_later_tdd_value }, +- { 0x2029, "HARQ PDU Release 8 FDD", dissect_harq_indication_rel8_fdd_value }, +- { 0x202A, "HARQ PDU Release 9 or later FDD", dissect_harq_indication_rel9_later_fdd_value }, +- { 0x2050, "HARQ PDU Release 13 or later FDD", dissect_harq_indication_rel13_later_fdd_value }, +- { 0x2052, "UL CQI Information", dissect_ul_cqi_information_value }, +- +- { 0x202B, "CRC Indication Body", dissect_crc_indication_body_value }, +- { 0x202C, "CRC PDU Release 8", dissect_crc_indication_rel8_value }, +- +- { 0x202D, "RX SR Indication Body", dissect_rx_sr_indication_body_value }, +- +- { 0x202E, "RX CQI Indication Body", dissect_rx_cqi_indication_body_value }, +- { 0x202F, "CQI PDU Release 8", dissect_rx_cqi_indication_rel8_value }, +- { 0x2030, "CQI PDU Release 9", dissect_rx_cqi_indication_rel9_value }, +- +- { 0x2031, "RACH Indication Body", dissect_rach_indication_body_value }, +- { 0x2032, "Preamable PDU Release 8", dissect_rach_indication_rel8_value }, +- { 0x2033, "Preamable PDU Release 9", dissect_rach_indication_rel9_value }, +- { 0x2051, "Preamable PDU Release 13", dissect_rach_indication_rel13_value }, +- +- { 0x2034, "SRS Indication Body", dissect_srs_indication_body_value }, +- { 0x2035, "SRS PDU Release 8", dissect_srs_indication_rel8_value }, +- { 0x2036, "SRS PDU Release 9", dissect_srs_indication_rel9_value }, +- { 0x2037, "SRS PDU Release 10 TDD", dissect_srs_indication_rel10_tdd_value }, +- { 0x2054, "TDD Channel Measurement", dissect_tdd_channel_measuerment_value }, +- { 0x2053, "SRS PDU Release 11", dissect_srs_indication_rel11_value }, +- +- +- { 0x2055, "LBT DL Config Request Body", dissect_lbt_dl_config_request_body_value }, +- { 0x2056, "LBT PDSCH Req PDU Release 13", dissect_lbt_dl_config_request_pdsch_req_rel13_value }, +- { 0x2057, "LBT DRS req PDU Release 13", dissect_lbt_dl_config_request_drs_req_rel13_value }, +- +- { 0x2058, "LBT DL Indication Message Body", dissect_lbt_indication_message_body_value }, +- { 0x2056, "LBT PDSCH Resp PDU Release 13", dissect_lbt_dl_config_request_pdsch_resp_rel13_value }, +- { 0x2057, "LBT DRS Resp PDU Release 13", dissect_lbt_dl_config_request_drs_resp_rel13_value }, +- +- { 0x3000, "LTE RSSI Request", dissect_lte_rssi_request_value }, +- { 0x3001, "UTRAN RSSI Request", dissect_utran_rssi_request_value }, +- { 0x3002, "GERAN RSSI Request", dissect_geran_rssi_request_value }, +- { 0x3003, "RSSI Indication", dissect_rssi_indication_value }, +- { 0x3004, "LTE CELL SEARCH Request", dissect_lte_cell_search_value }, +- { 0x3005, "UTRAN CELL SEARCH Request", dissect_utran_cell_search_value }, +- { 0x3006, "GERAN CELL SEARCH Request", dissect_geran_cell_search_value }, +- { 0x3007, "LTE CELL SEARCH Indication", dissect_lte_cell_search_indication_value }, +- { 0x3008, "UTRAN CELL SEARCH Indication", dissect_utran_cell_search_indication_value }, +- { 0x3009, "GERAN CELL SEARCH Indication", dissect_geran_cell_search_indication_value }, +- { 0x300a, "PNF CELL SEARCH STATE", dissect_pnf_cell_search_state_value }, +- { 0x300b, "LTE BROADCAST DETECT Request", dissect_lte_broadcast_detect_request_value }, +- { 0x300c, "UTRAN BROADCAST DETECT Request", dissect_utran_broadcast_detect_request_value }, +- { 0x300d, "PNF CELL SEARCH STATE", dissect_pnf_cell_search_state_value }, +- { 0x300e, "LTE BROADCAST DETECT Indication", dissect_lte_broadcast_detect_indication_value }, +- { 0x300f, "UTRAN BROADCAST DETECT Indication", dissect_utran_broadcast_detect_indication_value }, +- { 0x3010, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, +- { 0x3011, "LTE SYSTEM INFORMATION SCHEDULE Request", dissect_lte_system_information_schedule_request_value }, +- { 0x3012, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, +- { 0x3013, "LTE SYSTEM INFORMATION SCHEDULE Indication", dissect_lte_system_information_schedule_indication_value }, +- { 0x3014, "LTE SYSTEM INFORMATION Request", dissect_lte_system_information_request_value }, +- { 0x3015, "UTRAN SYSTEM INFORMATION Request", dissect_utran_system_information_request_value }, +- { 0x3016, "GERAN SYSTEM INFORMATION Request", dissect_geran_system_information_request_value }, +- { 0x3017, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, +- { 0x3018, "LTE SYSTEM INFORMATION Indication", dissect_lte_system_information_indication_value }, +- { 0x3019, "UTRAN SYSTEM INFORMATION Indication", dissect_utran_system_information_indication_value }, +- { 0x301a, "GERAN SYSTEM INFORMATION Indication", dissect_geran_system_information_indication_value }, +- +- +- +- +-}; +- +-int look_up_tlv(int tag_id) +-{ +- int i; +- int num_tags = sizeof(tags) / sizeof(tlv_t); +- +- for (i = 0; i < num_tags; i++) +- { +- if (tag_id == tags[i].tag_id) +- return i; +- } +- return -1; +-} +- +-static int dissect_tl_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset) +-{ +- proto_item *tl_ti = proto_tree_add_string_format(tree, hf_nfapi_tl, tvb, *offset, 4, "", "TL"); +- proto_tree *tl_tree = proto_item_add_subtree(tl_ti, ett_nfapi_tl); +- +- proto_tree_add_uint16(tl_tree, hf_nfapi_tl_tag, tvb, offset, 0); +- proto_tree_add_uint16(tl_tree, hf_nfapi_tl_length, tvb, offset, "bytes"); +- +- return 0; +- +-} +- +-static int dissect_tlv_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint len) +-{ +- while (*offset < len) +- { +- guint16 tlv_id = tvb_get_guint16(tvb, *offset, ENC_NA); +- guint16 tlv_len = tvb_get_guint16(tvb, *offset + 2, ENC_NA); +- +- int tlv_index = look_up_tlv(tlv_id); +- +- char* tlv_name = tlv_index != -1 ? tags[tlv_index].name : "Unknown"; +- +- proto_item *tlv_ti = proto_tree_add_string_format(tree, hf_nfapi_tlv_tree, tvb, *offset, tlv_len + 4, "", tlv_name); +- proto_tree *tlv_tree = proto_item_add_subtree(tlv_ti, ett_nfapi_tlv_tree); +- +- dissect_tl_header(tvb, pinfo, tlv_tree, data, offset); +- +- if (tags[tlv_index].decode != NULL) +- { +- guint tmp = *offset; +- guint end = *offset + tlv_len; +- tags[tlv_index].decode(tvb, pinfo, tlv_tree, data, &tmp, &end); +- *offset += tlv_len; +- } +- else +- { +- *offset += tlv_len; +- } +- } +- +- return 0; +-} +- +-static int dissect_rx_indication_body_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint* end) +-{ +- guint number_of_pdu_addr = *offset; +- guint16 count = proto_tree_add_uint16(tree, hf_nfapi_number_pdus, tvb, offset, 0); +- //dissect_array_value(tvb, pinfo, tree, data, offset, "RX PDU List", hf_nfapi_rx_indication_pdu_list, ett_nfapi_rx_indication_pdu_list, num_pdu, dissect_rx_pdu); +- +- guint16* lengths = malloc(count * 2); +- memset(lengths, 0, count * 2); +- +- guint16 i = 0; +- +- if (count > 0) +- { +- proto_item *list_ti = proto_tree_add_string_format(tree, hf_nfapi_rx_indication_pdu_list, tvb, *offset, 2, "", "RX PDU List"); +- proto_tree *list_tree = proto_item_add_subtree(list_ti, ett_nfapi_rx_indication_pdu_list); +- +- //for (i = 0; i < count; ++i) +- proto_tree *item_tree = 0; +- +- guint pdu_end = *end; +- while (*offset < *end && *offset < pdu_end) +- { +- +- guint16 tlv_id = tvb_get_guint16(tvb, *offset, ENC_NA); +- guint16 tlv_len = tvb_get_guint16(tvb, *offset + 2, ENC_NA); +- +- if (tlv_id == 0x2038) +- { +- proto_item *item_ti = proto_tree_add_string_format(list_tree, hf_nfapi_rx_indication_pdu_list, tvb, *offset, 2, "", "[%d]", i); +- item_tree = proto_item_add_subtree(item_ti, ett_nfapi_rx_indication_pdu_list); +- +- i++; +- } +- +- int tlv_index = look_up_tlv(tlv_id); +- +- char* tlv_name = tlv_index != -1 ? tags[tlv_index].name : "Unknown"; +- +- proto_item *tlv_ti = proto_tree_add_string_format(item_tree, hf_nfapi_tlv_tree, tvb, *offset, tlv_len + 4, "", tlv_name); +- proto_tree *tlv_tree = proto_item_add_subtree(tlv_ti, ett_nfapi_tlv_tree); +- +- +- +- +- dissect_tl_header(tvb, pinfo, tlv_tree, data, offset); +- +- guint tmp_offset = *offset; +- +- if (tlv_id == 0x2038) +- { +- dissect_rx_ue_info_value(tvb, pinfo, tlv_tree, data, &tmp_offset, end); +- } +- +- else if (tlv_id == 0x2024) +- { +- //int data_offset = dissect_rx_indication_rel8_value(tvb, pinfo, tlv_tree, data, &tmp_offset, end); +- +- lengths[i-1] = proto_tree_add_uint16(tlv_tree, hf_nfapi_length, tvb, &tmp_offset, 0); +- int data_offset = proto_tree_add_uint16(tlv_tree, hf_nfapi_data_offset, tvb, &tmp_offset, 0); +- proto_tree_add_uint8(tlv_tree, hf_nfapi_ul_cqi, tvb, &tmp_offset, 0); +- proto_tree_add_uint16(tlv_tree, hf_nfapi_timing_advance, tvb, &tmp_offset, 0); +- +- if ((data_offset > 0) && (pdu_end == *end)) +- { +- pdu_end = number_of_pdu_addr + data_offset; +- } +- +- } +- else if (tlv_id == 0x2025) +- { +- dissect_rx_indication_rel9_value(tvb, pinfo, tlv_tree, data, &tmp_offset, end); +- } +- +- +- *offset += tlv_len; +- } +- +- } +- +- for (i = 0; i < count; ++i) +- { +- proto_tree_add_uint8_array(tree, hf_nfapi_pdu, lengths[i], tvb, offset); +- } +- +- free(lengths); +- +- // more to follow here ?? +- return 0; +- +-} +- +- +-// ----------------------------------------------------------------------------| +- +- +-static int dissect_p45_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset) +-{ +- proto_item *p4_p5_header_ti = proto_tree_add_string_format(tree, hf_nfapi_p4_p5_message_header, tvb, *offset, NFAPI_HEADER_LENGTH, "", "P4 P5 Header"); +- proto_tree *p4_p5_header_tree = proto_item_add_subtree(p4_p5_header_ti, ett_nfapi_p4_p5_message_header); +- +- proto_tree_add_uint16(p4_p5_header_tree, hf_nfapi_p4_p5_message_header_phy_id, tvb, offset, 0); +- proto_tree_add_uint16(p4_p5_header_tree, hf_nfapi_p4_p5_message_header_message_id, tvb, offset, 0); +- proto_tree_add_uint16(p4_p5_header_tree, hf_nfapi_p4_p5_message_header_message_length, tvb, offset, 0); +- proto_tree_add_uint16(p4_p5_header_tree, hf_nfapi_p4_p5_message_header_spare, tvb, offset, 0); +- +- return 0; +-} +- +-static int dissect_p7_header_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset, guint8* m, guint8* seg, guint8* seq) +-{ +- proto_item *p7_header_ti = proto_tree_add_string_format(tree, hf_nfapi_p7_message_header, tvb, *offset, NFAPI_P7_HEADER_LENGTH, "", "P7 Header"); +- proto_tree *p7_header_tree = proto_item_add_subtree(p7_header_ti, ett_nfapi_p7_message_header); +- +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_phy_id, tvb, offset, 0); +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_message_id, tvb, offset, 0); +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_message_length, tvb, offset, "bytes"); +- +- // decoding bits for p7 header +- +- guint8 m_seg = tvb_get_guint8(tvb, *offset); +- *m = (m_seg & 0x80) >> 7; +- *seg = m_seg & 0x7F; +- +- +- proto_tree_add_bits_item(p7_header_tree, hf_nfapi_p7_message_header_m, tvb, (*offset) * 8, 1, ENC_NA); +- proto_tree_add_bits_item(p7_header_tree, hf_nfapi_p7_message_header_segment, tvb, ((*offset) * 8) + 1, 7, ENC_NA); +- *offset += 1; +- +- *seq = tvb_get_guint8(tvb, *offset); +- proto_tree_add_uint8(p7_header_tree, hf_nfapi_p7_message_header_sequence_number, tvb, offset, 0); +- +- +- proto_tree_add_uint32(p7_header_tree, hf_nfapi_p7_message_header_checksum, tvb, offset, 0); +- proto_tree_add_uint32(p7_header_tree, hf_nfapi_p7_message_header_transmit_timestamp, tvb, offset, "microseconds"); +- +- return 0; +- +-} +- +- +- +- +-static int dissect_p7_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, guint* offset) +-{ +- proto_item *p7_header_ti = proto_tree_add_string_format(tree, hf_nfapi_p7_message_header, tvb, *offset, NFAPI_P7_HEADER_LENGTH, "", "P7 Header"); +- proto_tree *p7_header_tree = proto_item_add_subtree(p7_header_ti, ett_nfapi_p7_message_header); +- +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_phy_id, tvb, offset, 0); +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_message_id, tvb, offset, 0); +- proto_tree_add_uint16(p7_header_tree, hf_nfapi_p7_message_header_message_length, tvb, offset, "bytes"); +- +- +- proto_tree_add_bits_item(p7_header_tree, hf_nfapi_p7_message_header_m, tvb, (*offset) * 8, 1, ENC_NA); +- proto_tree_add_bits_item(p7_header_tree, hf_nfapi_p7_message_header_segment, tvb, ((*offset) * 8) + 1, 7, ENC_NA); +- *offset += 1; +- +- proto_tree_add_uint8(p7_header_tree, hf_nfapi_p7_message_header_sequence_number, tvb, offset, 0); +- +- +- proto_tree_add_uint32(p7_header_tree, hf_nfapi_p7_message_header_checksum, tvb, offset, 0); +- proto_tree_add_uint32(p7_header_tree, hf_nfapi_p7_message_header_transmit_timestamp, tvb, offset, "microseconds"); +- +- return 0; +- +-} +- +-static reassembly_table ul_p7_reassemble_table; +-static reassembly_table dl_p7_reassemble_table; +- +- +- +-static int hf_msg_fragments = -1; +-static int hf_msg_fragment = -1; +-static int hf_msg_fragment_overlap = -1; +-static int hf_msg_fragment_overlap_conflicts = -1; +-static int hf_msg_fragment_multiple_tails = -1; +-static int hf_msg_fragment_too_long_fragment = -1; +-static int hf_msg_fragment_error = -1; +-static int hf_msg_fragment_count = -1; +-static int hf_msg_reassembled_in = -1; +-static int hf_msg_reassembled_length = -1; +-static int hf_msg_reassembled_data = -1; +-static gint ett_msg_fragment = -1; +-static gint ett_msg_fragments = -1; +- +-static const fragment_items msg_frag_items = { +- /* Fragment subtrees */ +- &ett_msg_fragment, +- &ett_msg_fragments, +- /* Fragment fields */ +- &hf_msg_fragments, +- &hf_msg_fragment, +- &hf_msg_fragment_overlap, +- &hf_msg_fragment_overlap_conflicts, +- &hf_msg_fragment_multiple_tails, +- &hf_msg_fragment_too_long_fragment, +- &hf_msg_fragment_error, +- &hf_msg_fragment_count, +- /* Reassembled in field */ +- &hf_msg_reassembled_in, +- /* Reassembled length field */ +- &hf_msg_reassembled_length, +- NULL, +- /* Tag */ +- "Message fragments" +-}; +- +-static int dissect_nfapi_ul_p7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +-{ +- guint8 m; +- guint8 seg; +- guint8 seq; +- guint offset = 0; +- +- guint16 msg_id = tvb_get_guint16(tvb, 2, ENC_NA); +- guint16 msg_len = tvb_get_guint16(tvb, 4, ENC_NA); +- +- dissect_p7_header_new(tvb, pinfo, tree, data, &offset, &m, &seg, &seq); +- +- guint8 save_fragmented = pinfo->fragmented; +- +- // not sure why I need to do this, but if I don't it does not reasses the protocol +- pinfo->fd->flags.visited = 0; +- +- if (m == 1 || (m == 0 && seg > 0)) +- { +- pinfo->fragmented = TRUE; +- +- fragment_head *fd_head = fragment_add_seq_check(&ul_p7_reassemble_table, tvb, offset, pinfo, seq, NULL, seg, msg_len - offset, (m == 1)); +- +- guint8 reassembled = 0; +- if (fd_head) +- { +- tvbuff_t * new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled UL P7", fd_head, &msg_frag_items, NULL, tree); +- +- if (new_tvb) +- { +- // set the tvb to the new reassembled buffer. +- tvb = new_tvb; +- reassembled = 1; +- col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Reassembled %d]", seg); +- +- // reset the offset for the new tvb +- offset = 0; +- } +- else +- { +- // Is this a failure to reassemble the data +- return 0; +- } +- } +- else +- { +- // this is a segement skip the body +- col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Segment %d]", seg); +- return 0; +- } +- } +- +- pinfo->fragmented = save_fragmented; +- +- { +- switch (msg_id) +- { +- //HARQ.indication +- case 0x85: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //CRC.indication +- case 0x86: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //RX_ULSCH.indication +- case 0x87: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //RACH.indication +- case 0x88: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //SRS.indication +- case 0x89: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //RX_SR.indication +- case 0x8A: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- //RX_CQI.indication +- case 0x8B: +- { +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- }; +- } +- +- return 0; +-} +- +-static int dissect_nfapi_dl_p7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +-{ +- guint8 m; +- guint8 seg; +- guint8 seq; +- guint offset = 0; +- +- guint16 msg_id = tvb_get_guint16(tvb, 2, ENC_NA); +- guint16 msg_len = tvb_get_guint16(tvb, 4, ENC_NA); +- +- dissect_p7_header_new(tvb, pinfo, tree, data, &offset, &m, &seg, &seq); +- +- guint8 save_fragmented = pinfo->fragmented; +- +- // not sure why I need to do this, but if I don't it does not reasses the protocol +- pinfo->fd->flags.visited = 0; +- +- if (m == 1 || (m == 0 && seg > 0)) +- { +- pinfo->fragmented = TRUE; +- +- fragment_head *fd_head = fragment_add_seq_check(&dl_p7_reassemble_table, tvb, offset, pinfo, seq, NULL, seg, msg_len - offset, (m == 1)); +- +- guint8 reassembled = 0; +- if (fd_head) +- { +- tvbuff_t * new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled DL P7", fd_head, &msg_frag_items, NULL, tree); +- +- if (new_tvb) +- { +- // set the tvb to the new reassembled buffer. +- tvb = new_tvb; +- reassembled = 1; +- col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Reassembled %d]", seg); +- +- // reset the offset for the new tvb +- offset = 0; +- } +- else +- { +- // Is this a failure to reassemble the data +- return 0; +- } +- } +- else +- { +- // this is a segement skip the body +- col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Segment %d]", seg); +- return 0; +- } +- } +- +- pinfo->fragmented = save_fragmented; +- +- { +- switch (msg_id) +- { +- // DL_CONFIG.request +- case 0x80: +- { +- //dissect_p7_header(tvb, pinfo, tree, data, &offset); +- proto_tree_add_uint16_with_conversion(tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- +- }; +- } +- +- return 0; +-} +- +- +-static int dissect_nfapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) +-{ +- col_set_str(pinfo->cinfo, COL_PROTOCOL, "NFAPI"); +- +- guint16 msg_id = tvb_get_guint16(tvb, 2, ENC_NA); +- guint16 msg_len = tvb_get_guint16(tvb, 4, ENC_NA); +- +- const gchar* message_str = val_to_str_const(msg_id, message_id_vals, "Unknown"); +- +- col_clear(pinfo->cinfo,COL_INFO); +- col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", message_str); +- +- proto_item *msg_tree_ti = proto_tree_add_string_format(tree, hf_nfapi_message_tree, +- tvb, 0, msg_len, +- "", message_str); +- +- proto_tree *msg_tree = proto_item_add_subtree(msg_tree_ti, ett_nfapi_message_tree); +- +- guint offset = 0; +- +- +- switch (msg_id) +- { +- // HARQ.indication +- case 0x85: +- // CRC.indication +- case 0x86: +- // RX_ULSCH.indicatoin +- case 0x87: +- // RACH.indication +- case 0x88: +- // SRS.indication +- case 0x89: +- // RX_SR.indication +- case 0x8A: +- // RX_CQI.indication +- case 0x8B: +- { +- dissect_nfapi_ul_p7(tvb, pinfo, msg_tree, data); +- } +- break; +- +- // DL_CONFIG.request +- case 0x80: +- { +- dissect_nfapi_dl_p7(tvb, pinfo, msg_tree, data); +- //dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- //proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- //dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- +- // UL_CONFIG.request +- case 0x81: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- // HI_DCI0.request +- case 0x83: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- // TX.request +- case 0x84: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- } +- break; +- +- // LBT_DL_CONFIG.request +- case 0x8C: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- } ++#define NFAPI_P7_HEADER_LENGTH 16 ++ ++static const unit_name_string khz_100_units_db = { " (100)khz", NULL }; ++ ++typedef enum{ ++ NFAPI_DL_CONFIG_REQUEST_MSG_ID = 0x0080, ++ NFAPI_UL_CONFIG_REQUEST_MSG_ID, ++ NFAPI_SUBFRAME_INDICATION_MSG_ID, ++ NFAPI_HI_DCI0_REQUEST_MSG_ID, ++ NFAPI_TX_REQUEST_MSG_ID, ++ NFAPI_HARQ_INDICATION_MSG_ID, ++ NFAPI_CRC_INDICATION_MSG_ID, ++ NFAPI_RX_ULSCH_INDICATION_MSG_ID, ++ NFAPI_RACH_INDICATION_MSG_ID, ++ NFAPI_SRS_INDICATION_MSG_ID, ++ NFAPI_RX_SR_INDICATION_MSG_ID, ++ NFAPI_RX_CQI_INDICATION_MSG_ID, ++ NFAPI_LBT_DL_CONFIG_REQUEST_MSG_ID, ++ NFAPI_LBT_DL_INDICATION_MSG_ID, ++ ++ NFAPI_PNF_PARAM_REQUEST_MSG_ID = 0x0100, ++ NFAPI_PNF_PARAM_RESPONSE_MSG_ID, ++ NFAPI_PNF_CONFIG_REQUEST_MSG_ID, ++ NFAPI_PNF_CONFIG_RESPONSE_MSG_ID, ++ NFAPI_PNF_START_REQUEST_MSG_ID, ++ NFAPI_PNF_START_RESPONSE_MSG_ID, ++ NFAPI_PNF_STOP_REQUEST_MSG_ID, ++ NFAPI_PNF_STOP_RESPONSE_MSG_ID, ++ NFAPI_PARAM_REQUEST_MSG_ID, ++ NFAPI_PARAM_RESPONSE_MSG_ID, ++ NFAPI_CONFIG_REQUEST_MSG_ID, ++ NFAPI_CONFIG_RESPONSE_MSG_ID, ++ NFAPI_START_REQUEST_MSG_ID, ++ NFAPI_START_RESPONSE_MSG_ID, ++ NFAPI_STOP_REQUEST_MSG_ID, ++ NFAPI_STOP_RESPONSE_MSG_ID, ++ NFAPI_MEASUREMENT_REQUEST_MSG_ID, ++ NFAPI_MEASUREMENT_RESPONSE_MSG_ID, ++ ++ NFAPI_DL_NODE_SYNC_MSG_ID = 0x0180, ++ NFAPI_UL_NODE_SYNC_MSG_ID, ++ NFAPI_TIMING_INFO_MSG_ID, ++ ++ NFAPI_RSSI_REQUEST_MSG_ID = 0x0200, ++ NFAPI_RSSI_RESPONSE_MSG_ID, ++ NFAPI_RSSI_INDICATION_MSG_ID, ++ NFAPI_CELL_SEARCH_REQUEST_MSG_ID, ++ NFAPI_CELL_SEARCH_RESPONSE_MSG_ID, ++ NFAPI_CELL_SEARCH_INDICATION_MSG_ID, ++ NFAPI_BROADCAST_DETECT_REQUEST_MSG_ID, ++ NFAPI_BROADCAST_DETECT_RESPONSE_MSG_ID, ++ NFAPI_BROADCAST_DETECT_INDICATION_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_REQUEST_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_RESPONSE_MSG_ID, ++ NFAPI_SYSTEM_INFORMATION_INDICATION_MSG_ID, ++ NFAPI_NMM_STOP_REQUEST_MSG_ID, ++ NFAPI_NMM_STOP_RESPONSE_MSG_ID, ++} nfapi_message_id_e; ++ ++static const value_string nfapi_error_vals[] = { ++ { 0x0, "MSG_OK" }, ++ { 0x1, "MSG_INVALID_STATE" }, ++ { 0x2, "MSG_INVALID_CONFIG" }, ++ { 0x3, "SFN_OUT_OF_SYNC" }, ++ { 0x4, "MSG_SUBFRAME_ERR" }, ++ { 0x5, "MSG_BCH_MISSING" }, ++ { 0x6, "MSG_BCH_MISSING" }, ++ { 0x7, "MSG_HI_ERR" }, ++ { 0x8, "MSG_TX_ERR" }, ++ { 0, NULL }, ++}; ++ ++static const value_string nfapi_p4_error_vals[] = { ++ { 100, "MSG_OK" }, ++ { 101, "MSG_INVALID_STATE" }, ++ { 102, "MSG_INVALID_CONFIG" }, ++ { 103, "MSG_RAT_NOT_SUPPORTED" }, ++ { 200, "MSG_NMM_STOP_OK" }, ++ { 201, "MSG_NMM_STOP_IGNORED" }, ++ { 202, "MSG_NMM_STOP_INVALID_STATE" }, ++ { 300, "MSG_PROCEDURE_COMPLETE" }, ++ { 301, "MSG_PROCEDURE_STOPPED" }, ++ { 302, "MSG_PARTIAL_RESULTS" }, ++ { 303, "MSG_TIMEOUT" }, ++ { 0, NULL }, ++}; ++ ++static const value_string nfapi_rat_type_vals[] = { ++ { 0, "LTE" }, ++ { 1, "UTRAN" }, ++ { 2, "GERAN" }, ++ { 0, NULL }, ++}; ++ ++typedef enum{ ++ UN_ALIGNED_SYNCHRONIZATION = 0, ++ INTERNAL_PNF_FRAME_ALIGNMENT, ++ ABSOLUTE_TIME_ALIGNED_SYNCHRONIZATION ++} nfapi_sync_mode_e; ++ ++static const value_string nfapi_sync_mode_vals[] = { ++ { UN_ALIGNED_SYNCHRONIZATION, "UN-ALIGNED SYNCHRONIZATION" }, ++ { INTERNAL_PNF_FRAME_ALIGNMENT, "INTERNAL PNF FRAME ALIGNMENT" }, ++ { ABSOLUTE_TIME_ALIGNED_SYNCHRONIZATION, "ABSOLUTE TIME ALIGNED SYNCHRONIZATION" }, ++ { 0, NULL }, ++}; ++ ++typedef enum { ++ NONE = 0, ++ GPS, ++ GLONASS, ++ BEIDOU ++} location_mode_e; ++ ++static const value_string location_mode_vals[] = { ++ { NONE, "NONE" }, ++ { GPS, "GPS" }, ++ { GLONASS, "GLONASS" }, ++ { BEIDOU, "BeiDou" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_uplink_rs_hopping_vals[] = { ++ { 0, "RS_NO_HOPPING" }, ++ { 1, "RS_GROUP_HOPPING" }, ++ { 2, "RS_SEQUENCE_HOPPING" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_laa_carrier_type_vals[] = { ++ { 0, "No multi carrier support" }, ++ { 1, "Mode A1" }, ++ { 2, "Mode A12" }, ++ { 3, "Mode B1" }, ++ { 4, "Mode B2" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_mutli_carrier_lbt_support_vals[] = { ++ { 0, "Multi carrier Mode A1" }, ++ { 1, "Multi carrier Mode A2" }, ++ { 2, "Multi carrier Mode B1" }, ++ { 3, "Multi carrier Mode B2" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_lbt_dl_req_pdu_type[] = { ++ { 0, "LBT_PDSCH_REQ PDU" }, ++ { 1, "LBT_DRS_REQ PDU" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string nfapi_lbt_dl_ind_pdu_type[] = { ++ { 0, "LBT_PDSCH_RSP PDU" }, ++ { 1, "LBT_DRS_RSP PDU" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_phy_state_vals[] = { ++ { 0, "IDLE" }, ++ { 1, "CONFIGURED" }, ++ { 2, "RUNNING" }, ++ { 0, NULL }, ++}; ++ ++ ++/* These are definitions where data 0 & 1 represent/provide a string name*/ ++static const true_false_string nfapi_csi_report_type_strname = { ++ "Periodic", ++ "Aperiodic", ++}; ++ ++static const true_false_string nfapi_control_type_string_name = { ++ "CQI/PMI", ++ "RI", ++}; ++ ++static const true_false_string cyclic_prefix_type_strname = { ++ "CP_NORMAL", ++ "CP_EXTENDED" ++}; ++ ++static const true_false_string support_strname = { ++ "No Support", ++ "Support" ++}; ++ ++static const true_false_string partial_sf_support_strname = ++{ ++ "Start partial SF support", ++ "End partial SF support" ++}; ++ ++static const true_false_string phich_duration_strname = { ++ "PHICH_D_NORMAL", ++ "PHICH_D_EXTENDED" ++}; ++ ++static const true_false_string high_speed_flag_strname = { ++ "HS_UNRESTRICTED_SET", ++ "HS_RESTRICTED_SET" ++}; ++ ++static const true_false_string hopping_mode_strname = { ++ "HM_INTER_SF", ++ "HM_INTRA_INTER_SF" ++}; ++ ++static const true_false_string srs_simult_tx_strname = { ++ "No Simultaneous Transmission", ++ "Simultaneous Transmission" ++}; ++ ++static const true_false_string crc_flag_strname = { ++ "CRC_ERROR", ++ "CRC_CORRECT" ++}; ++ ++static const true_false_string hi_value_strname = { ++ "HI_ACK", ++ "HI_NACK" ++}; ++ ++static const true_false_string flag_tb2_strname = { ++ "HI_NOT_PRESENT", ++ "HI_PRESENT" ++}; ++ ++static const true_false_string nfapi_multi_carrier_tx_strname = { ++ "Mutual transmission (self-deferral support for current carrier)", ++ "Transmit on channel access win (no self-deferral)" ++}; ++ ++static const true_false_string nfapi_multi_carrier_freeze_strname = { ++ "Absence of other technology is not guaranteed", ++ "Absence of other technology is guaranteed" ++}; ++ ++static const true_false_string initial_partial_sf_strname = { ++ "Full SF", ++ "Partial SF" ++}; ++ ++static const true_false_string lbt_mode_strname = { ++ "Full LBT", ++ "Partial LBT" ++}; ++ ++static const true_false_string data_report_mode_vals = { ++ "Crc reported in CRC.indication", ++ "Crc reported in RX.indication" ++}; ++ ++static const true_false_string mcch_flag_string_name = { ++ "MCCH or SC-MCCH change notification field is not valid", ++ "MCCH or SC-MCCH change notification field is valid" ++}; ++ ++static const true_false_string cross_carrier_scheduling_flag_strname = { ++ "Carrier indicator field is not valid", ++ "Carrier indicator field is valid" ++}; ++ ++static const true_false_string srs_flag_strname = { ++ "SRS request field is not valid", ++ "SRS request field is valid" ++}; ++static const true_false_string srs_request_strname = { ++ "SRS not requested", ++ "SRS requested" ++}; ++ ++static const true_false_string ul_dl_configuration_flag_strname = { ++ "UL/DL configuration field is not valid", ++ "UL/DL configuration field is valid" ++}; ++ ++static const true_false_string prs_cyclic_prefix_type_strname = { ++ "normal cyclic prefix", ++ "extended cyclic prefix" ++}; ++ ++static const true_false_string prs_muting_strname = { ++ "no muting", ++ "muting" ++}; ++ ++ ++static const value_string nfapi_dl_config_pdu_type_vals[] = { ++ { 0, "DL_CONFIG_DCI_DL_PDU" }, ++ { 1, "DL_CONFIG_BCH_PDU" }, ++ { 2, "DL_CONFIG_MCH_PDU" }, ++ { 3, "DL_CONFIG_DLSCH_PDU" }, ++ { 4, "DL_CONFIG_PCH_PDU" }, ++ { 5, "DL_CONFIG_PRS_PDU" }, ++ { 6, "DL_CONFIG_CSI_RS_PDU" }, ++ { 7, "DL_CONFIG_EPDCCH_DL_PDU" }, ++ { 8, "DL_CONFIG_EPDCCH_DL_PDU" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_duplex_mode_vals[] = { ++ { 0, "TDD" }, ++ { 1, "FDD" }, ++ { 2, "HD-FDD" }, ++ { 0, NULL } ++}; ++ ++static const value_string modulation_vals[] = { ++ { 2, "QPSK" }, ++ { 4, "16QAM" }, ++ { 6, "64QAM" }, ++ { 8, "256QAM" }, ++ { 0, NULL } ++}; ++ ++static const value_string pch_modulation_vals[] = { ++ { 0, "QPSK" }, ++ { 0, NULL } ++}; ++ ++static const value_string ue_mode_vals[] = { ++ { 0, "non LC/CE UE" }, ++ { 1, "LC/CE UE" }, ++ { 0, NULL } ++}; ++ ++static const value_string csi_rs_class_vals[] = { ++ { 0, "not used" }, ++ { 1, "Class A" }, ++ { 1, "Class B" }, ++ { 0, NULL } ++}; ++ ++static const value_string csi_rs_cdm_type_vals[] = { ++ { 0, "cdm 2" }, ++ { 1, "cdm 4" }, ++ { 0, NULL } ++}; ++ ++static const value_string antenna_ports_vals[] = { ++ { 0, "1 antenna ports" }, ++ { 1, "2 antenna ports" }, ++ { 2, "4 antenna ports" }, ++ { 0, NULL } ++}; ++ ++static const value_string combs_vals[] = { ++ { 0, "2 TC" }, ++ { 1, "4 TC" }, ++ { 0, NULL } ++}; ++ ++static const value_string resource_allocation_type_vals[] = { ++ { 0, "type 0" }, ++ { 1, "type 1" }, ++ { 2, "type 2 1A/1B/1D" }, ++ { 3, "type 2 1C" }, ++ { 4, "type 2 6-1A" }, ++ { 5, "type UEModeB" }, ++ { 6, "NB index" }, ++ { 0, NULL } ++}; ++ ++static const value_string transmission_scheme_vals[] = { ++ { 0, "SINGLE_ANTENNA_PORT_0" }, ++ { 1, "TX_DIVERSITY" }, ++ { 2, "LARGE_DELAY_CDD" }, ++ { 3, "CLOSED_LOOP_SPATIAL_MULTIPLEXING" }, ++ { 4, "MULTI_USER_MIMO" }, ++ { 5, "CLOSED_LOOP_RANK_1_PRECODING" }, ++ { 6, "SINGLE_ANTENNA_PORT_5" }, ++ { 7, "SINGLE_ANTENNA_PORT_7" }, ++ { 8, "SINGLE_ANTENNA_PORT_8" }, ++ { 9, "DUAL_LAYER_TX_PORT_7_AND_8" }, ++ { 10, "UP_TO_8_LAYER_TX" }, ++ { 11, "SINGLE_ANTENNA_PORT_11" }, ++ { 12, "SINGLE_ANTENNA_PORT_13" }, ++ { 13, "DUAL_LAYER_TX_PORT_11_13" }, ++ { 0, NULL } ++}; ++ ++static const value_string ul_transmission_scheme_vals[] = { ++ { 0, "SINGLE_ANTENNA_PORT_10" }, ++ { 1, "CLOSED_LOOP_SPATIAL_MULTIPLEXING" }, ++ { 0, NULL }, ++}; ++ ++static const value_string dl_dci_format_vals[] = { ++ { 0, "1" }, ++ { 1, "1A" }, ++ { 2, "1B" }, ++ { 3, "1C" }, ++ { 4, "1D" }, ++ { 5, "2" }, ++ { 6, "2A" }, ++ { 7, "2B" }, ++ { 8, "2C" }, ++ { 9, "2D" }, ++ { 10, "6-1A" }, ++ { 11, "6-1B" }, ++ { 12, "6-2" }, ++ { 0, NULL } ++}; ++ ++static const value_string ul_dci_format_vals[] = { ++ { 0, "0" }, ++ { 1, "3" }, ++ { 2, "3A" }, ++ { 3, "4" }, ++ { 4, "5" }, ++ { 0, NULL } ++}; ++ ++static const value_string mpdcch_ul_dci_format_vals[] = { ++ { 1, "3" }, ++ { 2, "3A" }, ++ { 4, "6-0A" }, ++ { 5, "6-0B" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string pa_vals[] = { ++ { 0, "-6dB" }, ++ { 1, "-4.77dB" }, ++ { 2, "-3dB" }, ++ { 3, "-1.77dB" }, ++ { 4, "0dB" }, ++ { 5, "1dB" }, ++ { 6, "2dB" }, ++ { 7, "3dB" }, ++ { 0, NULL } ++}; ++ ++static const value_string transmission_mode_vals[] = { ++ { 1, "Mode 1" }, ++ { 2, "Mode 2" }, ++ { 3, "Mode 3" }, ++ { 4, "Mode 4" }, ++ { 5, "Mode 5" }, ++ { 6, "Mode 6" }, ++ { 7, "Mode 7" }, ++ { 8, "Mode 8" }, ++ { 9, "Mode 9" }, ++ { 10, "Mode 10" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_ul_config_pdu_type_vals[] = { ++ { 0, "ULSCH" }, ++ { 1, "ULSCH_CQI_RI" }, ++ { 2, "ULSCH_HARQ" }, ++ { 3, "ULSCH_CQI_HARQ_RI" }, ++ { 4, "UCI_CQI" }, ++ { 5, "UCI_SR" }, ++ { 6, "UCI_HARQ" }, ++ { 7, "UCI_SR_HARQ" }, ++ { 8, "UCI_CQI_HARQ" }, ++ { 9, "UCI_CQI_SR" }, ++ { 10, "UCI_CQI_SR_HARQ" }, ++ { 11, "SRS" }, ++ { 12, "HARQ_BUFFER" }, ++ { 13, "ULSCH_UCI_CSI" }, ++ { 14, "ULSCH_UCI_HARQ" }, ++ { 15, "ULSCH_CSI_UCI_HARQ" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_tdd_ack_nack_mode_vals[] = { ++ { 0, "Bundling" }, ++ { 1, "Multiplexing" }, ++ { 2, "Format 1b with channel selection" }, ++ { 3, "Format 3" }, ++ { 4, "Format 4" }, ++ { 5, "Format 5" }, ++ { 0, NULL } ++}; ++static const value_string nfapi_fdd_ack_nack_mode_vals[] = { ++ { 0, "Format 1a/1b" }, ++ { 1, "Channel selection" }, ++ { 2, "Format 3" }, ++ { 3, "Format 4" }, ++ { 4, "Format 5" }, ++ { 0, NULL } ++}; ++ ++static const value_string nfapi_phich_resource_vals[] = { ++ { 0, "PHICH_R_ONE_SIXTH " }, ++ { 1, "PHICH_R_HALF" }, ++ { 2, "PHICH_R_ONE" }, ++ { 3, "PHICH_R_TWO" }, ++ { 0, NULL } ++}; ++ ++static const value_string local_distributed_vals[] = { ++ { 0, "localized" }, ++ { 1, "distributed" }, ++ { 0, NULL } ++}; ++ ++static const value_string transport_block_to_codeword_swap_flag_vals[] = { ++ { 0, "no swapping" }, ++ { 1, "swapped" }, ++ { 0, NULL } ++}; ++ ++static const value_string ngap_vals[] = { ++ { 0, "Ngap1" }, ++ { 1, "Ngap2" }, ++ { 0, NULL } ++}; ++ ++static const value_string pmi_vals[] = { ++ { 0, "Use precoding indicated in TPMI field" }, ++ { 1, "Use precoding indicated in last PMI report on PUSCH" }, ++ { 2, "use precoding indicated in TPM field" }, ++ { 0, NULL } ++}; ++ ++static const value_string true_false_vals[] = { ++ { 0, "false" }, ++ { 1, "true" }, ++ { 0, NULL } ++}; ++ ++static const value_string exhustive_search_vals[] = { ++ { 0, "non-exhaustive search" }, ++ { 1, "exhaustive search" }, ++ { 0, NULL } ++}; ++ ++static const value_string not_used_enabled_vals[] = { ++ { 0, "not used" }, ++ { 1, "enabled" }, ++ { 0, NULL } ++}; ++ ++static const value_string hopping_vals[] = { ++ { 0, "no hopping" }, ++ { 1, "hopping enabled" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string mpdcch_rnti_type_vals[] = { ++ { 1, "Temporary C-RNTI" }, ++ { 2, "RA-RNTI" }, ++ { 3, "P-RNTI" }, ++ { 4, "other" }, ++ { 0, NULL } ++}; ++ ++static const value_string rnti_type_vals[] = { ++ { 1, "C-RNTI" }, ++ { 2, "RA-RNTI, P-RNTI, SI-RNTI, SC-RNTI, G-RNTI" }, ++ { 3, "SPS-CRNTI" }, ++ { 0, NULL } ++}; ++ ++static const value_string primary_cells_type_vals[] = { ++ { 1, "TDD" }, ++ { 2, "FDD" }, ++ { 3, "HD_FDD" }, ++ { 0, NULL } ++}; ++ ++static const value_string ul_rssi_supported_vals[] = { ++ { 0, "Uplink RSSI not supported" }, ++ { 1, "Uplink RSSI supported" }, ++ { 0, NULL } ++}; ++ ++static const value_string nprb_vals[] = { ++ { 0, "2" }, ++ { 1, "3" }, ++ { 0, NULL } ++}; ++ ++static const value_string nmm_modes_supported_vals[] = ++{ ++ { 0, "NONE" }, ++ { 1, "NMM_ONLY" }, ++ { 2, "NMM_IN_CONFIGURED_STATE" }, ++ { 3, "NMM_IN_RUNNING_STATE" }, ++ { 4, "NMM_IN_CONFIGURED_AND_RUNNING_STATE" }, ++ { 0, NULL } ++}; ++ ++static const value_string dlsch_re13_ue_type_vals[] = { ++ { 0, "non LC/CE UE" }, ++ { 1, "LC/CE CEModeA UE" }, ++ { 2, "LC/CE CEModeB UE" }, ++ { 0, NULL } ++}; ++ ++static const value_string dlsch_re13_pdsch_payload_type_vals[] = { ++ { 0, "PDSCH carrying SIB1-BR " }, ++ { 1, "PDSCH carrying SI message (except for SIB1-BR or PCH)" }, ++ { 2, "PDSCH carrying other" }, ++ { 0, NULL } ++}; ++ ++static const value_string csi_rs_flags_strname[] = { ++ { 0, "CSI - RS parameters are not valid" }, ++ { 1, "CSI - RS parameters are valid" }, ++ { 0, NULL} ++}; ++ ++ ++static const value_string paging_direct_indication_differtiation_flag_vals[] = { ++ { 0, "Direct Information" }, ++ { 1, "Paging" }, ++ { 0, NULL } ++}; ++ ++static const value_string ul_tx_mode_vals[] = { ++ { 0, "SISO/MIMO" }, ++ { 1, "MIMO" }, ++ { 0, NULL } ++}; ++ ++static const value_string n_srs_vals[] = { ++ { 0, "No overlap" }, ++ { 1, "Overlap" }, ++ { 0, NULL } ++}; ++ ++static const value_string n_srs_initial_vals[] = { ++ { 0, "Last OFDM symbol is not punctured" }, ++ { 1, "Last OFDM symbol is punctured." }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string csi_mode_vals[] = { ++ { 0, "PUCCH format 2/2a/2b/3" }, ++ { 1, "PUCCH format 4" }, ++ { 2, "PUCCH format 5" }, ++ { 0, NULL } ++}; ++ ++static const value_string hi_dci0_pdu_type_vals[] = { ++ { 0, "HI" }, ++ { 1, "DCI UL" }, ++ { 2, "EDPCCH DCI UL" }, ++ { 3, "MDPCCH DCI UL" }, ++ { 0, NULL } ++}; ++ ++static const value_string ue_tx_antenna_selection_vals[] = { ++ { 0, "Not Configured" }, ++ { 1, "Configured and using UE port 0" }, ++ { 2, "Configured and using UE port 1" }, ++ { 0, NULL } ++}; ++ ++static const value_string size_of_cqi_csi_feild_vals[] = { ++ { 0, "1 bit" }, ++ { 1, "2 bits" }, ++ { 2, "3 bits" }, ++ { 0, NULL } ++}; ++ ++static const value_string number_of_antenna_port_vals[] = { ++ { 0, "1 antenna port" }, ++ { 1, "2 antenna ports" }, ++ { 2, "4 antenna ports" }, ++ { 0, NULL } ++}; ++ ++static const value_string ce_mode_vals[] = { ++ { 1, "CEModeA" }, ++ { 2, "CEModeB" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string csi_request_vals[] = { ++ { 0, "Aperiodic CSI not requested" }, ++ { 1, "Aperiodic CSI requested" }, ++ { 0, NULL } ++}; ++ ++static const value_string tdd_harq_mode_vals[] = { ++ { 0, "Format 1a/1b BUNDLING" }, ++ { 1, "Format 1a/1b MULTIPLEXING" }, ++ { 2, "Format 1a/1b SPECIAL BUNDLING" }, ++ { 3, "Channel Selection" }, ++ { 4, "Format 3" }, ++ { 5, "Format 4" }, ++ { 6, "Format 5" }, ++ { 0, NULL } ++}; ++ ++static const value_string fdd_harq_mode_vals[] = { ++ { 0, "Format 1a/1b" }, ++ { 1, "Channel Selection" }, ++ { 2, "Format 3" }, ++ { 3, "Format 4" }, ++ { 4, "Format 5" }, ++ { 0, NULL } ++}; ++ ++static const value_string harq_value_vals[] = { ++ { 1, "ACK" }, ++ { 2, "NACK" }, ++ { 3, "ACK or NACK" }, ++ { 4, "DTX" }, ++ { 5, "ACK or DTX" }, ++ { 6, "NACK or DTX" }, ++ { 7, "ACK or NACK or DTX" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string harq_special_value_vals[] = { ++ { 0, "0 or None" }, ++ { 1, "1 or 4 or 7 ACKs reported" }, ++ { 2, "2 or 5 or 8 ACKs reported" }, ++ { 3, "3 or 6 or 9 ACKs reported" }, ++ { 4, "DTX (UE did not transmit anything)" }, ++ { 0, NULL } ++}; ++ ++static const value_string channel_vals[] = { ++ { 0, "PUCCH" }, ++ { 1, "PUSCH" }, ++ { 0, NULL } ++}; ++ ++static const value_string rach_resource_type_vals[] = { ++ { 0, "Non LC / CE RACH" }, ++ { 1, "LC / CE RACH CE level 0" }, ++ { 2, "LC / CE RACH CE level 1" }, ++ { 3, "LC / CE RACH CE level 2" }, ++ { 4, "LC / CE RACH CE level 3" }, ++ { 0, NULL } ++}; ++ ++static const value_string up_pts_symbol_vals[] = { ++ { 0, "Symbol 0" }, ++ { 1, "Symbol 1" }, ++ { 0, NULL } ++}; ++ ++static const value_string arfcn_direction_vals[] = { ++ { 0, "DL" }, ++ { 1, "UL" }, ++ { 0, NULL } ++}; ++ ++static int proto_nfapi = -1; ++ ++/* These are for the subtrees */ ++static gint ett_nfapi_message_tree = -1; ++static gint ett_nfapi_p4_p5_message_header = -1; ++static gint ett_nfapi_p7_message_header = -1; ++static gint ett_nfapi_tlv_tree = -1; ++static gint ett_nfapi_tl = -1; ++static gint ett_nfapi_pnf_phy = -1; ++static gint ett_nfapi_pnf_phy_rel10 = -1; ++static gint ett_nfapi_pnf_phy_rel11 = -1; ++static gint ett_nfapi_pnf_phy_rel12 = -1; ++static gint ett_nfapi_pnf_phy_rel13 = -1; ++static gint ett_nfapi_pnf_phy_rf_config = -1; ++static gint ett_nfapi_rf_bands = -1; ++static gint ett_nfapi_tx_antenna_ports = -1; ++static gint ett_nfapi_harq_ack_nack_data = -1; ++static gint ett_nfapi_harq_data = -1; ++static gint ett_nfapi_cqi_pmi_size = -1; ++static gint ett_nfapi_cc = -1; ++static gint ett_nfapi_rbs = -1; ++static gint ett_nfapi_antennas = -1; ++static gint ett_nfapi_dl_config_request_pdu_list = -1; ++static gint ett_nfapi_ul_config_request_pdu_list = -1; ++static gint ett_nfapi_hi_dci0_request_pdu_list = -1; ++static gint ett_nfapi_tx_request_pdu_list = -1; ++static gint ett_nfapi_rx_indication_pdu_list = -1; ++static gint ett_nfapi_harq_indication_pdu_list = -1; ++static gint ett_nfapi_crc_indication_pdu_list = -1; ++static gint ett_nfapi_sr_indication_pdu_list = -1; ++static gint ett_nfapi_cqi_indication_pdu_list = -1; ++static gint ett_nfapi_preamble_indication_pdu_list = -1; ++static gint ett_nfapi_srs_indication_pdu_list = -1; ++static gint ett_nfapi_lbt_dl_config_pdu_list = -1; ++static gint ett_nfapi_lbt_dl_indication_pdu_list = -1; ++static gint ett_nfapi_subbands = -1; ++static gint ett_nfapi_bf_vector_antennas = -1; ++static gint ett_nfapi_bf_vectors = -1; ++static gint ett_nfapi_csi_rs_resource_configs = -1; ++static gint ett_nfapi_csi_rs_bf_vector = -1; ++static gint ett_nfapi_epdcch_prbs = -1; ++static gint ett_nfapi_precoding = -1; ++static gint ett_nfapi_earfcn_list = -1; ++static gint ett_nfapi_uarfcn_list = -1; ++static gint ett_nfapi_arfcn_list = -1; ++static gint ett_nfapi_rssi_list = -1; ++static gint ett_nfapi_pci_list = -1; ++static gint ett_nfapi_psc_list = -1; ++static gint ett_nfapi_lte_cells_found_list = -1; ++static gint ett_nfapi_utran_cells_found_list = -1; ++static gint ett_nfapi_geran_cells_found_list = -1; ++static gint ett_nfapi_si_periodicity_list = -1; ++static gint ett_nfapi_downlink_bandwidth_support = -1; ++static gint ett_nfapi_uplink_bandwidth_support = -1; ++static gint ett_nfapi_downlink_modulation_support = -1; ++static gint ett_nfapi_uplink_modulation_support = -1; ++static gint ett_nfapi_received_interference_power_mesurement_results = -1; ++static gint ett_nfapi_release_support = -1; ++static expert_field ei_invalid_range = EI_INIT; ++static expert_field ei_invalid_tlv_length = EI_INIT; ++ ++static int hf_nfapi_p4_p5_message_header_phy_id = -1; ++static int hf_nfapi_p4_p5_message_header_message_id = -1; ++static int hf_nfapi_p4_p5_message_header_message_length = -1; ++static int hf_nfapi_p4_p5_message_header_spare = -1; ++static int hf_nfapi_p7_message_header_phy_id = -1; ++static int hf_nfapi_p7_message_header_message_id = -1; ++static int hf_nfapi_p7_message_header_message_length = -1; ++static int hf_nfapi_p7_message_header_m = -1; ++static int hf_nfapi_p7_message_header_segment = -1; ++static int hf_nfapi_p7_message_header_sequence_number = -1; ++static int hf_nfapi_p7_message_header_checksum = -1; ++static int hf_nfapi_p7_message_header_transmit_timestamp = -1; ++static int hf_nfapi_tl_tag = -1; ++static int hf_nfapi_tl_length = -1; ++static int hf_nfapi_sync_mode = -1; ++static int hf_nfapi_location_mode = -1; ++static int hf_nfapi_location_coordinates = -1; ++static int hf_nfapi_location_coordinates_length = -1; ++static int hf_nfapi_dl_config_timing = -1; ++static int hf_nfapi_tx_timing = -1; ++static int hf_nfapi_ul_config_timing = -1; ++static int hf_nfapi_hi_dci0_timing = -1; ++static int hf_nfapi_maximum_number_phys = -1; ++static int hf_nfapi_maximum_total_bandwidth = -1; ++static int hf_nfapi_maximum_total_number_dl_layers = -1; ++static int hf_nfapi_maximum_total_number_ul_layers = -1; ++static int hf_nfapi_shared_bands = -1; ++static int hf_nfapi_shared_pa = -1; ++static int hf_nfapi_maximum_total_power = -1; ++static int hf_nfapi_oui = -1; ++static int hf_nfapi_pdu = -1; ++static int hf_nfapi_pnf_phy_number_phy = -1; ++static int hf_nfapi_pnf_phy_config_index = -1; ++static int hf_nfapi_number_of_rf_exclusions = -1; ++static int hf_nfapi_dl_bandwidth_support = -1; ++static int hf_nfapi_dl_bandwidth_support_6 = -1; ++static int hf_nfapi_dl_bandwidth_support_15 = -1; ++static int hf_nfapi_dl_bandwidth_support_25 = -1; ++static int hf_nfapi_dl_bandwidth_support_50 = -1; ++static int hf_nfapi_dl_bandwidth_support_75 = -1; ++static int hf_nfapi_dl_bandwidth_support_100 = -1; ++static int hf_nfapi_ul_bandwidth_support = -1; ++static int hf_nfapi_ul_bandwidth_support_6 = -1; ++static int hf_nfapi_ul_bandwidth_support_15= -1; ++static int hf_nfapi_ul_bandwidth_support_25 = -1; ++static int hf_nfapi_ul_bandwidth_support_50 = -1; ++static int hf_nfapi_ul_bandwidth_support_75 = -1; ++static int hf_nfapi_ul_bandwidth_support_100 = -1; ++static int hf_nfapi_downlink_channel_bandwidth_supported = -1; ++static int hf_nfapi_uplink_channel_bandwidth_supported = -1; ++static int hf_nfapi_number_of_dl_layers_supported = -1; ++static int hf_nfapi_number_of_ul_layers_supported = -1; ++static int hf_nfapi_maximum_3gpp_release_supported = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel8 = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel9 = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel10 = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel11 = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel12 = -1; ++static int hf_nfapi_maximum_3gpp_release_supported_rel13 = -1; ++static int hf_nfapi_nmm_modes_supported = -1; ++static int hf_nfapi_number_of_rfs = -1; ++static int hf_nfapi_rf_config_index = -1; ++static int hf_nfapi_band = -1; ++static int hf_nfapi_maximum_transmit_power = -1; ++static int hf_nfapi_maximum_transmit_power_2 = -1; ++static int hf_nfapi_earfcn = -1; ++static int hf_nfapi_minimum_transmit_power = -1; ++static int hf_nfapi_number_of_antennas_suppported = -1; ++static int hf_nfapi_minimum_downlink_frequency = -1; ++static int hf_nfapi_maximum_downlink_frequency = -1; ++static int hf_nfapi_minimum_uplink_frequency = -1; ++static int hf_nfapi_maximum_uplink_frequency = -1; ++static int hf_nfapi_number_of_rf_bands = -1; ++static int hf_nfapi_nmm_uplink_rssi_supported = -1; ++static int hf_nfapi_phy_rf_config_info_phy_id = -1; ++static int hf_nfapi_transmission_mode7_supported = -1; ++static int hi_nfapi_transmission_mode8_supported = -1; ++static int hi_nfapi_two_antennas_ports_for_pucch = -1; ++static int hi_nfapi_transmission_mode_9_supported = -1; ++static int hi_nfapi_simultaneous_pucch_pusch = -1; ++static int hi_nfapi_four_layer_tx_with_tm3_and_tm4 = -1; ++static int hf_nfapi_epdcch_supported = -1; ++static int hi_nfapi_multi_ack_csi_reporting = -1; ++static int hi_nfapi_pucch_tx_diversity_with_channel_selection = -1; ++static int hi_nfapi_ul_comp_supported = -1; ++static int hi_nfapi_transmission_mode_5_supported = -1; ++static int hf_nfapi_csi_subframe_set = -1; ++static int hi_nfapi_enhanced_4tx_codebook = -1; ++static int hi_nfapi_drs_supported = -1; ++static int hi_nfapi_ul_64qam_supported = -1; ++static int hi_nfapi_transmission_mode_10_supported = -1; ++static int hi_nfapi_alternative_tbs_indices = -1; ++static int hf_nfapi_pucch_format_4_supported = -1; ++static int hf_nfapi_pucch_format_5_supported = -1; ++static int hf_nfapi_more_than_5_ca_supported = -1; ++static int hf_nfapi_laa_supported = -1; ++static int hf_nfapi_laa_ending_in_dwpts_supported = -1; ++static int hf_nfapi_laa_starting_in_second_slot_supported = -1; ++static int hf_nfapi_beamforming_supported = -1; ++static int hf_nfapi_csi_rs_enhancements_supported = -1; ++static int hf_nfapi_drms_enhancements_supported = -1; ++static int hf_nfapi_srs_enhancements_supported = -1; ++static int hf_nfapi_dl_rs_tx_power = -1; ++static int hf_nfapi_received_interference_power = -1; ++static int hf_nfapi_thermal_noise_power = -1; ++static int hf_nfapi_dl_rs_tx_power_measurement = -1; ++static int hf_nfapi_received_interference_power_measurement = -1; ++static int hf_nfapi_thermal_noise_power_measurement = -1; ++ ++// P5 Message Structures ++static int hf_nfapi_error_code = -1; ++static int hf_nfapi_p4_error_code = -1; ++static int hf_nfapi_rat_type = -1; ++static int hf_nfapi_num_tlv = -1; ++static int hf_nfapi_phy_state = -1; ++static int hf_nfapi_phy_antenna_capability = -1; ++static int hf_nfapi_release_capability = -1; ++static int hf_nfapi_mbsfn_capability = -1; ++static int hf_nfapi_laa_capability = -1; ++static int hf_nfapi_pd_sensing_lbt_support = -1; ++static int hf_nfapi_multi_carrier_lbt_support = -1; ++static int hf_nfapi_partial_sf_support = -1; ++ ++static int hf_nfapi_pnf_address_ipv4 = -1; ++static int hf_nfapi_pnf_address_ipv6 = -1; ++static int hf_nfapi_vnf_address_ipv4 = -1; ++static int hf_nfapi_vnf_address_ipv6 = -1; ++static int hf_nfapi_pnf_port = -1; ++static int hf_nfapi_vnf_port = -1; ++static int hf_nfapi_dl_ue_per_sf = -1; ++static int hf_nfapi_ul_ue_per_sf = -1; ++static int hf_nfapi_timing_window = -1; ++static int hf_nfapi_timing_info_mode = -1; ++static int hf_nfapi_timing_info_period = -1; ++static int hf_nfapi_duplex_mode = -1; ++static int hf_nfapi_pcfich_power_offset = -1; ++static int hf_nfapi_pb = -1; ++static int hf_nfapi_dl_cyclic_prefix_type = -1; ++static int hf_nfapi_ul_cyclic_prefix_type = -1; ++static int hf_nfapi_tx_antenna_ports = -1; ++static int hf_nfapi_rx_antenna_ports = -1; ++static int hf_nfapi_downlink_channel_bandwidth = -1; ++static int hf_nfapi_uplink_channel_bandwidth = -1; ++static int hf_nfapi_reference_signal_power = -1; ++static int hf_nfapi_phich_resource = -1; ++static int hf_nfapi_phich_duration = -1; ++static int hf_nfapi_phich_power_offset = -1; ++static int hf_nfapi_primary_synchronization_signal_epre_eprers = -1; ++static int hf_nfapi_secondary_synchronization_signal_epre_eprers = -1; ++static int hf_nfapi_physical_cell_id = -1; ++static int hf_nfapi_configuration_index = -1; ++static int hf_nfapi_root_sequence_index = -1; ++static int hf_nfapi_zero_correlation_zone_configuration = -1; ++static int hf_nfapi_high_speed_flag = -1; ++static int hf_nfapi_frequency_offset = -1; ++static int hf_nfapi_hopping_mode = -1; ++static int hf_nfapi_hopping_offset = -1; ++static int hf_nfapi_delta_pucch_shift = -1; ++static int hf_nfapi_n_cqi_rb = -1; ++static int hf_nfapi_n_an_cs = -1; ++static int hf_nfapi_n1_pucch_an = -1; ++static int hf_nfapi_bandwidth_configuration = -1; ++static int hf_nfapi_max_up_pts = -1; ++static int hf_nfapi_srs_subframe_configuration = -1; ++static int hf_nfapi_srs_acknack_srs_simultaneous_transmission = -1; ++static int hf_nfapi_uplink_rs_hopping = -1; ++static int hf_nfapi_group_assignment = -1; ++static int hf_nfapi_cyclic_shift_1_for_drms = -1; ++static int hf_nfapi_subframe_assignment = -1; ++static int hf_nfapi_special_subframe_patterns = -1; ++static int hf_nfapi_ed_threshold_for_lbt_for_pdsch = -1; ++static int hf_nfapi_ed_threshold_for_lbt_for_drs = -1; ++static int hf_nfapi_pd_threshold = -1; ++static int hf_nfapi_multi_carrier_type = -1; ++static int hf_nfapi_multi_carrier_tx = -1; ++static int hf_nfapi_multi_carrier_freeze = -1; ++static int hf_nfapi_tx_antenna_ports_for_drs = -1; ++static int hf_nfapi_transmission_power_for_drs = -1; ++static int hf_nfapi_pbch_repetitions_enabled_r13 = -1; ++static int hf_nfapi_prach_cat_m_root_sequence_index = -1; ++static int hf_nfapi_prach_cat_m_zero_correlation_zone_configuration = -1; ++static int hf_nfapi_prach_cat_m_high_speed_flag = -1; ++static int hf_nfapi_prach_ce_level_0_enable = -1; ++static int hf_nfapi_prach_ce_level_0_configuration_index = -1; ++static int hf_nfapi_prach_ce_level_0_frequency_offset = -1; ++static int hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt = -1; ++static int hf_nfapi_prach_ce_level_0_starting_subframe_periodicity = -1; ++static int hf_nfapi_prach_ce_level_0_hopping_enabled = -1; ++static int hf_nfapi_prach_ce_level_0_hopping_offset = -1; ++static int hf_nfapi_prach_ce_level_1_enable = -1; ++static int hf_nfapi_prach_ce_level_1_configuration_index = -1; ++static int hf_nfapi_prach_ce_level_1_frequency_offset = -1; ++static int hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt = -1; ++static int hf_nfapi_prach_ce_level_1_starting_subframe_periodicity = -1; ++static int hf_nfapi_prach_ce_level_1_hopping_enabled = -1; ++static int hf_nfapi_prach_ce_level_1_hopping_offset = -1; ++static int hf_nfapi_prach_ce_level_2_enable = -1; ++static int hf_nfapi_prach_ce_level_2_configuration_index = -1; ++static int hf_nfapi_prach_ce_level_2_frequency_offset = -1; ++static int hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt = -1; ++static int hf_nfapi_prach_ce_level_2_starting_subframe_periodicity = -1; ++static int hf_nfapi_prach_ce_level_2_hopping_enabled = -1; ++static int hf_nfapi_prach_ce_level_2_hopping_offset = -1; ++static int hf_nfapi_prach_ce_level_3_enable = -1; ++static int hf_nfapi_prach_ce_level_3_configuration_index = -1; ++static int hf_nfapi_prach_ce_level_3_frequency_offset = -1; ++static int hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt = -1; ++static int hf_nfapi_prach_ce_level_3_starting_subframe_periodicity = -1; ++static int hf_nfapi_prach_ce_level_3_hopping_enabled = -1; ++static int hf_nfapi_prach_ce_level_3_hopping_offset = -1; ++static int hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b = -1; ++static int hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a = -1; ++static int hf_nfapi_dl_modulation_support = -1; ++static int hf_nfapi_dl_modulation_support_qpsk = -1; ++static int hf_nfapi_dl_modulation_support_16qam = -1; ++static int hf_nfapi_dl_modulation_support_64qam = -1; ++static int hf_nfapi_dl_modulation_support_256qam = -1; ++static int hf_nfapi_ul_modulation_support = -1; ++static int hf_nfapi_ul_modulation_support_qpsk = -1; ++static int hf_nfapi_ul_modulation_support_16qam = -1; ++static int hf_nfapi_ul_modulation_support_64qam = -1; ++static int hf_nfapi_data_report_mode = -1; ++static int hf_nfapi_sfnsf = -1; ++ ++// P7 Sub Structures ++static int hf_nfapi_dl_dci_format = -1; ++static int hf_nfapi_ul_dci_format = -1; ++static int hf_nfapi_mpdcch_ul_dci_format = -1; ++static int hf_nfapi_cce_idx = -1; ++static int hf_nfapi_aggregation_level = -1; ++static int hf_nfapi_mcs_1 = -1; ++static int hf_nfapi_redundancy_version_1 = -1; ++static int hf_nfapi_new_data_indicator_1 = -1; ++static int hf_nfapi_mcs_2 = -1; ++static int hf_nfapi_redundancy_version_2 = -1; ++static int hf_nfapi_new_data_indicator_2 = -1; ++static int hf_nfapi_harq_process = -1; ++static int hf_nfapi_tpmi = -1; ++static int hf_nfapi_pmi = -1; ++static int hf_nfapi_precoding_information = -1; ++static int hf_nfapi_tpc = -1; ++static int hf_nfapi_downlink_assignment_index = -1; ++static int hf_nfapi_transport_block_size_index = -1; ++static int hf_nfapi_downlink_power_offset = -1; ++static int hf_nfapi_allocate_prach_flag = -1; ++static int hf_nfapi_preamble_index = -1; ++static int hf_nfapi_prach_mask_index = -1; ++static int hf_nfapi_rnti_type = -1; ++static int hf_nfapi_mpdcch_rnti_type = -1; ++static int hf_nfapi_mcch_flag = -1; ++static int hf_nfapi_mcch_change_notification = -1; ++static int hf_nfapi_scrambling_identity = -1; ++static int hf_nfapi_cross_carrier_scheduling_flag = -1; ++static int hf_nfapi_carrier_indicator = -1; ++static int hf_nfapi_srs_flag = -1; ++static int hf_nfapi_srs_request = -1; ++static int hf_nfapi_antenna_ports_scrambling_and_layers = -1; ++static int hf_nfapi_total_dci_length_including_padding = -1; ++static int hf_nfapi_harq_ack_resource_offset = -1; ++static int hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator = -1; ++static int hf_nfapi_primary_cell_type = -1; ++static int hf_nfapi_ul_dl_configuration_flag = -1; ++static int hf_nfapi_number_of_ul_dl_configurations = -1; ++static int hf_nfapi_ul_dl_configuration_index = -1; ++static int hf_nfapi_laa_end_partial_sf_flag = -1; ++static int hf_nfapi_laa_end_partial_sf_configuration = -1; ++static int hf_nfapi_initial_lbt_sf = -1; ++static int hf_nfapi_codebooksize_determination_r13 = -1; ++static int hf_nfapi_rel13_drms_table_flag = -1; ++static int hf_nfapi_csi_rs_resource_config = -1; ++static int hf_nfapi_csi_rs_number_of_nzp_configurations = -1; ++static int hf_nfapi_pdsch_start = -1; ++static int hf_nfapi_drms_config_flag = -1; ++static int hf_nfapi_drms_scrambling = -1; ++static int hf_nfapi_csi_config_flag = -1; ++static int hf_nfapi_csi_scrambling = -1; ++static int hf_nfapi_pdsch_re_mapping_flag = -1; ++static int hf_nfapi_pdsch_re_mapping_antenna_ports = -1; ++static int hf_nfapi_pdsch_re_mapping_freq_shift = -1; ++static int hf_nfapi_alt_cqi_table_r12 = -1; ++static int hf_nfapi_max_layers = -1; ++static int hf_nfapi_n_dl_harq = -1; ++static int hf_nfapi_dwpts_symbols = -1; ++static int hf_nfapi_ue_type = -1; ++static int hf_nfapi_pdsch_payload_type = -1; ++static int hf_nfapi_initial_transmission_sf = -1; ++static int hf_nfapi_req13_drms_table_flag = -1; ++static int hf_nfapi_prnti = -1; ++static int hf_nfapi_mcs = -1; ++static int hf_nfapi_number_of_transport_blocks = -1; ++static int hf_nfapi_ue_mode = -1; ++static int hf_prs_bandwidth = -1; ++static int hf_prs_cyclic_prefix_type = -1; ++static int hf_prs_muting = -1; ++static int hf_nfapi_csi_rs_resource_index = -1; ++static int hf_nfapi_csi_rs_class = -1; ++static int hf_nfapi_cdm_type = -1; ++static int hf_nfapi_edpcch_prb_index = -1; ++static int hf_nfapi_epdcch_resource_assignment_flag = -1; ++static int hf_nfapi_epdcch_id = -1; ++static int hf_nfapi_epdcch_start_symbol = -1; ++static int hf_nfapi_epdcch_num_prb = -1; ++static int hf_nfapi_precoding_value = -1; ++static int hf_nfapi_mpdcch_narrowband = -1; ++static int hf_nfapi_number_of_prb_pairs = -1; ++static int hf_nfapi_resource_block_assignment = -1; ++static int hf_nfapi_start_symbol = -1; ++static int hf_nfapi_ecce_index = -1; ++static int hf_nfapi_ce_mode = -1; ++static int hf_nfapi_drms_scrabmling_init = -1; ++static int hf_nfapi_pdsch_reception_levels = -1; ++static int hf_nfapi_new_data_indicator = -1; ++static int hf_nfapi_tpmi_length = -1; ++static int hf_nfapi_pmi_flag = -1; ++static int hf_nfapi_harq_resource_offset = -1; ++static int hf_nfapi_dci_subframe_repetition_number = -1; ++static int hf_nfapi_downlink_assignment_index_length = -1; ++static int hf_nfapi_starting_ce_level = -1; ++static int hf_nfapi_antenna_ports_and_scrambling_identity_flag = -1; ++static int hf_nfapi_antenna_ports_and_scrambling_identity = -1; ++static int hf_nfapi_paging_direct_indication_differentiation_flag = -1; ++static int hf_nfapi_direct_indication = -1; ++static int hf_nfapi_number_of_tx_antenna_ports = -1; ++ ++// P7 Message Structures ++static int hf_nfapi_dl_node_sync_t1 = -1; ++static int hf_nfapi_dl_node_sync_delta_sfn_sf = -1; ++static int hf_nfapi_ul_node_sync_t1 = -1; ++static int hf_nfapi_ul_node_sync_t2 = -1; ++static int hf_nfapi_ul_node_sync_t3 = -1; ++static int hf_nfapi_timing_info_last_sfn_sf = -1; ++static int hf_nfapi_timing_info_time_since_last_timing_info = -1; ++static int hf_nfapi_timing_info_dl_config_jitter = -1; ++static int hf_nfapi_timing_info_tx_request_jitter = -1; ++static int hf_nfapi_timing_info_ul_config_jitter = -1; ++static int hf_nfapi_timing_info_hi_dci0_jitter = -1; ++static int hf_nfapi_timing_info_dl_config_latest_delay = -1; ++static int hf_nfapi_timing_info_tx_request_latest_delay = -1; ++static int hf_nfapi_timing_info_ul_config_latest_delay = -1; ++static int hf_nfapi_timing_info_hi_dci0_latest_delay = -1; ++static int hf_nfapi_timing_info_dl_config_earliest_arrival = -1; ++static int hf_nfapi_timing_info_tx_request_earliest_arrival = -1; ++static int hf_nfapi_timing_info_ul_config_earliest_arrival = -1; ++static int hf_nfapi_timing_info_hi_dci0_earliest_arrival = -1; ++static int hf_nfapi_sfn_sf = -1; ++static int hf_nfapi_number_pdcch_ofdm_symbols = -1; ++static int hf_nfapi_number_dci = -1; ++static int hf_nfapi_number_pdus = -1; ++static int hf_nfapi_number_pdsch_rnti = -1; ++static int hf_nfapi_transmission_power_pcfich = -1; ++static int hf_nfapi_number_of_harqs = -1; ++static int hf_nfapi_number_of_crcs = -1; ++static int hf_nfapi_number_of_srs = -1; ++static int hf_nfapi_number_of_cqi = -1; ++static int hf_nfapi_number_of_preambles = -1; ++static int hf_nfapi_number_of_srss = -1; ++static int hf_nfapi_lbt_dl_req_pdu_type = -1; ++static int hf_nfapi_lbt_dl_ind_pdu_type = -1; ++static int hf_nfapi_dl_config_pdu_type = -1; ++static int hf_nfapi_pdu_size = -1; ++static int hf_nfapi_instance_length = -1; ++static int hf_nfapi_length; ++static int hf_nfapi_pdu_index = -1; ++static int hf_nfapi_rnti = -1; ++static int hf_nfapi_resource_allocation_type = -1; ++static int hf_nfapi_virtual_resource_block_assignment_flag = -1; ++static int hf_nfapi_resource_block_coding = -1; ++static int hf_nfapi_modulation = -1; ++static int hf_nfapi_redundancy_version = -1; ++static int hf_nfapi_transport_blocks = -1; ++static int hf_nfapi_transport_block_to_codeword_swap_flag = -1; ++static int hf_nfapi_transmission_scheme = -1; ++static int hf_nfapi_ul_transmission_scheme = -1; ++static int hf_nfapi_number_of_layers = -1; ++static int hf_nfapi_number_of_subbands = -1; ++static int hf_nfapi_codebook_index = -1; ++static int hf_nfapi_ue_category_capacity = -1; ++static int hf_nfapi_pa = -1; ++static int hf_nfapi_delta_power_offset_index = -1; ++static int hf_nfapi_ngap = -1; ++static int hf_nfapi_nprb = -1; ++static int hf_nfapi_transmission_mode = -1; ++static int hf_nfapi_num_bf_prb_per_subband = -1; ++static int hf_nfapi_num_bf_vector = -1; ++static int hf_nfapi_bf_vector_subband_index = -1; ++static int hf_nfapi_bf_vector_num_antennas = -1; ++static int hf_nfapi_bf_vector_bf_value = -1; ++static int hf_nfapi_nscid = -1; ++static int hf_nfapi_csi_rs_flag = -1; ++static int hf_nfapi_csi_rs_resource_config_r10 = -1; ++static int hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10 = -1; ++static int hf_nfapi_transmission_power = -1; ++static int hf_nfapi_mbsfn_area_id = -1; ++static int hf_nfapi_csi_rs_antenna_port_count_r10 = -1; ++static int hf_nfapi_ul_config_pdu_type = -1; ++static int hf_nfapi_rach_prach_frequency_resources = -1; ++static int hf_nfapi_srs_present = -1; ++static int hf_nfapi_handle = -1; ++static int hf_nfapi_pucch_index = -1; ++static int hf_nfapi_size = -1; ++static int hf_nfapi_resource_block_start = -1; ++static int hf_nfapi_number_of_resource_blocks = -1; ++static int hf_nfapi_cyclic_shift_2_for_drms = -1; ++static int hf_nfapi_frequency_hopping_enabled_flag = -1; ++static int hf_nfapi_frequency_hopping_bits = -1; ++static int hf_nfapi_new_data_indication = -1; ++static int hf_nfapi_harq_process_number = -1; ++static int hf_nfapi_ul_tx_mode = -1; ++static int hf_nfapi_current_tx_nb = -1; ++static int hf_nfapi_n_srs = -1; ++static int hf_nfapi_disable_sequence_hopping_flag = -1; ++static int hf_nfapi_dl_cqi_pmi_size_rank_1 = -1; ++static int hf_nfapi_dl_cqi_pmi_size_rank_greater_1 = -1; ++static int hf_nfapi_ri_size = -1; ++static int hf_nfapi_delta_offset_cqi = -1; ++static int hf_nfapi_delta_offset_ri = -1; ++static int hf_nfapi_harq_size = -1; ++static int hf_nfapi_delta_offset_harq = -1; ++static int hf_nfapi_tdd_ack_nack_mode = -1; ++static int hf_nfapi_fdd_ack_nack_mode = -1; ++static int hf_nfapi_n_srs_initial = -1; ++static int hf_nfapi_initial_number_of_resource_blocks = -1; ++static int hf_nfapi_dl_cqi_pmi_size = -1; ++static int hf_nfapi_report_type = -1; ++static int hf_nfapi_dl_cqi_ri_pmi_size = -1; ++static int hf_nfapi_control_type = -1; ++static int hf_nfapi_number_of_cc = -1; ++static int hf_nfapi_virtual_cell_id_enabled_flag = -1; ++static int hf_nfapi_npusch_identity = -1; ++static int hf_nfapi_ndrms_csh_identity = -1; ++static int hf_nfapi_total_number_of_repetitions = -1; ++static int hf_nfapi_repetition_number = -1; ++static int hf_nfapi_initial_sf_io = -1; ++static int hf_nfapi_empty_symbols_due_to_retunning = -1; ++static int hf_nfapi_dl_cqi_ri_pmi_size_2 = -1; ++static int hf_nfapi_npucch_identity = -1; ++static int hf_nfapi_harq_size_2 = -1; ++static int hf_nfapi_delta_offset_harq_2 = -1; ++static int hf_nfapi_empty_symbols = -1; ++static int hf_nfapi_csi_mode = -1; ++static int hf_nfapi_dl_cqi_pmi_size_2 = -1; ++static int hf_nfapi_statring_prb = -1; ++static int hf_nfapi_cdm_index = -1; ++static int hf_nfapi_nsrs = -1; ++static int hf_nfapi_num_ant_ports = -1; ++static int hf_nfapi_n_pucch_2_0 = -1; ++static int hf_nfapi_n_pucch_2_1 = -1; ++static int hf_nfapi_n_pucch_2_2 = -1; ++static int hf_nfapi_n_pucch_2_3 = -1; ++static int hf_nfapi_starting_prb = -1; ++static int hf_nfapi_antenna_port = -1; ++static int hf_nfapi_number_of_combs = -1; ++static int hf_nfapi_number_of_pucch_resource = -1; ++static int hf_nfapi_pucch_index_p1 = -1; ++static int hf_nfapi_n_pucch_1_0 = -1; ++static int hf_nfapi_n_pucch_1_1 = -1; ++static int hf_nfapi_n_pucch_1_2 = -1; ++static int hf_nfapi_n_pucch_1_3 = -1; ++static int hf_nfapi_srs_bandwidth = -1; ++static int hf_nfapi_frequency_domain_position = -1; ++static int hf_nfapi_srs_hopping_bandwidth = -1; ++static int hf_nfapi_transmission_comb = -1; ++static int hf_nfapi_i_srs = -1; ++static int hf_nfapi_sounding_reference_cyclic_shift = -1; ++static int hf_nfapi_pdu_length = -1; ++static int hf_nfapi_crc_flag = -1; ++static int hf_nfapi_number_of_hi_pdus = -1; ++static int hf_nfapi_number_of_dci_pdus = -1; ++static int hf_nfapi_hi_dci0_pdu_type = -1; ++static int hf_nfapi_hi_value = -1; ++static int hf_nfapi_i_phich = -1; ++static int hf_nfapi_flag_tb2 = -1; ++static int hf_nfapi_hi_value_2 = -1; ++static int hf_nfapi_ue_tx_antenna_selection = -1; ++static int hf_nfapi_cqi_csi_request = -1; ++static int hf_nfapi_ul_index = -1; ++static int hf_nfapi_dl_assignment_index = -1; ++static int hf_nfapi_tpc_bitmap = -1; ++static int hf_nfapi_new_data_indication_two = -1; ++static int hf_nfapi_size_of_cqi_csi_feild = -1; ++static int hf_nfapi_resource_allocation_flag = -1; ++static int hf_nfapi_number_of_antenna_ports = -1; ++static int hf_nfapi_n_ul_rb = -1; ++static int hf_nfapi_pscch_resource = -1; ++static int hf_nfapi_time_resource_pattern = -1; ++static int hf_nfapi_mpdcch_transmission_type = -1; ++static int hf_nfapi_drms_scrambling_init = -1; ++static int hf_nfapi_pusch_repetition_levels = -1; ++static int hf_nfapi_frequency_hopping_flag = -1; ++static int hf_nfapi_csi_request = -1; ++static int hf_nfapi_dai_presence_flag = -1; ++static int hf_nfapi_total_dci_length_include_padding = -1; ++static int hf_nfapi_data_offset = -1; ++static int hf_nfapi_ul_cqi = -1; ++static int hf_nfapi_timing_advance_r9 = -1; ++static int hf_nfapi_timing_advance = -1; ++static int hf_nfapi_harq_data_value_0 = -1; ++static int hf_nfapi_harq_data_value_0_special = -1; ++static int hf_nfapi_harq_data_value_1 = -1; ++static int hf_nfapi_harq_data_value_2 = -1; ++static int hf_nfapi_harq_data_value_3 = -1; ++static int hf_nfapi_tdd_harq_mode = -1; ++static int hf_nfapi_fdd_harq_mode = -1; ++static int hf_nfapi_number_of_ack_nack = -1; ++static int hf_nfapi_harq_tb_1 = -1; ++static int hf_nfapi_harq_tb_2 = -1; ++static int hf_nfapi_harq_tb_n = -1; ++static int hf_nfapi_channel = -1; ++static int hf_nfapi_ri = -1; ++static int hf_nfapi_number_of_cc_reported = -1; ++static int hf_nfapi_preamble = -1; ++static int hf_nfapi_rach_resource_type = -1; ++static int hf_nfapi_snr = -1; ++static int hf_nfapi_doppler_estimation = -1; ++static int hf_nfapi_rb_start = -1; ++static int hf_nfapi_up_pts_symbol = -1; ++static int hf_nfapi_number_prb_per_subband = -1; ++static int hf_nfapi_number_antennas = -1; ++static int hf_nfapi_subband_index = -1; ++static int hf_nfapi_channel_coefficient = -1; ++static int hf_nfapi_ul_rtoa = -1; ++static int hf_nfapi_mp_cca = -1; ++static int hf_nfapi_n_cca = -1; ++static int hf_nfapi_offset = -1; ++static int hf_nfapi_lte_txop_sf = -1; ++static int hf_nfapi_txop_sfn_sf_end = -1; ++static int hf_nfapi_lbt_mode = -1; ++static int hf_nfapi_sfn_sf_end = -1; ++static int hf_nfapi_result = -1; ++static int hf_nfapi_txop_symbols = -1; ++static int hf_nfapi_initial_partial_sf = -1; ++static int hf_nfapi_frequency_band_indicator = -1; ++static int hf_nfapi_measurement_period = -1; ++static int hf_nfapi_bandwidth = -1; ++static int hf_nfapi_timeout = -1; ++static int hf_nfapi_number_of_earfcns = -1; ++static int hf_nfapi_uarfcn = -1; ++static int hf_nfapi_number_of_uarfcns = -1; ++static int hf_nfapi_arfcn = -1; ++static int hf_nfapi_arfcn_direction = -1; ++static int hf_nfapi_number_of_arfcns = -1; ++static int hf_nfapi_rssi = -1; ++static int hf_nfapi_number_of_rssi = -1; ++static int hf_nfapi_pci = -1; ++static int hf_nfapi_measurement_bandwidth = -1; ++static int hf_nfapi_exhaustive_search = -1; ++static int hf_nfapi_number_of_pci = -1; ++static int hf_nfapi_psc = -1; ++static int hf_nfapi_number_of_psc = -1; ++static int hf_nfapi_rsrp = -1; ++static int hf_nfapi_rsrq = -1; ++static int hf_nfapi_number_of_lte_cells_found = -1; ++static int hf_nfapi_rscp = -1; ++static int hf_nfapi_enco = -1; ++static int hf_nfapi_number_of_utran_cells_found = -1; ++static int hf_nfapi_bsic = -1; ++static int hf_nfapi_rxlev = -1; ++static int hf_nfapi_rxqual = -1; ++static int hf_nfapi_sfn_offset = -1; ++static int hf_nfapi_number_of_geran_cells_found = -1; ++static int hf_nfapi_number_of_tx_antenna = -1; ++static int hf_nfapi_mib_length = -1; ++static int hf_nfapi_mib = -1; ++static int hf_nfapi_phich_configuration = -1; ++static int hf_nfapi_retry_count = -1; ++static int hf_nfapi_sib1 = -1; ++static int hf_nfapi_si_periodicity = -1; ++static int hf_nfapi_si_index = -1; ++static int hf_nfapi_number_of_si_periodicity = -1; ++static int hf_nfapi_si_window_length = -1; ++static int hf_nfapi_sib_type = -1; ++static int hf_nfapi_sib_len = -1; ++static int hf_nfapi_sib = -1; ++static int hf_nfapi_si_len = -1; ++static int hf_nfapi_si = -1; ++static int hf_nfapi_pnf_search_state = -1; ++static int hf_nfapi_pnf_broadcast_state = -1; ++ ++static const value_string message_id_vals[] = ++{ ++ { NFAPI_DL_CONFIG_REQUEST_MSG_ID, "DL_CONFIG.request" }, ++ { NFAPI_UL_CONFIG_REQUEST_MSG_ID, "UL_CONFIG.request" }, ++ { NFAPI_SUBFRAME_INDICATION_MSG_ID, "SUBFRAME_INDICATION" }, ++ { NFAPI_HI_DCI0_REQUEST_MSG_ID, "HI_DCI0.request" }, ++ { NFAPI_TX_REQUEST_MSG_ID, "TX.request" }, ++ { NFAPI_HARQ_INDICATION_MSG_ID, "HARQ.indication" }, ++ { NFAPI_CRC_INDICATION_MSG_ID, "CRC.indication" }, ++ { NFAPI_RX_ULSCH_INDICATION_MSG_ID, "RX_ULSCH.indication" }, ++ { NFAPI_RACH_INDICATION_MSG_ID, "RACH.indication" }, ++ { NFAPI_SRS_INDICATION_MSG_ID, "SRS.indication" }, ++ { NFAPI_RX_SR_INDICATION_MSG_ID, "RX_SR.indication" }, ++ { NFAPI_RX_CQI_INDICATION_MSG_ID, "RX_CQI.indication" }, ++ { NFAPI_LBT_DL_CONFIG_REQUEST_MSG_ID, "LBT_DL_CONFIG.request" }, ++ { NFAPI_LBT_DL_INDICATION_MSG_ID, "LBT_DL.indication" }, ++ ++ { NFAPI_PNF_PARAM_REQUEST_MSG_ID, "PNF_PARAM.request" }, ++ { NFAPI_PNF_PARAM_RESPONSE_MSG_ID, "PNF_PARAM.response" }, ++ { NFAPI_PNF_CONFIG_REQUEST_MSG_ID, "PNF_CONFIG.request" }, ++ { NFAPI_PNF_CONFIG_RESPONSE_MSG_ID, "PNF_CONFIG.response" }, ++ { NFAPI_PNF_START_REQUEST_MSG_ID, "PNF_START.request" }, ++ { NFAPI_PNF_START_RESPONSE_MSG_ID, "PNF_START.response" }, ++ { NFAPI_PNF_STOP_REQUEST_MSG_ID, "PNF_STOP.request" }, ++ { NFAPI_PNF_STOP_RESPONSE_MSG_ID, "PNF_STOP.response" }, ++ { NFAPI_PARAM_REQUEST_MSG_ID, "PARAM.request" }, ++ { NFAPI_PARAM_RESPONSE_MSG_ID, "PARAM.response" }, ++ { NFAPI_CONFIG_REQUEST_MSG_ID, "CONFIG.request" }, ++ { NFAPI_CONFIG_RESPONSE_MSG_ID, "CONFIG.response" }, ++ { NFAPI_START_REQUEST_MSG_ID, "START.request" }, ++ { NFAPI_START_RESPONSE_MSG_ID, "START.response" }, ++ { NFAPI_STOP_REQUEST_MSG_ID, "STOP.request" }, ++ { NFAPI_STOP_RESPONSE_MSG_ID, "STOP.response" }, ++ { NFAPI_MEASUREMENT_REQUEST_MSG_ID, "MEASUREMENT.request" }, ++ { NFAPI_MEASUREMENT_RESPONSE_MSG_ID, "MEASUREMENT.response" }, ++ ++ { NFAPI_DL_NODE_SYNC_MSG_ID, "UL_NODE_SYNC" }, ++ { NFAPI_UL_NODE_SYNC_MSG_ID, "DL_NODE_SYNC" }, ++ { NFAPI_TIMING_INFO_MSG_ID, "TIMING_INFO" }, ++ ++ { NFAPI_RSSI_REQUEST_MSG_ID, "RSSI.request" }, ++ { NFAPI_RSSI_RESPONSE_MSG_ID, "RSSI.response" }, ++ { NFAPI_RSSI_INDICATION_MSG_ID, "RSSI.indication" }, ++ { NFAPI_CELL_SEARCH_REQUEST_MSG_ID, "CELL_SEARCH.request" }, ++ { NFAPI_CELL_SEARCH_RESPONSE_MSG_ID, "CELL_SEARCH.response" }, ++ { NFAPI_CELL_SEARCH_INDICATION_MSG_ID, "CELL_SEARCH.indication" }, ++ { NFAPI_BROADCAST_DETECT_REQUEST_MSG_ID, "BROADCAST_DETECT.request" }, ++ { NFAPI_BROADCAST_DETECT_RESPONSE_MSG_ID, "BROADCAST_DETECT.response" }, ++ { NFAPI_BROADCAST_DETECT_INDICATION_MSG_ID, "BROADCAST_DETECT.indication" }, ++ { NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST_MSG_ID, "SYSTEM_INFORMATION_SCHEDULE.request" }, ++ { NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE_MSG_ID, "SYSTEM_INFORMATION_SCHEDULE.response" }, ++ { NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION_MSG_ID, "SYSTEM_INFORMATION_SCHEDULE.indication" }, ++ { NFAPI_SYSTEM_INFORMATION_REQUEST_MSG_ID, "SYSTEM_INFORMATION.request" }, ++ { NFAPI_SYSTEM_INFORMATION_RESPONSE_MSG_ID, "SYSTEM_INFORMATION.response" }, ++ { NFAPI_SYSTEM_INFORMATION_INDICATION_MSG_ID, "SYSTEM_INFORMATION.indication" }, ++ { NFAPI_NMM_STOP_REQUEST_MSG_ID, "NMM_STOP.request" }, ++ { NFAPI_NMM_STOP_RESPONSE_MSG_ID, "NMM_STOP.response" }, ++ ++ { 0, NULL }, ++}; ++ ++typedef void(*tlv_decode)(ptvcursor_t * ptvc, packet_info* pinfo); ++ ++typedef struct ++{ ++ guint16 tag_id; ++ char* name; ++ tlv_decode decode; ++} tlv_t; ++ ++static void dissect_tlv_list(ptvcursor_t * ptvc, packet_info* pinfo, gint len); ++ ++static void dissect_array_value(ptvcursor_t * ptvc, packet_info* pinfo, const char* name, guint32 ett_idx, guint32 count, tlv_decode decode) ++{ ++ guint16 i = 0; ++ ++ if (count > 0) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_idx, "%s", name); ++ ++ for (i = 0; i < count; ++i) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_idx, "[%d]", i); ++ decode(ptvc, pinfo); ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++} ++ ++static void dissect_pnf_param_general_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // nFAPI Sync Mode ++ guint8 nfapi_sync_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_sync_mode, 1, ENC_BIG_ENDIAN); ++ if (nfapi_sync_mode_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nfapi sync mode value [0..2]"); ++ } ++ ++ // Location Mode ++ guint8 location_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_location_mode, 1, ENC_BIG_ENDIAN); ++ if (location_mode_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid location mode value [0..3]"); ++ } ++ ++ guint16 len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_location_coordinates_length, 2, ENC_BIG_ENDIAN); ++ if (len > 0) ++ ptvcursor_add(ptvc, hf_nfapi_location_coordinates, len, ENC_NA); ++ ptvcursor_add(ptvc, hf_nfapi_dl_config_timing, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_tx_timing, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_ul_config_timing, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_hi_dci0_timing, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_number_phys, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_total_bandwidth, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_total_number_dl_layers, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_total_number_ul_layers, 1, ENC_BIG_ENDIAN); ++ ++ // Shared Bands ++ guint8 shared_bands_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_shared_bands, 1, ENC_BIG_ENDIAN); ++ if (shared_bands_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid shared bands value [0..1]"); ++ } ++ ++ // Shared PA ++ guint8 shared_pa_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_shared_pa, 1, ENC_BIG_ENDIAN); ++ if (shared_pa_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid shared pa value [0..1]"); ++ } ++ ++ ptvcursor_add(ptvc, hf_nfapi_maximum_total_power, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_oui, 3, ENC_HOST_ENDIAN); ++} ++static void dissect_pnf_rf_config_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_rf_config_index, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_pnf_phy_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ++ guint16 num_rf_configs = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rfs, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Config List", ett_nfapi_pnf_phy, num_rf_configs, dissect_pnf_rf_config_instance_value); ++ ++ guint16 num_rf_exclusions = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rf_exclusions, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Exclustion List", ett_nfapi_pnf_phy, num_rf_exclusions, dissect_pnf_rf_config_instance_value); ++ ++ // Downlink Channel Bandwidth Supported ++ guint16 downlink_channel_bandwidth_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add_no_advance(ptvc, hf_nfapi_downlink_channel_bandwidth_supported, 2, ENC_BIG_ENDIAN); ++ if (downlink_channel_bandwidth_supported_value > 0x3F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink channel bandwidht supported bits [0..0x3F]"); ++ } ++ ++ proto_tree* dl_bw_support_tree = proto_item_add_subtree(item, ett_nfapi_downlink_bandwidth_support); ++ ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_6, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_15, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_25, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_50, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_75, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_100, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++ ++ ++ ++ // Uplink Channel Bandwidth Supported ++ guint16 uplink_channel_bandwidth_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add_no_advance(ptvc, hf_nfapi_uplink_channel_bandwidth_supported, 2, ENC_BIG_ENDIAN); ++ if (uplink_channel_bandwidth_supported_value > 0x3F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid uplink channel bandwidht supported bits [0..0x3F]"); ++ } ++ ++ proto_tree* ul_bw_support_tree = proto_item_add_subtree(item, ett_nfapi_uplink_bandwidth_support); ++ ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_6, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_15, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_25, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_50, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_75, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_100, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++ ++ // Number of DL layers supported ++ guint8 number_of_dl_layer_supported_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_dl_layers_supported, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_dl_layer_supported_value == 1 || number_of_dl_layer_supported_value == 2 || ++ number_of_dl_layer_supported_value == 4 || number_of_dl_layer_supported_value == 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of dl layers supported value [1, 2, 4, 8]"); ++ } ++ ++ // Number of DL layers supported ++ guint8 number_of_ul_layer_supported_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ul_layers_supported, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_ul_layer_supported_value == 1 || number_of_ul_layer_supported_value == 2 || ++ number_of_ul_layer_supported_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ul layers supported value [1, 2, 4]"); ++ } ++ ++ // Maximum 3GPP Release Supported ++ guint16 maximum_3gpp_release_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add_no_advance(ptvc, hf_nfapi_maximum_3gpp_release_supported, 2, ENC_BIG_ENDIAN); ++ if (maximum_3gpp_release_supported_value > 0x3F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid maximum 3GPP release supported value [0..0x3F]"); ++ } ++ ++ proto_tree* release_support_tree = proto_item_add_subtree(item, ett_nfapi_release_support); ++ ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel8, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel9, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel10, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel11, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel12, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel13, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++ ++ ++ // NMM Modes Supported ++ guint8 nmm_modes_supported_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nmm_modes_supported, 1, ENC_BIG_ENDIAN); ++ if (nmm_modes_supported_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nmm modes supported value [0..3]"); ++ } ++} ++ ++static void dissect_pnf_phy_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_phy = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY List", ett_nfapi_pnf_phy, num_phy, dissect_pnf_phy_instance_value); ++} ++ ++static void dissect_pnf_rf_config_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ ptvcursor_add(ptvc, hf_nfapi_rf_config_index, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_band, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_transmit_power, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_minimum_transmit_power, 2, ENC_BIG_ENDIAN); ++ ++ guint8 number_of_antennas_supported_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_antennas_suppported, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_antennas_supported_value == 1 || number_of_antennas_supported_value == 2 || ++ number_of_antennas_supported_value == 4 || number_of_antennas_supported_value == 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of supported antennas [1, 2, 4, 8]"); ++ } ++ ++ ptvcursor_add(ptvc, hf_nfapi_minimum_downlink_frequency, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_downlink_frequency, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_minimum_uplink_frequency, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_maximum_uplink_frequency, 4, ENC_BIG_ENDIAN); ++} ++ ++ ++static void dissect_pnf_rf_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_rf = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rfs, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF List", ett_nfapi_pnf_phy_rf_config, num_rf, dissect_pnf_rf_config_value); ++} ++ ++static void dissect_pnf_phy_rel10_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PHY Config Index ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ++ // Transmission mode 7 supported ++ guint16 transmission_mode7_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_mode7_supported, 2, ENC_BIG_ENDIAN); ++ if (transmission_mode7_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode 7 supported value [0..1]"); ++ } ++ ++ // Two antennas ports for PUCCH ++ guint16 transmission_mode8_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_transmission_mode8_supported, 2, ENC_BIG_ENDIAN); ++ if (transmission_mode8_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode 8 supported value [0..1]"); ++ } ++ ++ // Transmission mode 8 supported ++ guint16 two_antennas_port_for_pucch_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_two_antennas_ports_for_pucch, 2, ENC_BIG_ENDIAN); ++ if (two_antennas_port_for_pucch_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid two antennas ports for pucch value [0..1]"); ++ } ++ ++ // Transmission mode 9 supported ++ guint16 transmission_mode9_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_transmission_mode_9_supported, 2, ENC_BIG_ENDIAN); ++ if (transmission_mode9_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode 9 supported value [0..1]"); ++ } ++ ++ // Simultaneous PUCCH PUSCH ++ guint16 simultaenous_pucch_pusch_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_simultaneous_pucch_pusch, 2, ENC_BIG_ENDIAN); ++ if (simultaenous_pucch_pusch_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid simultaneous pucch pusch supported value [0..1]"); ++ } ++ ++ // Four layer Tx with TM3 and TM4 ++ guint16 four_layer_tx_with_tm3_and_tm4_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_four_layer_tx_with_tm3_and_tm4, 2, ENC_BIG_ENDIAN); ++ if (four_layer_tx_with_tm3_and_tm4_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid four layer tx with tm3 and tm4 value [0..1]"); ++ } ++} ++ ++static void dissect_pnf_phy_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_phy = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY Rel 10 List", ett_nfapi_pnf_phy_rel10, num_phy, dissect_pnf_phy_rel10_instance_value); ++} ++ ++static void dissect_pnf_phy_rel11_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PHY Config Index ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ++ // ePDCCH supported ++ guint16 epdcch_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_epdcch_supported, 2, ENC_BIG_ENDIAN); ++ if (epdcch_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid edpcch supported value [0..1]"); ++ } ++ ++ // Multi ACK CSI reporting ++ guint16 multi_ack_csi_reporting_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_multi_ack_csi_reporting, 2, ENC_BIG_ENDIAN); ++ if (multi_ack_csi_reporting_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid multi ack csi reporting value [0..1]"); ++ } ++ ++ // PUCCH Tx diversity with channel selection ++ guint16 pucch_tx_diversity_with_channel_selection_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_pucch_tx_diversity_with_channel_selection, 2, ENC_BIG_ENDIAN); ++ if (pucch_tx_diversity_with_channel_selection_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch tx diversity with channel selection value [0..1]"); ++ } ++ ++ // UL CoMP supported ++ guint16 ul_comp_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_ul_comp_supported, 2, ENC_BIG_ENDIAN); ++ if (ul_comp_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul comp supported value [0..1]"); ++ } ++ ++ // Transmission mode 5 supported ++ guint16 transmission_mode_5_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_transmission_mode_5_supported, 2, ENC_BIG_ENDIAN); ++ if (transmission_mode_5_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode 5 supported value [0..1]"); ++ } ++} ++ ++static void dissect_pnf_phy_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_phy = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY Rel 11 List", ett_nfapi_pnf_phy_rel11, num_phy, dissect_pnf_phy_rel11_instance_value); ++} ++ ++static void dissect_pnf_phy_rel12_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PHY Config Index ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ++ // CSI subframe set ++ guint16 csi_subframe_set_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_subframe_set, 2, ENC_BIG_ENDIAN); ++ if (csi_subframe_set_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi subframe set value [0..1]"); ++ } ++ ++ // Enhanced 4TX codebook ++ guint16 enhanced_4tx_codebook_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_enhanced_4tx_codebook, 2, ENC_BIG_ENDIAN); ++ if (enhanced_4tx_codebook_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid enhanced 4TX codebook value [0..1]"); ++ } ++ ++ // DRS supported ++ guint16 drs_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_drs_supported, 2, ENC_BIG_ENDIAN); ++ if (drs_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drs supported value [0..1]"); ++ } ++ ++ // UL 64QAM supported ++ guint16 ul_64qam_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_ul_64qam_supported, 2, ENC_BIG_ENDIAN); ++ if (ul_64qam_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul 64 QAM supported value [0..1]"); ++ } ++ ++ // Transmission mode 10 supported ++ guint16 transmission_mode_10_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_transmission_mode_10_supported, 2, ENC_BIG_ENDIAN); ++ if (transmission_mode_10_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode 10 supported value [0..1]"); ++ } ++ ++ // Alternative TBS indices ++ guint16 alternative_tbs_indices_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hi_nfapi_alternative_tbs_indices, 2, ENC_BIG_ENDIAN); ++ if (alternative_tbs_indices_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid alternative tbs indicies supported value [0..1]"); ++ } ++} ++ ++static void dissect_pnf_phy_rel12_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_phy = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY Rel 12 List", ett_nfapi_pnf_phy_rel12, num_phy, dissect_pnf_phy_rel12_instance_value); ++} ++ ++static void dissect_pnf_phy_rel13_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PHY Config Index ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ++ // PUCCH format 4 supported ++ guint16 pucch_format_4_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pucch_format_4_supported, 2, ENC_BIG_ENDIAN); ++ if (pucch_format_4_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch format 4 supported value [0..1]"); ++ } ++ ++ // PUCCH format 5 supported ++ guint16 pucch_format_5_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pucch_format_5_supported, 2, ENC_BIG_ENDIAN); ++ if (pucch_format_5_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch format 5 supported value [0..1]"); ++ } ++ ++ // More than 5 CA support ++ guint16 more_than_5_ca_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_more_than_5_ca_supported, 2, ENC_BIG_ENDIAN); ++ if (more_than_5_ca_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid more than 5 ca supported value [0..1]"); ++ } ++ ++ // LAA supported ++ guint16 laa_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_laa_supported, 2, ENC_BIG_ENDIAN); ++ if (laa_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid laa supported value [0..1]"); ++ } ++ ++ // LAA ending in DwPTS supported ++ guint16 laa_ending_in_dwpts_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_laa_ending_in_dwpts_supported, 2, ENC_BIG_ENDIAN); ++ if (laa_ending_in_dwpts_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid laa ending in dwpts supported value [0..1]"); ++ } ++ ++ // LAA starting in second slot Supported ++ guint16 laa_starting_in_second_slot_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_laa_starting_in_second_slot_supported, 2, ENC_BIG_ENDIAN); ++ if (laa_starting_in_second_slot_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid laa starting in second slot supported value [0..1]"); ++ } ++ ++ // Beamforming Supported ++ guint16 beamingforming_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_beamforming_supported, 2, ENC_BIG_ENDIAN); ++ if (beamingforming_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid beamforming supported value [0..1]"); ++ } ++ ++ // CSI-RS enhancements supported ++ guint16 csi_rs_enhancements_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_enhancements_supported, 2, ENC_BIG_ENDIAN); ++ if (csi_rs_enhancements_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi rs enhancements supported value [0..1]"); ++ } ++ ++ // DMRS enhancements supported ++ guint16 drms_enhancements_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_enhancements_supported, 2, ENC_BIG_ENDIAN); ++ if (drms_enhancements_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms enhancements supported value [0..1]"); ++ } ++ ++ // SRS enhancements supported ++ guint16 srs_enhancements_supported_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_enhancements_supported, 2, ENC_BIG_ENDIAN); ++ if (srs_enhancements_supported_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs enhancements supported value [0..1]"); ++ } ++ ++} ++ ++static void dissect_pnf_phy_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_phy = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY Rel 13 List", ett_nfapi_pnf_phy_rel13, num_phy, dissect_pnf_phy_rel13_instance_value); ++} ++ ++static void dissect_pnf_phy_rf_config_instance_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_phy_rf_config_info_phy_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_config_index, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_rf_config_index, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_pnf_phy_rf_config_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_configs = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_phy_number_phy, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "PHY RF Config List", ett_nfapi_pnf_phy_rf_config, num_configs, dissect_pnf_phy_rf_config_instance_value); ++} ++ ++static void dissect_dl_rs_tx_power_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_dl_rs_tx_power, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value >= 1 && value <= 255)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value [1..255]"); ++ } ++} ++static void dissect_received_interference_power_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_received_interference_power, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value >= 1 && value <= 255)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value [1..255]"); ++ } ++} ++static void dissect_thermal_noise_power_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_thermal_noise_power, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_dl_rs_tx_power_measurement_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_dl_rs_tx_power_measurement, 2, ENC_BIG_ENDIAN); ++} ++ ++static void dissect_received_interference_power_result_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_received_interference_power_measurement, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_received_interference_power_measurement_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 num_resource_block = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_resource_blocks, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "Results", ett_nfapi_received_interference_power_mesurement_results, num_resource_block, dissect_received_interference_power_result_value); ++} ++static void dissect_thermal_noise_power_measurement_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_thermal_noise_power_measurement, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_duplex_mode_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_duplex_mode, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid duplex mode [0..2]"); ++ } ++} ++static void dissect_pcfich_power_offset_value(ptvcursor_t* ptvc, packet_info *pinfo) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pcfich_power_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid power level [0..10000]"); ++ } ++} ++static void dissect_pb_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pb, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink power allocation index [0..3]"); ++ } ++} ++ ++static void dissect_dl_cyclic_prefix_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_dl_cyclic_prefix_type, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dl cyclic prefix type [0..1]"); ++ } ++} ++static void dissect_ul_cyclic_prefix_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ul_cyclic_prefix_type, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul cyclic prefix type [0..1]"); ++ } ++} ++static void dissect_dl_channel_bandwidth_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_downlink_channel_bandwidth, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 6 || value == 15 || value == 25 || value == 50 || value == 75 || value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++} ++static void dissect_ul_channel_bandwidth_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_uplink_channel_bandwidth, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 6 || value == 15 || value == 25 || value == 50 || value == 75 || value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid uplink bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++} ++static void dissect_reference_signal_power_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_reference_signal_power, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid reference signal power [0..255]"); ++ } ++ ++} ++static void dissect_tx_antenna_ports_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_tx_antenna_ports, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tx antenna ports value [1, 2, 4, 8, 16]"); ++ } ++} ++static void dissect_rx_antenna_ports_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_rx_antenna_ports, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rx antenna ports value [1, 2, 4, 8, 16]"); ++ } ++} ++static void dissect_phich_resource_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_phich_resource, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid phich resource value [0..3]"); ++ } ++} ++static void dissect_phich_duration_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_phich_duration, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid phich duration value [0..1]"); ++ } ++} ++static void dissect_phich_power_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_phich_power_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid phich power offset value [0..10000]"); ++ } ++} ++static void dissect_psch_synch_signal_epre_eprers_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_primary_synchronization_signal_epre_eprers, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid primary synchronization signal epre/eprers value [0..10000]"); ++ } ++} ++static void dissect_physical_cell_id_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_physical_cell_id, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid physical cell id [0..503]"); ++ } ++} ++static void dissect_ssch_synch_signal_epre_eprers_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_secondary_synchronization_signal_epre_eprers, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid secondary synchronization signal epre/eprers value [0..10000]"); ++ } ++} ++static void dissect_prach_configuration_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_configuration_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach configuration index [0..63]"); ++ } ++} ++static void dissect_prach_root_sequence_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_root_sequence_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 837) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach root sequency index [0..837]"); ++ } ++} ++static void dissect_prach_zero_correlation_zone_configuration_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_zero_correlation_zone_configuration, 2, ENC_BIG_ENDIAN); ++ ++ // How do differentiate between fdd 0..6 and tdd 0..15 ranges? ++ if (value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid zero correlation zone configuration [0..15]"); ++ } ++} ++static void dissect_prach_high_speed_flag_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_high_speed_flag, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid high speed flag value [0..1]"); ++ } ++} ++static void dissect_prach_frequency_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ // How to determine the ul channel bandiwdth? ++ if (value > (100 -6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach frequency offset value [0..94]"); ++ } ++} ++static void dissect_pusch_hopping_mode_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_hopping_mode, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pusch hopping mode value [0..1]"); ++ } ++} ++static void dissect_pusch_hopping_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_hopping_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 98) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pusch hopping offset value [0..98]"); ++ } ++} ++static void dissect_pusch_number_of_subbands_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_number_of_subbands, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value >= 1 && value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of sub-bands [1..4]"); ++ } ++} ++static void dissect_pucch_delta_pucch_shift_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_delta_pucch_shift, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value >= 1 && value <= 3)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta pucch shift [1..3]"); ++ } ++} ++static void dissect_pucch_n_cqi_rb_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_n_cqi_rb, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 98) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n cqi rb value [0..98]"); ++ } ++} ++static void dissect_pucch_n_an_cs_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_n_an_cs, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n an cs value [0..7]"); ++ } ++} ++static void dissect_pucch_n1_pucch_an_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_n1_pucch_an, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n1pucch an value [0..2047]"); ++ } ++} ++static void dissect_srs_bandwidth_configuration_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_bandwidth_configuration, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs bandwidth configuration value [0..7]"); ++ } ++} ++static void dissect_srs_max_uppts_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_max_up_pts, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid max up pts value [0..1]"); ++ } ++} ++static void dissect_srs_subframe_configuration_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_srs_subframe_configuration, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs subframe configuration value [0..15]"); ++ } ++} ++static void dissect_srs_acknack_srs_sim_tx_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_srs_acknack_srs_simultaneous_transmission, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs ack nack srs simultaneous transmission value [0..1]"); ++ } ++} ++static void dissect_uplink_rs_hopping_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_uplink_rs_hopping, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid uplink rs hopping value [0..2]"); ++ } ++} ++static void dissect_group_assignment_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_group_assignment, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 29) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid group assignment value [0..29]"); ++ } ++} ++static void dissect_cyclic_shift_1_for_drms_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_cyclic_shift_1_for_drms, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cyclic shift 1 for drms value [0..7]"); ++ } ++} ++static void dissect_tdd_subframe_assignement_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_subframe_assignment, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 6) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tdd subframe assignment value [0..6]"); ++ } ++} ++static void dissect_tdd_subframe_patterns_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_special_subframe_patterns, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 9) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid special subframe pattern value [0..9]"); ++ } ++} ++static void dissect_laa_ed_threashold_for_lbt_for_pdsch_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ed_threshold_for_lbt_for_pdsch, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 70) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ed threshold for ltb for pdsch value [0..70]"); ++ } ++} ++static void dissect_laa_ed_threashold_for_lbt_for_drs_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ed_threshold_for_lbt_for_drs, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 70) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ed threshold for ltb for drs value [0..70]"); ++ } ++} ++static void dissect_laa_pd_threshold_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pd_threshold, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 70 && value != 65535) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pd threshold value [0..70, 65536]"); ++ } ++} ++static void dissect_laa_multi_carrier_type_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_multi_carrier_type, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mutli carrier type [0..4]"); ++ } ++} ++static void dissect_laa_multi_carrier_tx_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_multi_carrier_tx, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mutli carrier tx value [0..1]"); ++ } ++} ++static void dissect_laa_multi_carrier_freeze_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_multi_carrier_freeze, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mutli carrier freeze value [0..1]"); ++ } ++} ++static void dissect_laa_tx_antenna_port_for_drs_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_tx_antenna_ports_for_drs, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tx antenna ports for drs value [1, 2, 4]"); ++ } ++} ++static void dissect_laa_transmission_power_for_drs_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_transmission_power_for_drs, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power for drs [0..10000]"); ++ } ++} ++static void dissect_emtc_pbch_repeitions_enabled_r13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pbch_repetitions_enabled_r13, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pbch repetitions enabled r13 value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_cat_m_root_sequence_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_cat_m_root_sequence_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 837) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach cat-m root sequence index value [0..837]"); ++ } ++} ++static void dissect_emtc_prach_cat_m_zero_correlation_zone_configuration_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_cat_m_zero_correlation_zone_configuration, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach cat-m zero correlation zone configuration value [0..15]"); ++ } ++} ++static void dissect_emtc_prach_cat_m_high_speed_flag_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_cat_m_high_speed_flag, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach cat-m high speed flag value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_0_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_enable, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 enable value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_0_configuration_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_configuration_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 configuration index value [0..63]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_0_frequency_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > (100 - 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 frequency offset value [0..94]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_0_num_of_repeitions_per_attempt_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt, 2, ENC_BIG_ENDIAN); ++ ++ if (!( value == 1 || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 number of repetitions per attempt value [1, 2, 4, 8, 16, 32, 64, 128]"); ++ } ++} ++static void dissect_emtc_ce_level_0_starting_subframe_periodicity_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_starting_subframe_periodicity, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 0xFFF || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128 || value == 256)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 starting subframe periodicity value [2, 4, 8, 16, 32, 64, 128, 256, 0xFFFF]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_0_hopping_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_hopping_enabled, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 hopping enabled value [0..1]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_0_hopping_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_0_hopping_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 94) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #0 hopping offset value [0..94]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_1_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_enable, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 enable value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_1_configuration_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_configuration_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 configuration index value [0..63]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_1_frequency_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > (100 - 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 frequency offset value [0..94]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_1_num_of_repeitions_per_attempt_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 number of repetitions per attempt value [1, 2, 4, 8, 16, 32, 64, 128]"); ++ } ++} ++static void dissect_emtc_ce_level_1_starting_subframe_periodicity_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_starting_subframe_periodicity, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 0xFFF || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128 || value == 256)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 starting subframe periodicity value [2, 4, 8, 16, 32, 64, 128, 256, 0xFFFF]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_1_hopping_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_hopping_enabled, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 hopping enabled value [0..1]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_1_hopping_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_1_hopping_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 94) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #1 hopping offset value [0..94]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_2_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_enable, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 enable value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_2_configuration_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_configuration_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 configuration index value [0..63]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_2_frequency_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > (100 - 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 frequency offset value [0..94]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_2_num_of_repeitions_per_attempt_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 number of repetitions per attempt value [1, 2, 4, 8, 16, 32, 64, 128]"); ++ } ++} ++static void dissect_emtc_ce_level_2_starting_subframe_periodicity_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_starting_subframe_periodicity, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 0xFFF || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128 || value == 256)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 starting subframe periodicity value [2, 4, 8, 16, 32, 64, 128, 256, 0xFFFF]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_2_hopping_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_hopping_enabled, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 hopping enabled value [0..1]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_2_hopping_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_2_hopping_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 94) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 hopping offset value [0..94]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_3_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_enable, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 enable value [0..1]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_3_configuration_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_configuration_index, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #2 configuration index value [0..63]"); ++ } ++} ++static void dissect_emtc_prach_ce_level_3_frequency_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > (100 - 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 frequency offset value [0..94]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_3_num_of_repeitions_per_attempt_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 number of repetitions per attempt value [1, 2, 4, 8, 16, 32, 64, 128]"); ++ } ++} ++static void dissect_emtc_ce_level_3_starting_subframe_periodicity_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_starting_subframe_periodicity, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 0xFFF || value == 2 || value == 4 || value == 8 || value == 16 || value == 32 || ++ value == 64 || value == 128 || value == 256)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 starting subframe periodicity value [2, 4, 8, 16, 32, 64, 128, 256, 0xFFFF]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_3_hopping_enabled_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_hopping_enabled, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 hopping enabled value [0..1]"); ++ } ++} ++static void dissect_emtc_preach_ce_level_3_hopping_offset_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_prach_ce_level_3_hopping_offset, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 94) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach ce level #3 hopping offset value [0..94]"); ++ } ++} ++static void dissect_emtc_pucch_interval_ul_hopping_config_common_mode_a_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 5 || value == 10 || value == 20)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch internal ul hopping config common mode a value [1, 2, 4, 8] or [1, 5, 10, 20]"); ++ } ++} ++static void dissect_emtc_pucch_interval_ul_hopping_config_common_mode_b_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 2 || value == 4 || value == 8 || value == 16 || value == 5 || value == 10 || value == 20 || value == 40)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch internal ul hopping config common mode a value [2, 4, 8, 16] or [5, 10, 20, 40]"); ++ } ++} ++static void dissect_dl_bandwidth_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add_no_advance(ptvc, hf_nfapi_dl_bandwidth_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x1F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink bandwidth support bit [0..0x1F]"); ++ } ++ ++ proto_tree* dl_bw_support_tree = proto_item_add_subtree(item, ett_nfapi_downlink_bandwidth_support); ++ ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_6, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_15, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_25, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_50, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_75, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_bw_support_tree, hf_nfapi_dl_bandwidth_support_100, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++} ++static void dissect_ul_bandwidth_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add_no_advance(ptvc, hf_nfapi_ul_bandwidth_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x1F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid uplink bandwidth support bit [0..0x1F]"); ++ } ++ ++ proto_tree* ul_bw_support_tree = proto_item_add_subtree(item, ett_nfapi_uplink_bandwidth_support); ++ ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_6, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_15, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_25, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_50, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_75, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_bw_support_tree, hf_nfapi_ul_bandwidth_support_100, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++ ++} ++static void dissect_dl_modulation_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add_no_advance(ptvc, hf_nfapi_dl_modulation_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink modulation support bit [0..0x7]"); ++ } ++ ++ proto_tree* dl_mod_support_tree = proto_item_add_subtree(item, ett_nfapi_downlink_modulation_support); ++ ++ proto_tree_add_bits_item(dl_mod_support_tree, hf_nfapi_dl_modulation_support_qpsk, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_mod_support_tree, hf_nfapi_dl_modulation_support_16qam, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_mod_support_tree, hf_nfapi_dl_modulation_support_64qam, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(dl_mod_support_tree, hf_nfapi_dl_modulation_support_256qam, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++} ++static void dissect_ul_modulation_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add_no_advance(ptvc, hf_nfapi_ul_modulation_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid uplink modulation support bit [0..0x7]"); ++ } ++ ++ proto_tree* ul_mod_support_tree = proto_item_add_subtree(item, ett_nfapi_uplink_modulation_support); ++ ++ proto_tree_add_bits_item(ul_mod_support_tree, hf_nfapi_ul_modulation_support_qpsk, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_mod_support_tree, hf_nfapi_ul_modulation_support_16qam, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(ul_mod_support_tree, hf_nfapi_ul_modulation_support_64qam, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++} ++static void dissect_phy_antenna_capability_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_phy_antenna_capability, 2, ENC_BIG_ENDIAN); ++ ++ if (!(value == 1 || value == 2 || value == 4 || value == 8 || value == 16)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid phy antenna capability [1, 2, 4, 8, 16]"); ++ } ++} ++static void dissect_release_capability_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add_no_advance(ptvc, hf_nfapi_release_capability, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x3F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid release capability value [0..0x3F]"); ++ } ++ ++ proto_tree* release_support_tree = proto_item_add_subtree(item, ett_nfapi_release_support); ++ ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel8, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 15, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel9, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 14, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel10, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 13, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel11, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 12, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel12, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 11, 1, ENC_NA); ++ proto_tree_add_bits_item(release_support_tree, hf_nfapi_maximum_3gpp_release_supported_rel13, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8 + 10, 1, ENC_NA); ++ ++ ptvcursor_advance(ptvc, 2); ++} ++static void dissect_mbsfn_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_mbsfn_capability, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mbsfn capability bit [0..0x1]"); ++ } ++} ++static void dissect_laa_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_laa_capability, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid laa support bit [0..0x1]"); ++ } ++} ++static void dissect_laa_pd_sensing_lbt_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pd_sensing_lbt_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pd sensing lbt support bit [0..0x1]"); ++ } ++} ++static void dissect_laa_multi_carrier_lbt_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_multi_carrier_lbt_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0xF) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid multi carrier LBT support bit [0..0xF]"); ++ } ++} ++static void dissect_laa_partial_sf_support_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_partial_sf_support, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 0x1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid partial SF support bit [0..0x1]"); ++ } ++} ++static void dissect_data_report_mode_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_data_report_mode, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid data report mode value [0..1]"); ++ } ++} ++static void dissect_sfn_sf_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_sfnsf, 2, ENC_BIG_ENDIAN); ++ ++ guint16 sfn = value >> 0x4; ++ guint16 sf = value & 0x000F; ++ if (sfn > 1023 || sf > 9) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid sfn/sf value sfn:%d [0..1023] sf:%d [0..9]", sfn, sf); ++ } ++} ++static void dissect_phy_state_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_phy_state, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid phy state [0..2]"); ++ } ++} ++static void dissect_p7_vnf_address_ipv4_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_vnf_address_ipv4, 4, ENC_NA); ++} ++static void dissect_p7_vnf_address_ipv6_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_vnf_address_ipv6, 16, ENC_NA); ++} ++static void dissect_p7_vnf_port_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_vnf_port, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_p7_pnf_address_ipv4_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_pnf_address_ipv4, 4, ENC_NA); ++} ++static void dissect_p7_pnf_address_ipv6_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_pnf_address_ipv6, 16, ENC_NA); ++} ++static void dissect_p7_pnf_port_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_pnf_port, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_downlink_ues_per_subframe_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_dl_ue_per_sf, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_uplink_ues_per_subframe_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_ul_ue_per_sf, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_rf_band_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_band, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_rf_bands_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rf_bands, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Band List", ett_nfapi_rf_bands, count, dissect_rf_band_value); ++} ++static void dissect_timing_window_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_window, 1, ENC_BIG_ENDIAN); ++ ++ if (value > 30) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing window value [0..30]"); ++ } ++} ++static void dissect_timing_info_mode_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_info_mode, 1, ENC_BIG_ENDIAN); ++ ++ if (value > 0x3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing info mode [0..0x3]"); ++ } ++} ++static void dissect_timing_info_period_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_info_period, 1, ENC_BIG_ENDIAN); ++ ++ // Compiler throws an hissy fit that value <= 255 is always true... Yes, but I am trying to ++ // follow the specification... ++ if (!(value >= 1 /* && value <= 255*/)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing info period [1..255]"); ++ } ++} ++static void dissect_maximum_transmit_power_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_maximum_transmit_power_2, 2, ENC_BIG_ENDIAN); ++ ++ if (value > 700) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid maxiumum transmit power [0..700]"); ++ } ++} ++static void dissect_earfcn_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_earfcn, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_nmm_gsm_frequency_bands_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rf_bands, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Band List", ett_nfapi_rf_bands, count, dissect_rf_band_value); ++} ++static void dissect_nmm_umts_frequency_bands_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rf_bands, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Band List", ett_nfapi_rf_bands, count, dissect_rf_band_value); ++} ++static void dissect_nmm_lte_frequency_bands_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rf_bands, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "RF Band List", ett_nfapi_rf_bands, count, dissect_rf_band_value); ++} ++static void dissect_nmm_uplink_rssi_supported_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_nmm_uplink_rssi_supported, 1, ENC_BIG_ENDIAN); ++ ++ if (value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nmm uplink rssi supported value [0..1]"); ++ } ++} ++static void dissect_dl_config_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_dl_config_pdu_type, 1, ENC_BIG_ENDIAN); ++ guint8 size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_size, 1, ENC_BIG_ENDIAN); ++ ++ guint pdu_end = (ptvcursor_current_offset(ptvc) + size - 2); ++ dissect_tlv_list(ptvc, pinfo, pdu_end); ++} ++static void dissect_dl_config_request_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Number of PDCCH OFDM symbols ++ guint8 number_of_pdcch_ofdm_symbols_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_pdcch_ofdm_symbols, 1, ENC_BIG_ENDIAN); ++ if (number_of_pdcch_ofdm_symbols_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pdcch ofdm symbols value [0..4]"); ++ } ++ ++ // Number of DCIs ++ guint8 number_of_dcis_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_dci, 1, ENC_BIG_ENDIAN); ++ ++ // Number of PDUs ++ guint16 number_of_pdus_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_pdus, 2, ENC_BIG_ENDIAN); ++ if (number_of_pdus_value > 514) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pdus value [0..514]"); ++ } ++ ++ // Number of PDSCH RNTIs ++ ptvcursor_add(ptvc, hf_nfapi_number_pdsch_rnti, 1, ENC_BIG_ENDIAN); ++ ++ // Transmission power for PCFICH ++ guint16 transmission_power_for_pdsch_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power_pcfich, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_for_pdsch_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power for pcfich value [0..10000]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "DL Config PDU List", ett_nfapi_dl_config_request_pdu_list, number_of_dcis_value + number_of_pdus_value, dissect_dl_config_pdu); ++} ++static void dissect_dl_config_request_bch_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // PDU index ++ ptvcursor_add(ptvc, hf_nfapi_pdu_index, 2, ENC_BIG_ENDIAN); ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DCI format ++ guint8 dci_format_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dl_dci_format, 1, ENC_BIG_ENDIAN); ++ if (dci_format_value > 9) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci format value [0..9]"); ++ } ++ ++ // CCE index ++ guint8 cce_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cce_idx, 1, ENC_BIG_ENDIAN); ++ if (cce_index_value > 88) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cce index value [0..88]"); ++ } ++ ++ // Aggregation level ++ guint8 aggregation_level_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_aggregation_level, 1, ENC_BIG_ENDIAN); ++ if (!(aggregation_level_value == 1 || aggregation_level_value == 2 || aggregation_level_value == 4 || ++ aggregation_level_value == 8 || aggregation_level_value == 16 || aggregation_level_value == 32)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid aggregation level value [1, 2, 4, 8, 16, 32]"); ++ } ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // Resource allocation type ++ guint8 resource_allocation_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ if (resource_allocation_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocation type value [0..1]"); ++ } ++ ++ // Virtual resource block assignment flag ++ guint8 virtual_resource_block_assignment_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_virtual_resource_block_assignment_flag, 1, ENC_BIG_ENDIAN); ++ if (virtual_resource_block_assignment_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid virtual resource block assignment flag value [0..1]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ++ // MCS_1 ++ guint8 mcs_1_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs_1, 1, ENC_BIG_ENDIAN); ++ if (mcs_1_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs 1 value [0..31]"); ++ } ++ ++ // Redundancy version_1 ++ guint8 redundancy_version_1_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version_1, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_1_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy version 1 value [0..3]"); ++ } ++ ++ // New data indicator_1 ++ guint8 new_data_indicator_1_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indicator_1, 1, ENC_BIG_ENDIAN); ++ if (new_data_indicator_1_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indicator 1 value [0..1]"); ++ } ++ ++ // Transport block to codeword swap flag ++ guint8 transport_block_to_codeword_swap_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transport_block_to_codeword_swap_flag, 1, ENC_BIG_ENDIAN); ++ if (transport_block_to_codeword_swap_flag_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport block to codeword swap flag value [0..1]"); ++ } ++ ++ // MCS_2 ++ guint8 mcs_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs_2, 1, ENC_BIG_ENDIAN); ++ if (mcs_2_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs 2 value [0..31]"); ++ } ++ ++ // Redundancy version_2 ++ guint8 redundancy_version_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version_2, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_2_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy version 2 value [0..3]"); ++ } ++ ++ // New Data indicator_2 ++ guint8 new_data_indicator_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indicator_2, 1, ENC_BIG_ENDIAN); ++ if (new_data_indicator_2_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indicator 2 value [0..1]"); ++ } ++ ++ // HARQ process ++ guint8 harq_process_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_process, 1, ENC_BIG_ENDIAN); ++ if (harq_process_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq process value [0..15]"); ++ } ++ ++ // TPMI ++ guint8 tpmi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpmi, 1, ENC_BIG_ENDIAN); ++ if (tpmi_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi value [0..3]"); ++ } ++ ++ // PMI ++ guint8 pmi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pmi, 1, ENC_BIG_ENDIAN); ++ if (pmi_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi value [0..2]"); ++ } ++ ++ // Precoding information ++ guint8 precoding_information_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_precoding_information, 1, ENC_BIG_ENDIAN); ++ if (precoding_information_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid precoding information value [0..15]"); ++ } ++ ++ // TPC ++ guint8 tpc_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpc, 1, ENC_BIG_ENDIAN); ++ if (tpc_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpc value [0..3]"); ++ } ++ ++ // Downlink assignment index ++ guint8 downlink_assignment_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_downlink_assignment_index, 1, ENC_BIG_ENDIAN); ++ if (downlink_assignment_index_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink assignment value [0..15]"); ++ } ++ ++ // NGAP ++ guint8 ngap_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ngap, 1, ENC_BIG_ENDIAN); ++ if (ngap_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ngap value [0..1]"); ++ } ++ ++ // Transport block size index ++ guint8 transport_block_size_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transport_block_size_index, 1, ENC_BIG_ENDIAN); ++ if (transport_block_size_index_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport block size index value [0..31]"); ++ } ++ ++ // Downlink power offset ++ guint8 downlink_power_offset_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_downlink_power_offset, 1, ENC_BIG_ENDIAN); ++ if (downlink_power_offset_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink power offset value [0..1]"); ++ } ++ ++ // Allocate PRACH flag ++ guint8 allocate_prach_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_allocate_prach_flag, 1, ENC_BIG_ENDIAN); ++ if (allocate_prach_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid allocate prach flag value [0..1]"); ++ } ++ ++ // Preamble index ++ guint8 preamble_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_preamble_index, 1, ENC_BIG_ENDIAN); ++ if (preamble_index_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid preamble index value [0..63]"); ++ } ++ ++ // PRACH mask index ++ guint8 prach_mask_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_prach_mask_index, 1, ENC_BIG_ENDIAN); ++ if (prach_mask_index_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach mask index value [0..15]"); ++ } ++ ++ // RNTI type ++ guint8 rnti_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti_type, 1, ENC_BIG_ENDIAN); ++ if (!(rnti_type_value >= 1 && rnti_type_value <= 3)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti type value [1..3]"); ++ } ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value value [0..10000]"); ++ } ++ ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // MCCH flag ++ guint8 mcch_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcch_flag, 1, ENC_BIG_ENDIAN); ++ if (mcch_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcch flag value [0..1]"); ++ } ++ ++ // MCCH change notification ++ ptvcursor_add(ptvc, hf_nfapi_mcch_change_notification, 1, ENC_BIG_ENDIAN); ++ ++ // Scrambling identity ++ guint8 scrambling_identity_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_scrambling_identity, 1, ENC_BIG_ENDIAN); ++ if (scrambling_identity_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid scrambling identity value [0..1]"); ++ } ++ ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Cross carrier scheduling flag ++ guint8 cross_carrier_scheduling_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cross_carrier_scheduling_flag, 1, ENC_BIG_ENDIAN); ++ if (cross_carrier_scheduling_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cross carrier scheduling flag value [0..1]"); ++ } ++ ++ // Carrier indicator ++ guint8 carrier_indicator_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_carrier_indicator, 1, ENC_BIG_ENDIAN); ++ if (carrier_indicator_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid carrier indicator value [0..7]"); ++ } ++ ++ // SRS flag ++ guint8 srs_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_flag, 1, ENC_BIG_ENDIAN); ++ if (srs_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs flag value [0..1]"); ++ } ++ ++ // SRS request ++ guint8 srs_request_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_request, 1, ENC_BIG_ENDIAN); ++ if (srs_request_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs request value [0..1]"); ++ } ++ ++ // Antenna ports, scrambling and layers ++ guint8 antenna_ports_scrambling_and_layers_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_antenna_ports_scrambling_and_layers, 1, ENC_BIG_ENDIAN); ++ if (antenna_ports_scrambling_and_layers_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid antenna ports scrambling and layers value [0..15]"); ++ } ++ ++ // Total DCI length including padding ++ ptvcursor_add(ptvc, hf_nfapi_total_dci_length_including_padding, 1, ENC_BIG_ENDIAN); ++ ++ // N_DL_RB ++ // TODO : This is missing from the encoder.... ++ //ptvcursor_add(ptvc, hf_nfapi_n_dl_rb, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // HARQ-ACK resource offset ++ guint8 harq_ack_resource_offset_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_ack_resource_offset, 1, ENC_BIG_ENDIAN); ++ if (harq_ack_resource_offset_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid hack ack resource offset value [0..3]"); ++ } ++ ++ // PDSCH RE Mapping and Quasi-Co-Location Indicator ++ guint8 pdsch_re_mapping_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator, 1, ENC_BIG_ENDIAN); ++ if (pdsch_re_mapping_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch re mapping value [0..3]"); ++ } ++ ++} ++static void dissect_ul_dl_configuration_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UL/DL configuration indication ++ guint8 ul_dl_configuration_indication_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ul_dl_configuration_index, 1, ENC_BIG_ENDIAN); ++ if (!(ul_dl_configuration_indication_value >= 1 && ul_dl_configuration_indication_value <= 5)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul/dl configuration indication value [1..5]"); ++ } ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel12_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Primary cell type ++ guint8 primary_cell_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_primary_cell_type, 1, ENC_BIG_ENDIAN); ++ if (primary_cell_type_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid primary cell type value [0..2]"); ++ } ++ ++ // UL/DL configuration flag ++ guint8 ul_dl_configuration_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_dl_configuration_flag, 1, ENC_BIG_ENDIAN); ++ if (ul_dl_configuration_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul/dl configuration flag value [0..1]"); ++ } ++ ++ // Number of UL / DL configurations ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ul_dl_configurations, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "UL/DL Configurations", ett_nfapi_pnf_phy, count, dissect_ul_dl_configuration_index_value); ++} ++static void dissect_dl_config_request_dl_dci_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_laa_end_partial_sf_flag, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_laa_end_partial_sf_configuration, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_initial_lbt_sf, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_codebooksize_determination_r13, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_rel13_drms_table_flag, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_dl_config_request_mch_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_index, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_modulation, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_mbsfn_area_id, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_codebook_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 codebook_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_codebook_index, 1, ENC_BIG_ENDIAN); ++ if (codebook_index_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid codebook index value [0..15]"); ++ } ++} ++static void dissect_bf_vector_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_bf_vector_bf_value, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_bf_vector_type_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_bf_vector_subband_index, 1, ENC_BIG_ENDIAN); ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_bf_vector_num_antennas, 1, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "Antennas", ett_nfapi_bf_vector_antennas, count, dissect_bf_vector_value); ++} ++static void dissect_dl_config_request_dlsch_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // PDU index ++ ptvcursor_add(ptvc, hf_nfapi_pdu_index, 2, ENC_BIG_ENDIAN); ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (!(rnti_value >= 1 /* && rnti_value <= 65535)*/)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid codebook index value [1..65535]"); ++ } ++ ++ // Resource allocation type ++ guint8 resource_allocation_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ if (resource_allocation_type_value > 5) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocation type value [0..5]"); ++ } ++ ++ // Virtual resource block assignment flag ++ guint8 virtual_resource_block_assignment_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_virtual_resource_block_assignment_flag, 1, ENC_BIG_ENDIAN); ++ if (virtual_resource_block_assignment_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid virtual resource block allocation assignment value [0..1]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ++ // Modulation ++ guint8 modulation_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_modulation, 1, ENC_BIG_ENDIAN); ++ if (!(modulation_value == 2 || modulation_value == 4 || modulation_value == 6 || modulation_value == 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid modulation value [2, 4, 6, 8]"); ++ } ++ ++ // Redundancy version ++ guint8 redundancy_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version, 1, ENC_BIG_ENDIAN); ++ if (redundancy_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy value [0..3]"); ++ } ++ ++ // Transport blocks ++ guint8 transport_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transport_blocks, 1, ENC_BIG_ENDIAN); ++ if (!(transport_blocks_value >= 1 && transport_blocks_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport blocks value [1..2]"); ++ } ++ ++ // Transport block to codeword swap flag ++ guint8 transport_blocks_to_codeword_swap_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transport_block_to_codeword_swap_flag, 1, ENC_BIG_ENDIAN); ++ if (transport_blocks_to_codeword_swap_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport block to codeword swap flag value [0..1]"); ++ } ++ ++ // Transmission scheme ++ guint8 transmission_scheme_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_scheme, 1, ENC_BIG_ENDIAN); ++ if (transmission_scheme_value > 13) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission scheme value [0..13]"); ++ } ++ ++ // Number of layers ++ guint8 number_of_layers_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_layers, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_layers_value >= 1 && number_of_layers_value <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of layers value [1..8]"); ++ } ++ ++ // Number of subbands ++ guint8 num_subbands = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_subbands, 1, ENC_BIG_ENDIAN); ++ if (num_subbands > 13) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of subbands value [0..13]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "Subbands", ett_nfapi_subbands, num_subbands, dissect_codebook_index_value); ++ ++ // UE category capacity ++ guint8 ue_category_capacity_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_category_capacity, 1, ENC_BIG_ENDIAN); ++ if (ue_category_capacity_value > 14) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue category capacity value [0..14]"); ++ } ++ ++ // P-A ++ guint8 pa_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pa, 1, ENC_BIG_ENDIAN); ++ if (pa_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid p-a value [0..7]"); ++ } ++ ++ // Delta power offset index ++ guint8 delta_power_offset_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_power_offset_index, 1, ENC_BIG_ENDIAN); ++ if (delta_power_offset_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta power offset value [0..1]"); ++ } ++ ++ // NGAP ++ guint8 ngap_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ngap, 1, ENC_BIG_ENDIAN); ++ if (ngap_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ngap value [0..1]"); ++ } ++ ++ // NPRB ++ guint8 nrpb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nprb, 1, ENC_BIG_ENDIAN); ++ if (nrpb_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nprb value [0..1]"); ++ } ++ ++ // Transmission mode ++ guint8 transmission_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_mode, 1, ENC_BIG_ENDIAN); ++ if (!(transmission_mode_value >= 1 && transmission_mode_value <= 10)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission mode value [1..10]"); ++ } ++ ++ // numBfPRBperSubband ++ ptvcursor_add(ptvc, hf_nfapi_num_bf_prb_per_subband, 1, ENC_BIG_ENDIAN); ++ ++ // numBfVector ++ guint8 num_vectors = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_num_bf_vector, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "Beamforming Vectors", ett_nfapi_bf_vectors, num_vectors, dissect_bf_vector_type_value); ++} ++static void dissect_csi_rs_resource_config_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 csi_rs_resource_config_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_resource_config, 1, ENC_BIG_ENDIAN); ++ if (csi_rs_resource_config_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi-rs resource config value [0..31]"); ++ } ++} ++static void dissect_dl_config_request_dlsch_pdu_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 nscid_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_nscid, 1, ENC_BIG_ENDIAN); ++ if (nscid_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nscid value [0..1]"); ++ } ++} ++static void dissect_dl_config_request_dlsch_pdu_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // CSI-RS flag ++ guint8 csi_rs_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_flag, 1, ENC_BIG_ENDIAN); ++ if (csi_rs_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi-rs flag value [0..1]"); ++ } ++ ++ // CSI-RS resource config R10 ++ ptvcursor_add(ptvc, hf_nfapi_csi_rs_resource_config_r10, 1, ENC_BIG_ENDIAN); ++ ++ // CSI-RS zero Tx power resource config bitmap R10 ++ ptvcursor_add(ptvc, hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, 2, ENC_BIG_ENDIAN); ++ ++ // CSI-RS Number of NZP configuration ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_number_of_nzp_configurations, 1, ENC_BIG_ENDIAN); ++ if (count > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi-rs number of nzp configuration value [0..3]"); ++ } ++ ++ // CSI-RS configuration ++ dissect_array_value(ptvc, pinfo, "CSI-RS Resource Configs", ett_nfapi_csi_rs_resource_configs, count, dissect_csi_rs_resource_config_value); ++ ++ // PDSCH start ++ guint8 pdsch_start_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdsch_start, 1, ENC_BIG_ENDIAN); ++ if (pdsch_start_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch start value [0..4]"); ++ } ++ ++} ++static void dissect_dl_config_request_dlsch_pdu_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DMRS Config flag ++ guint8 drms_config_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_config_flag, 1, ENC_BIG_ENDIAN); ++ if (drms_config_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms config flag value [0..1]"); ++ } ++ ++ // DMRS-Scrambling ++ guint16 drms_scrambling_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_scrambling, 2, ENC_BIG_ENDIAN); ++ if (drms_scrambling_value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms scrambling value [0..503]"); ++ } ++ ++ // CSI Config flag ++ guint8 csi_config_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_config_flag, 1, ENC_BIG_ENDIAN); ++ if (csi_config_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi config flag value [0..1]"); ++ } ++ ++ // CSI- Scrambling ++ guint16 csi_scrambling_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_scrambling, 2, ENC_BIG_ENDIAN); ++ if (csi_scrambling_value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi scrambling value [0..503]"); ++ } ++ ++ // PDSCH RE mapping flag ++ guint8 pdsch_re_mapping_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_re_mapping_flag, 1, ENC_BIG_ENDIAN); ++ if (pdsch_re_mapping_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch re mapping flag value [0..1]"); ++ } ++ ++ // PDSCH RE mapping antenna ports ++ guint8 pdsch_re_mapping_antenna_ports_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_re_mapping_antenna_ports, 1, ENC_BIG_ENDIAN); ++ if (!(pdsch_re_mapping_antenna_ports_value == 1 || pdsch_re_mapping_antenna_ports_value == 2 || ++ pdsch_re_mapping_antenna_ports_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch re mapping antenna ports value [1, 2, 4]"); ++ } ++ ++ // PDSCH RE mapping freq shift ++ guint8 pdsch_re_mapping_freq_shift_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_re_mapping_freq_shift, 1, ENC_BIG_ENDIAN); ++ if (pdsch_re_mapping_freq_shift_value > 5) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch re mapping freq shift value [0..5]"); ++ } ++} ++static void dissect_dl_config_request_dlsch_pdu_rel12_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // altCQI-Table-r12 ++ guint8 alt_cqi_table_r12_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_alt_cqi_table_r12, 1, ENC_BIG_ENDIAN); ++ if (alt_cqi_table_r12_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid alt cqi table r12 value [0..1]"); ++ } ++ ++ // MaxLayers ++ guint8 max_layers_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_max_layers, 1, ENC_BIG_ENDIAN); ++ if (!(max_layers_value >= 1 && max_layers_value <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid max layers value [1..8]"); ++ } ++ ++ ptvcursor_add(ptvc, hf_nfapi_n_dl_harq, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_dl_config_request_dlsch_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DwPTS Symbols ++ guint8 dwpts_symbols_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dwpts_symbols, 1, ENC_BIG_ENDIAN); ++ if (!(dwpts_symbols_value == 3 || dwpts_symbols_value == 6 || dwpts_symbols_value == 9 || ++ dwpts_symbols_value == 10 || dwpts_symbols_value == 11 || dwpts_symbols_value == 12 || ++ dwpts_symbols_value == 14)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dwpts symbols value [3, 6, 9, 10, 11, 12, 14]"); ++ } ++ ++ // Initial LBT SF ++ guint8 initial_lbt_sf_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_lbt_sf, 1, ENC_BIG_ENDIAN); ++ if (initial_lbt_sf_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial lbt sf value [0..1]"); ++ } ++ ++ // UE Type ++ guint8 ue_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_type, 1, ENC_BIG_ENDIAN); ++ if (ue_type_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue type value [0..2]"); ++ } ++ ++ // PDSCH Payload Type ++ guint8 pdsch_payload_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_payload_type, 1, ENC_BIG_ENDIAN); ++ if (pdsch_payload_type_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch payload type value [0..2]"); ++ } ++ ++ // Initial transmission SF (io) ++ guint16 initial_transmission_sf_io_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_transmission_sf, 2, ENC_BIG_ENDIAN); ++ if (!(initial_transmission_sf_io_value <= 10239 || initial_transmission_sf_io_value == 0xFFFF)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial transmission sf io value [0..10239, 0xFFFF]"); ++ } ++ ++ // Rel-13-DMRS-tabe flag ++ guint8 rel13_drms_table_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_req13_drms_table_flag, 1, ENC_BIG_ENDIAN); ++ if (rel13_drms_table_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rel13 drms table flag value [0..1]"); ++ } ++} ++static void dissect_dl_config_request_pch_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // PDU index ++ ptvcursor_add(ptvc, hf_nfapi_pdu_index, 2, ENC_BIG_ENDIAN); ++ ++ // P-RNTI ++ guint16 prnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_prnti, 2, ENC_BIG_ENDIAN); ++ if (prnti_value != 0xFFFE) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prnti value [0xFFFE]"); ++ } ++ ++ // Resource allocation type ++ guint8 resource_allocation_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ if (!(resource_allocation_type_value == 2 || resource_allocation_type_value == 3 || resource_allocation_type_value == 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocate type value [2, 3, 6]"); ++ } ++ ++ // Virtual resource block assignment flag ++ guint8 virtual_resource_block_assignment_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_virtual_resource_block_assignment_flag, 1, ENC_BIG_ENDIAN); ++ if (virtual_resource_block_assignment_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid virtual resource block assignment flag value [0..1]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ++ // MCS ++ guint8 mcs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs, 1, ENC_BIG_ENDIAN); ++ if (mcs_value != 0) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs value [0]"); ++ } ++ ++ // Redundancy version ++ guint8 redundancy_version_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_value != 0) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy value [0]"); ++ } ++ ++ // Number of transport blocks ++ guint8 number_of_transport_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_transport_blocks, 1, ENC_BIG_ENDIAN); ++ if (number_of_transport_blocks_value != 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport blocks value [1]"); ++ } ++ ++ // Transport block to codeword swap flag ++ ptvcursor_add(ptvc, hf_nfapi_transport_block_to_codeword_swap_flag, 1, ENC_BIG_ENDIAN); ++ ++ // Transmission scheme ++ guint8 transmission_scheme_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_scheme, 1, ENC_BIG_ENDIAN); ++ if (!(transmission_scheme_value == 0 || transmission_scheme_value == 1 || transmission_scheme_value == 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission schemes value [0, 1, 6]"); ++ } ++ ++ // Number of layers ++ guint8 number_of_layers_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_layers, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_layers_value >= 1 && number_of_layers_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of layers value [1..4]"); ++ } ++ ++ // Codebook index ++ ptvcursor_add(ptvc, hf_nfapi_codebook_index, 1, ENC_BIG_ENDIAN); ++ ++ // UE category capacity ++ guint8 ue_category_capacity_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_category_capacity, 1, ENC_BIG_ENDIAN); ++ if (ue_category_capacity_value > 14) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue category capacity value [0..14]"); ++ } ++ ++ // P-A ++ guint8 p_a_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pa, 1, ENC_BIG_ENDIAN); ++ if (p_a_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid p-a value value [0..7]"); ++ } ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++ // NPRB ++ guint8 nprb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nprb, 1, ENC_BIG_ENDIAN); ++ if (nprb_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid nprb value [0..1]"); ++ } ++ ++ // NGAP ++ guint8 ngap_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ngap, 1, ENC_BIG_ENDIAN); ++ if (ngap_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ngap value [0..1]"); ++ } ++ ++} ++static void dissect_dl_config_request_pch_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // UE mode ++ guint8 ue_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_mode, 1, ENC_BIG_ENDIAN); ++ if (ue_mode_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue mode value [0..1]"); ++ } ++ ++ // Initial transmission SF (io) ++ guint16 initial_transmission_sf_io_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_transmission_sf, 2, ENC_BIG_ENDIAN); ++ if (!(initial_transmission_sf_io_value <= 10239 || initial_transmission_sf_io_value == 0xFFFF)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial transmission sf io value [0..10239, 0xFFFF]"); ++ } ++} ++static void dissect_dl_config_request_prs_pdu_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++ // PRS bandwidth ++ guint8 prs_bandwidth_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_prs_bandwidth, 1, ENC_BIG_ENDIAN); ++ if (!(prs_bandwidth_value == 6 || prs_bandwidth_value == 15 || prs_bandwidth_value == 25 || ++ prs_bandwidth_value == 50 || prs_bandwidth_value == 75 || prs_bandwidth_value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prs bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++ ++ // PRS cyclic prefix type ++ guint8 prs_cyclic_prefix_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_prs_cyclic_prefix_type, 1, ENC_BIG_ENDIAN); ++ if (prs_cyclic_prefix_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prs cyclic prefix value [0..1]"); ++ } ++ ++ // PRS muting ++ guint8 prs_muting_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_prs_muting, 1, ENC_BIG_ENDIAN); ++ if (prs_muting_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prs muting value [0..1]"); ++ } ++} ++static void dissect_dl_config_request_csi_rs_pdu_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // CSI-RS antenna port count R10 ++ guint8 csi_rs_antenna_port_count_r10_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_antenna_port_count_r10, 1, ENC_BIG_ENDIAN); ++ if (!(csi_rs_antenna_port_count_r10_value == 1 || csi_rs_antenna_port_count_r10_value == 2 || ++ csi_rs_antenna_port_count_r10_value == 4 || csi_rs_antenna_port_count_r10_value == 8 || ++ csi_rs_antenna_port_count_r10_value == 12 || csi_rs_antenna_port_count_r10_value == 16)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi rs antenna port count r10 value [1, 2, 4, 6, 8, 10]"); ++ } ++ ++ // CSI-RS resource config R10 ++ ptvcursor_add(ptvc, hf_nfapi_csi_rs_resource_config_r10, 1, ENC_BIG_ENDIAN); ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++ // CSI-RS zero Tx power resource config bitmap R10 ++ ptvcursor_add(ptvc, hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, 2, ENC_BIG_ENDIAN); ++ ++ // CSI-RS Number of NZP configuration ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_number_of_nzp_configurations, 1, ENC_BIG_ENDIAN); ++ if (count > 8) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi-rs number of nzp configuration value [0..8]"); ++ } ++ ++ // CSI-RS configuration ++ dissect_array_value(ptvc, pinfo, "CSI-RS Resource Configs", ett_nfapi_csi_rs_resource_configs, count, dissect_csi_rs_resource_config_value); ++} ++static void dissect_csi_rs_bf_vector_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_resource_index, 1, ENC_BIG_ENDIAN); ++ if (count > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi-rs resource index value [0..7]"); ++ } ++ ++ // todo : how to work out the antenna port count for the bfValue ++} ++static void dissect_dl_config_request_csi_rs_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Class ++ guint8 class_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_rs_class, 1, ENC_BIG_ENDIAN); ++ if (class_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid class value [0..2]"); ++ } ++ ++ // cdmType ++ guint8 cdm_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cdm_type, 1, ENC_BIG_ENDIAN); ++ if (cdm_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cdm type value [0..1]"); ++ } ++ ++ // numBfVector ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_num_bf_vector, 1, ENC_BIG_ENDIAN); ++ if (!((class_value == 1 && count == 0) || (class_value == 2 && count <= 8))) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid num bf vector value [0] or [0..8]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "Beamforming Vector", ett_nfapi_csi_rs_bf_vector, count, dissect_csi_rs_bf_vector_value); ++} ++static void dissect_epdcch_prb_index_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // EPDCCH PRB index ++ guint8 epdcch_prb_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_edpcch_prb_index, 1, ENC_BIG_ENDIAN); ++ if (epdcch_prb_index_value > 99) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid epdcch prb_index value [0..99]"); ++ } ++} ++static void dissect_dl_config_request_edpcch_params_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // EPDCCH Resource assignment flag ++ guint8 epdcch_resource_assignment_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_epdcch_resource_assignment_flag, 1, ENC_BIG_ENDIAN); ++ if (epdcch_resource_assignment_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid epdcch resource assignment flag value [0..1]"); ++ } ++ ++ // EPDCCH ID ++ guint16 epdcch_id_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_epdcch_id, 2, ENC_BIG_ENDIAN); ++ if (epdcch_id_value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid epdcch id value [0..503]"); ++ } ++ ++ // EPDCCH Start Symbol ++ guint8 epdcch_start_symbol_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_epdcch_start_symbol, 1, ENC_BIG_ENDIAN); ++ if (!(epdcch_start_symbol_value >= 1 && epdcch_start_symbol_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid epdcch start symbol value [1..4]"); ++ } ++ ++ // EPDCCH NumPRB ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_epdcch_num_prb, 1, ENC_BIG_ENDIAN); ++ if (!(count == 2 || count == 4 || count == 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid epdcch num prb value [2, 4, 8]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "PRBs", ett_nfapi_epdcch_prbs, count, dissect_epdcch_prb_index_value); ++ ++ dissect_bf_vector_type_value(ptvc, pinfo); ++} ++static void dissect_dl_config_request_edpcch_params_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DwPTS Symbols ++ guint8 dwtps_symbols_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_lbt_sf, 1, ENC_BIG_ENDIAN); ++ if (!(dwtps_symbols_value == 3 || dwtps_symbols_value == 6 || dwtps_symbols_value == 9 || ++ dwtps_symbols_value == 10 || dwtps_symbols_value == 11 || dwtps_symbols_value == 12 || ++ dwtps_symbols_value == 14)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dwpts symbols value [3, 6, 9, 10, 11, 12, 14]"); ++ } ++ ++ // Initial LBT SF ++ guint8 initial_lbt_sf_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dwpts_symbols, 1, ENC_BIG_ENDIAN); ++ if (initial_lbt_sf_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial lbt sf value [0..1]"); ++ } ++ ++} ++static void dissect_precoding_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add(ptvc, hf_nfapi_precoding_value, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_dl_config_request_mpdpcch_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // MPDCCH Narrowband ++ guint8 mpdcch_narrowband_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_narrowband, 1, ENC_BIG_ENDIAN); ++ if (mpdcch_narrowband_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mpdcch narrowband value [0..15]"); ++ } ++ ++ // Number of PRB pairs ++ guint8 number_of_prb_pair_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_prb_pairs, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_prb_pair_value == 2 || number_of_prb_pair_value == 4 || number_of_prb_pair_value == 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of prb pair value [2, 4, 6]"); ++ } ++ ++ // Resource Block Assignment ++ guint8 resource_block_assignment_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_assignment, 1, ENC_BIG_ENDIAN); ++ if (resource_block_assignment_value > 14) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block assignment value [0..14]"); ++ } ++ ++ // MPDCCH transmission type ++ guint8 mpdcch_transmission_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_transmission_type, 1, ENC_BIG_ENDIAN); ++ if (mpdcch_transmission_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mpdcch transmission type value [0..1]"); ++ } ++ ++ // Start symbol ++ guint8 start_symbol_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_start_symbol, 1, ENC_BIG_ENDIAN); ++ if (!(start_symbol_value >= 1 && start_symbol_value <=4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid start symbol value [1..4]"); ++ } ++ ++ // ECCE index ++ guint8 ecce_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ecce_index, 1, ENC_BIG_ENDIAN); ++ if (ecce_index_value > 22) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ecce index value [0..22]"); ++ } ++ ++ // Aggregation level ++ guint8 aggregation_level_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_aggregation_level, 1, ENC_BIG_ENDIAN); ++ if (!(aggregation_level_value == 2 || aggregation_level_value == 4 || aggregation_level_value == 8 || ++ aggregation_level_value == 16 || aggregation_level_value == 24)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid aggregation level value [2, 4, 8, 16, 24]"); ++ } ++ ++ // RNTI type ++ guint8 rnti_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_rnti_type, 1, ENC_BIG_ENDIAN); ++ if (rnti_type_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti type value [0..4]"); ++ } ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (!(rnti_value >= 1)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // CEMode ++ guint8 cemode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ce_mode, 1, ENC_BIG_ENDIAN); ++ if (!(cemode_value >= 1 && cemode_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cemode value [1..2]"); ++ } ++ ++ // DMRS scrambling init ++ guint16 drms_scrambling_init_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_scrabmling_init, 2, ENC_BIG_ENDIAN); ++ if (drms_scrambling_init_value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms scrambling init value [0..503]"); ++ } ++ ++ // Initial transmission SF (io) ++ guint16 initial_transmission_sf_io_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_transmission_sf, 2, ENC_BIG_ENDIAN); ++ if (!(initial_transmission_sf_io_value <= 10239 || initial_transmission_sf_io_value == 0xFFFF)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial transmission sf io value [0..10239, 0xFFFF]"); ++ } ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++ // DCI format ++ guint8 dci_format_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dl_dci_format, 1, ENC_BIG_ENDIAN); ++ if (!(dci_format_value == 10 || dci_format_value == 11 || dci_format_value == 12)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci format value [10, 11, 12]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 2, ENC_BIG_ENDIAN); ++ ++ // MCS ++ guint8 mcs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs, 1, ENC_BIG_ENDIAN); ++ if (mcs_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..15]"); ++ } ++ ++ // PDSCH repetition levels ++ guint8 pdsch_repetition_levels_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pdsch_reception_levels, 1, ENC_BIG_ENDIAN); ++ if (!(pdsch_repetition_levels_value >= 1 && pdsch_repetition_levels_value <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdsch repetition levels value [1..8]"); ++ } ++ ++ // Redundancy version ++ guint8 redundancy_version_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy version value [0..3]"); ++ } ++ ++ // New data indicator ++ guint8 new_data_indicator_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indicator, 1, ENC_BIG_ENDIAN); ++ if (new_data_indicator_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indicator value [0..1]"); ++ } ++ ++ // HARQ process ++ guint8 harq_process_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_process, 1, ENC_BIG_ENDIAN); ++ if (harq_process_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq process value [0..15]"); ++ } ++ ++ // TPMI length ++ guint8 tpmi_length_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpmi_length, 1, ENC_BIG_ENDIAN); ++ if (!(tpmi_length_value == 0 || tpmi_length_value == 2 || tpmi_length_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi length value [0, 2, 4]"); ++ } ++ ++ // TPMI ++ guint8 tpmi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpmi, 1, ENC_BIG_ENDIAN); ++ if (tpmi_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi value [0..15]"); ++ } ++ ++ // PMI flag ++ guint8 pmi_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pmi_flag, 1, ENC_BIG_ENDIAN); ++ if (pmi_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pmi flag value [0..1]"); ++ } ++ ++ // PMI ++ guint8 pmi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pmi, 1, ENC_BIG_ENDIAN); ++ if (pmi_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pmi value [0..1]"); ++ } ++ ++ // HARQ resource offset ++ guint8 harq_resource_offset_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_resource_offset, 1, ENC_BIG_ENDIAN); ++ if (harq_resource_offset_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq resource offset value [0..3]"); ++ } ++ ++ // DCI subframe repetition number ++ guint8 dci_subframe_reptition_number_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dci_subframe_repetition_number, 1, ENC_BIG_ENDIAN); ++ if (!(dci_subframe_reptition_number_value >= 1 && dci_subframe_reptition_number_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci subframe repetition number value [1..4]"); ++ } ++ ++ // TPC ++ guint8 tpc_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpc, 1, ENC_BIG_ENDIAN); ++ if (tpc_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpc value [0..3]"); ++ } ++ ++ // Downlink assignment index Length ++ guint8 downlink_assignment_index_length_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_downlink_assignment_index_length, 1, ENC_BIG_ENDIAN); ++ if (!(downlink_assignment_index_length_value == 0 || downlink_assignment_index_length_value == 2 || ++ downlink_assignment_index_length_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink assignmnet index value [0, 2, 4]"); ++ } ++ ++ // Downlink assignment index ++ guint8 downlink_assignment_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_downlink_assignment_index, 1, ENC_BIG_ENDIAN); ++ if (downlink_assignment_index_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid downlink assignment index value [0..15]"); ++ } ++ ++ // Allocate PRACH flag ++ guint8 allocate_prach_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_allocate_prach_flag, 1, ENC_BIG_ENDIAN); ++ if (allocate_prach_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid allocate prach flag value [0..1]"); ++ } ++ ++ // Preamble index ++ guint8 preamble_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_preamble_index, 1, ENC_BIG_ENDIAN); ++ if (preamble_index_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid preamble index value [0..63]"); ++ } ++ ++ // PRACH mask index ++ guint8 prach_mask_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_prach_mask_index, 1, ENC_BIG_ENDIAN); ++ if (prach_mask_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid prach mask index value [0..15]"); ++ } ++ ++ // Starting CE Level ++ guint8 starting_ce_level_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_starting_ce_level, 1, ENC_BIG_ENDIAN); ++ if (starting_ce_level_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid starting ce level value [0..3]"); ++ } ++ ++ // SRS request ++ guint8 srs_request_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_request, 1, ENC_BIG_ENDIAN); ++ if (srs_request_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs request value [0..1]"); ++ } ++ ++ // Antenna ports and scrambling identity flag ++ guint8 antenna_ports_and_scrambling_identity_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_antenna_ports_and_scrambling_identity_flag, 1, ENC_BIG_ENDIAN); ++ if (antenna_ports_and_scrambling_identity_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid antenna ports and scrambling identity flag value [0..1]"); ++ } ++ ++ // Antenna ports and scrambling identity ++ guint8 antenna_ports_and_scrambling_identity_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_antenna_ports_and_scrambling_identity, 1, ENC_BIG_ENDIAN); ++ if (antenna_ports_and_scrambling_identity_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid antenna ports and scrambling identity value [0..3]"); ++ } ++ ++ // Frequency hopping enabled flag ++ guint8 frequency_hopping_enabled_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_enabled_flag, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_enabled_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping enabled flag value [0..1]"); ++ } ++ ++ // Paging/Direct indication differentiation flag ++ guint8 paging_direct_indicaton_differentiation_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_paging_direct_indication_differentiation_flag, 1, ENC_BIG_ENDIAN); ++ if (paging_direct_indicaton_differentiation_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid paging/direct indication differentiation flag value [0..1]"); ++ } ++ ++ // Direct indication ++ ptvcursor_add(ptvc, hf_nfapi_direct_indication, 1, ENC_BIG_ENDIAN); ++ ++ // Total DCI length including padding ++ item = ptvcursor_add(ptvc, hf_nfapi_total_dci_length_including_padding, 1, ENC_BIG_ENDIAN); ++ ++ // Number of TX Antenna ports ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_tx_antenna_ports, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "Precoding", ett_nfapi_precoding, count, dissect_precoding_value); ++} ++static void dissect_ul_config_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PDU Type ++ guint8 ul_pdu_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_config_pdu_type, 1, ENC_BIG_ENDIAN); ++ if (ul_pdu_type_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul pdu type value [0..15]"); ++ } ++ ++ guint8 size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_size, 1, ENC_BIG_ENDIAN); ++ ++ guint pdu_end = (ptvcursor_current_offset(ptvc) + size - 2); ++ dissect_tlv_list(ptvc, pinfo, pdu_end); ++} ++static void dissect_ul_config_request_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Number of PDUs ++ guint8 num_pdu = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_pdus, 1, ENC_BIG_ENDIAN); ++ ++ // RACH/PRACH frequency resources ++ guint8 rach_prach_frequency_resources_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rach_prach_frequency_resources, 1, ENC_BIG_ENDIAN); ++ if (rach_prach_frequency_resources_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rach prach frequency resources value [0..1]"); ++ } ++ ++ // SRS present ++ guint8 srs_present_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_present, 1, ENC_BIG_ENDIAN); ++ if (srs_present_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs present value [0..1]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "UL Config PDU List", ett_nfapi_ul_config_request_pdu_list, num_pdu, dissect_ul_config_pdu); ++} ++static void dissect_ul_config_ulsch_pdu_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // Size ++ ptvcursor_add(ptvc, hf_nfapi_size, 2, ENC_BIG_ENDIAN); ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (!(rnti_value >= 1)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // Resource block start ++ guint8 resource_block_start_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_start, 1, ENC_BIG_ENDIAN); ++ if (resource_block_start_value > 99) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block start value [0..99]"); ++ } ++ ++ // Number of resource blocks ++ guint8 number_of_resource_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_resource_blocks, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_resource_blocks_value >= 1 && number_of_resource_blocks_value <= 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of resource blocks value [1..100]"); ++ } ++ ++ // Modulation type ++ guint8 modulation_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_modulation, 1, ENC_BIG_ENDIAN); ++ if (!(modulation_type_value == 2 || modulation_type_value == 4 || modulation_type_value == 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid modulation type value [2, 4, 6]"); ++ } ++ ++ // Cyclic Shift 2 for DMRS ++ guint8 cyclic_shift_2_for_drms_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cyclic_shift_2_for_drms, 1, ENC_BIG_ENDIAN); ++ if (cyclic_shift_2_for_drms_value > 99) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cyclic shift 2 for drms value [0..7]"); ++ } ++ ++ // Frequency hopping enabled flag ++ guint8 frequency_hopping_enabled_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_enabled_flag, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_enabled_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping enabled flag value [0..1]"); ++ } ++ ++ // Frequency hopping bits ++ guint8 frequency_hopping_bits_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_bits, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_bits_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping bits value [0..3]"); ++ } ++ ++ // New data indication ++ guint8 new_data_indication_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indication, 1, ENC_BIG_ENDIAN); ++ if (new_data_indication_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indicator value [0..1]"); ++ } ++ ++ // Redundancy version ++ guint8 redundancy_version_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy version value [0..3]"); ++ } ++ ++ // HARQ process number ++ guint8 harq_process_number_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_process_number, 1, ENC_BIG_ENDIAN); ++ if (harq_process_number_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq process number value [0..15]"); ++ } ++ ++ // UL Tx mode ++ guint8 ul_tx_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_tx_mode, 1, ENC_BIG_ENDIAN); ++ if (ul_tx_mode_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul tx mode value [0..1]"); ++ } ++ ++ // Current TX NB ++ ptvcursor_add(ptvc, hf_nfapi_current_tx_nb, 1, ENC_BIG_ENDIAN); ++ ++ // N srs ++ guint8 n_srs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_srs, 1, ENC_BIG_ENDIAN); ++ if (n_srs_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n_srs value [0..1]"); ++ } ++} ++static void dissect_ul_config_ulsch_pdu_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Resource allocation type ++ guint8 resource_allocation_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ if (resource_allocation_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocation type value [0..1]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ++ // Transport blocks ++ guint8 transport_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transport_blocks, 1, ENC_BIG_ENDIAN); ++ if (!(transport_blocks_value >= 1 && transport_blocks_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transport blocks value [1..2]"); ++ } ++ ++ // Transmission scheme ++ guint8 transmission_scheme_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_transmission_scheme, 1, ENC_BIG_ENDIAN); ++ if (transmission_scheme_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission scheme value [0..1]"); ++ } ++ ++ // Number Of layers ++ guint8 number_of_layers_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_layers, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_layers_value >= 1 && number_of_layers_value <=4 )) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of layers value [1..4]"); ++ } ++ ++ // Codebook Index ++ guint8 codebook_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_codebook_index, 1, ENC_BIG_ENDIAN); ++ if (codebook_index_value > 23) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid codebook index value [0..23]"); ++ } ++ ++ // Disable sequence hopping flag ++ guint8 disable_sequence_hopping_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_disable_sequence_hopping_flag, 1, ENC_BIG_ENDIAN); ++ if (disable_sequence_hopping_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid disable sequence hopping flag value [0..1]"); ++ } ++} ++static void dissect_ul_config_ulsch_pdu_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Virtual cell ID enabled flag ++ guint8 virtual_cell_id_enabled_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_virtual_cell_id_enabled_flag, 1, ENC_BIG_ENDIAN); ++ if (virtual_cell_id_enabled_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid virtual cell id enabled flag value [0..1]"); ++ } ++ ++ // nPUSCH Identity ++ guint16 npusch_identity_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_npusch_identity, 2, ENC_BIG_ENDIAN); ++ if (npusch_identity_value > 509) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npusch identity value [0..509]"); ++ } ++ ++ // DMRS Config flag ++ guint8 drms_config_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_config_flag, 1, ENC_BIG_ENDIAN); ++ if (drms_config_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms config flag value [0..1]"); ++ } ++ ++ // nDMRS-CSH Identity ++ guint16 ndrms_csh_identity_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ndrms_csh_identity, 2, ENC_BIG_ENDIAN); ++ if (ndrms_csh_identity_value > 509) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ndrms-csh identity value [0..509]"); ++ } ++ ++} ++static void dissect_ul_config_ulsch_pdu_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // UE Type ++ guint8 ue_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_type, 1, ENC_BIG_ENDIAN); ++ if (ue_type_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue type value [0..2]"); ++ } ++ ++ // Total Number of repetitions ++ guint16 total_number_of_repetitions_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_total_number_of_repetitions, 2, ENC_BIG_ENDIAN); ++ if (!(total_number_of_repetitions_value >= 1 && total_number_of_repetitions_value <= 2048)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid total number of repetitions value [1..2048]"); ++ } ++ ++ // Repetition Number ++ guint16 repetition_number_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_repetition_number, 2, ENC_BIG_ENDIAN); ++ if (!(repetition_number_value >= 1 && repetition_number_value <= 2048)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid repetition number value [1..2048]"); ++ } ++ ++ // Initial transmission SF (io) ++ guint16 intial_transmission_sf_io_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_sf_io, 2, ENC_BIG_ENDIAN); ++ if (!(intial_transmission_sf_io_value <= 10239 || intial_transmission_sf_io_value == 0xFFFF)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid repetition number value [0..10239, 0xFFFF]"); ++ } ++ ++ // Empy symbols due to re-tunning ++ // todo : decode as a bitmap ++ ptvcursor_add(ptvc, hf_nfapi_empty_symbols_due_to_retunning, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_ul_config_init_tx_params_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // N srs initial ++ guint8 n_srs_initial_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_srs_initial, 1, ENC_BIG_ENDIAN); ++ if (n_srs_initial_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n srs initial value [0..1]"); ++ } ++ ++ // Initial number of resource blocks ++ guint8 initial_number_of_resource_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_number_of_resource_blocks, 1, ENC_BIG_ENDIAN); ++ if (!(initial_number_of_resource_blocks_value >= 1 && initial_number_of_resource_blocks_value <= 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial number of reosurce blocks value [1..100]"); ++ } ++ ++} ++static void dissect_ul_config_cqi_ri_info_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DL CQI/PMI Size Rank = 1 ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_pmi_size_rank_1, 1, ENC_BIG_ENDIAN); ++ ++ // DL CQI/PMI Size Rank>1 ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_pmi_size_rank_greater_1, 1, ENC_BIG_ENDIAN); ++ ++ // RI Size ++ guint8 ri_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ri_size, 1, ENC_BIG_ENDIAN); ++ if (ri_size_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ri size value [0..3]"); ++ } ++ ++ // Delta Offset CQI ++ guint8 delta_offset_cqi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_cqi, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_cqi_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset cqi value [0..15]"); ++ } ++ ++ // Delta Offset RI ++ guint8 delta_offset_ri_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_ri, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_ri_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset ri value [0..15]"); ++ } ++} ++static void dissect_ul_cqi_pmi_size(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Delta Offset RI ++ guint8 dl_cqi_pmi_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_ri, 1, ENC_BIG_ENDIAN); ++ if (dl_cqi_pmi_size_value > 255) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset ri value [0..255]"); ++ } ++} ++ ++static void dissect_ul_config_cqi_ri_info_rel9_later_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ // Report type ++ guint8 type = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_report_type, 1, ENC_BIG_ENDIAN); ++ if (type > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid report type value [0..1]"); ++ } ++ ++ // Delta offset CQI ++ guint8 delta_offset_cqi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_cqi, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_cqi_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset cqi value [0..15]"); ++ } ++ ++ // Delta offset RI ++ guint8 delta_offset_ri_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_ri, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_ri_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset ri value [0..15]"); ++ } ++ ++ switch (type) ++ { ++ case 0: ++ { ++ // DL CQI/PMI/RI size ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_ri_pmi_size, 1, ENC_BIG_ENDIAN); ++ ++ // Control Type ++ guint8 control_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_control_type, 1, ENC_BIG_ENDIAN); ++ if (control_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid control type value [0..1]"); ++ } ++ break; ++ } ++ case 1: ++ { ++ // todo : encoder not right for this case. ++ gint8 num_cc_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_cc, 1, ENC_BIG_ENDIAN); ++ ++ if (!(num_cc_value >= 1 && num_cc_value <= 32)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of cc value [1..32]"); ++ } ++ ++ // UL CONFIG CQI PMI SIZE ++ dissect_array_value(ptvc, pinfo, "CQI PMI SIZE", ett_nfapi_cqi_pmi_size, 8, dissect_ul_cqi_pmi_size); ++ ++ /* ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "CCs"); ++ ++ for (int i = 0; i < num_cc; ++i) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "[%d]", i); ++ ++ guint8 ri_size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_ri_size, 1, ENC_BIG_ENDIAN); ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "Rank"); ++ ++ for (int j = 0; j < ri_size; ++j) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "[%d]", j); ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_pmi_size, 1, ENC_BIG_ENDIAN); ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ */ ++ ++ break; ++ } ++ } ++} ++static void dissect_ul_config_cqi_ri_info_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // DL CQI/PMI/RI size 2 ++ guint16 dl_cqi_ri_pmi_size_2_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_dl_cqi_ri_pmi_size_2, 2, ENC_BIG_ENDIAN); ++ if (dl_cqi_ri_pmi_size_2_value < 255) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dl cqi ri pmi size 2 value [>= 255]"); ++ } ++} ++static void dissect_ul_config_harq_info_ulsch_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // HARQ Size ++ guint8 harq_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_size, 1, ENC_BIG_ENDIAN); ++ if (harq_size_value > 21) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq size value [0..21]"); ++ } ++ ++ // Delta Offset HARQ ++ guint8 delta_offset_harq_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_harq, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_harq_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset harq value [0..15]"); ++ } ++ ++ // ACK_NACK mode ++ guint8 ack_nack_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tdd_ack_nack_mode, 1, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value > 5) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ack nack mode value [0..5]"); ++ } ++} ++static void dissect_ul_config_harq_info_ulsch_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // HARQ Size 2 ++ ptvcursor_add(ptvc, hf_nfapi_harq_size_2, 2, ENC_BIG_ENDIAN); ++ ++ // Delta Offset HARQ 2 ++ guint8 delta_offset_harq_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_delta_offset_harq_2, 1, ENC_BIG_ENDIAN); ++ if (delta_offset_harq_2_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid delta offset harq 2 value [0..15]"); ++ } ++} ++static void dissect_ul_config_ue_info_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++} ++static void dissect_ul_config_ue_info_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Virtual cell ID enabled flag ++ guint8 virtual_cell_id_enabled_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_virtual_cell_id_enabled_flag, 1, ENC_BIG_ENDIAN); ++ if (virtual_cell_id_enabled_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid virtual cell id enabled flag value [0..1]"); ++ } ++ ++ // nPUCCH Identity ++ guint16 npucch_identity_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_npucch_identity, 2, ENC_BIG_ENDIAN); ++ if (npucch_identity_value > 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch identity value [0..503]"); ++ } ++ ++} ++static void dissect_ul_config_ue_info_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // UE Type ++ guint8 ue_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_type, 1, ENC_BIG_ENDIAN); ++ if (ue_type_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue type value [0..2]"); ++ } ++ ++ // Empty symbols ++ // todo : use bit map decoding ++ ptvcursor_add(ptvc, hf_nfapi_empty_symbols, 1, ENC_BIG_ENDIAN); ++ ++ // Total Number of repetitions ++ guint16 total_number_of_repetitions_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_total_number_of_repetitions, 2, ENC_BIG_ENDIAN); ++ if (!(total_number_of_repetitions_value >= 1 && total_number_of_repetitions_value <= 32)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid total number of repetitions value [1..32]"); ++ } ++ ++ // Repetition Number ++ guint16 repetition_number_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_repetition_number, 2, ENC_BIG_ENDIAN); ++ if (!(repetition_number_value >= 1 && repetition_number_value <= 32)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid repetition number value [1..32]"); ++ } ++ ++} ++static void dissect_ul_config_cqi_info_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PUCCH index ++ guint16 pucch_index_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pucch_index, 2, ENC_BIG_ENDIAN); ++ if (pucch_index_value > 1184) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch index value [0..1184]"); ++ } ++ ++ // DL CQI/PMI Size ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_pmi_size, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_ul_config_cqi_info_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Number of PUCCH Resources ++ guint8 number_of_pucch_resources_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_pucch_resource, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_pucch_resources_value >= 1 && number_of_pucch_resources_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pucch resources value [1..2]"); ++ } ++ ++ //PUCCH Index P1 ++ guint16 pucch_index_p1_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pucch_index_p1, 2, ENC_BIG_ENDIAN); ++ if (pucch_index_p1_value > 1184) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch index p1 value [0..1184]"); ++ } ++} ++static void dissect_ul_config_cqi_info_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // CSI_mode ++ guint8 csi_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_mode, 1, ENC_BIG_ENDIAN); ++ if (csi_mode_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi mode value [0..2]"); ++ } ++ ++ // DL CQI/PMI Size 2 ++ ptvcursor_add(ptvc, hf_nfapi_dl_cqi_pmi_size_2, 2, ENC_BIG_ENDIAN); ++ ++ // Starting PRB ++ guint8 starting_prb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_statring_prb, 1, ENC_BIG_ENDIAN); ++ if (starting_prb_value > 109) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid starting prb value [0..109]"); ++ } ++ ++ // n_PRB ++ guint8 n_prb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nprb, 1, ENC_BIG_ENDIAN); ++ if (n_prb_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n prb value [0..7]"); ++ } ++ ++ // cdm_Index ++ guint8 cdm_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cdm_index, 1, ENC_BIG_ENDIAN); ++ if (cdm_index_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cdm index value [0..1]"); ++ } ++ ++ // N srs ++ guint8 n_srs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nsrs, 1, ENC_BIG_ENDIAN); ++ if (n_srs_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n srs value [0..1]"); ++ } ++ ++} ++static void dissect_ul_config_sr_info_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 pucch_index_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_pucch_index, 2, ENC_BIG_ENDIAN); ++ if (pucch_index_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch index value [0..2047]"); ++ } ++} ++static void dissect_ul_config_sr_info_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Number of PUCCH Resources ++ guint8 number_of_pucch_resources_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_pucch_resource, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_pucch_resources_value >= 1 && number_of_pucch_resources_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pucch resources value [0..2047]"); ++ } ++ ++ // PUCCH Index P1 ++ guint16 pucch_index_p1_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pucch_index_p1, 2, ENC_BIG_ENDIAN); ++ if (pucch_index_p1_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pucch index p1 value [0..2047]"); ++ } ++} ++static void dissect_ul_config_harq_info_uci_rel10_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // HARQ size ++ guint8 harq_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_size, 1, ENC_BIG_ENDIAN); ++ if (harq_size_value > 21) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq size value [0..21]"); ++ } ++ ++ // ACK_NACK mode ++ guint8 ack_nack_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tdd_ack_nack_mode, 1, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value > 5) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ack nack mode value [0..5]"); ++ } ++ ++ // Number of PUCCH resources ++ guint8 number_of_pucch_resources_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_pucch_resource, 1, ENC_BIG_ENDIAN); ++ if (number_of_pucch_resources_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pucch resources value [0..4]"); ++ } ++ ++ // n_PUCCH_1_0 ++ guint16 npucch_1_0_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_0, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1 || ack_nack_mode_value == 2) ++ { ++ if (npucch_1_0_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 0 value [0..2047] (All Format 1a/1b)"); ++ } ++ } ++ else if (ack_nack_mode_value == 3) ++ { ++ if (npucch_1_0_value > 549) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 0 value [0..549] (Format 3)"); ++ } ++ } ++ ++ // n_PUCCH_1_1 ++ guint16 npucch_1_1_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_1, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1 || ack_nack_mode_value == 2) ++ { ++ if (npucch_1_1_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 1 value [0..2047] (All Format 1a/1b)"); ++ } ++ } ++ ++ // n_PUCCH_1_2 ++ guint16 npucch_1_2_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_2, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 2) ++ { ++ if (npucch_1_2_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 2 value [0..2047] (All Format 1a/1b)"); ++ } ++ } ++ ++ // n_PUCCH_1_3 ++ guint16 npucch_1_3_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_3, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 2) ++ { ++ if (npucch_1_3_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 3 value [0..2047] (All Format 1a/1b)"); ++ } ++ } ++} ++static void dissect_ul_config_harq_info_uci_rel8_fdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // n_PUCCH_1_0 ++ // todo : how to work out the ack_nack mode? ++ guint16 npucch_1_0_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_0, 2, ENC_BIG_ENDIAN); ++ if (npucch_1_0_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n pucch 1 0 value [0..2047]"); ++ } ++ ++ // HARQ Size ++ guint8 harq_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_size, 1, ENC_BIG_ENDIAN); ++ if (!(harq_size_value >= 1 && harq_size_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq size value [1..2]"); ++ } ++} ++static void dissect_ul_config_harq_info_uci_rel9_later_fdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // HARQ Size ++ guint8 harq_size_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* harq_size_item = ptvcursor_add(ptvc, hf_nfapi_harq_size, 1, ENC_BIG_ENDIAN); ++ ++ // ACK_NAK mode ++ guint8 ack_nack_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_fdd_ack_nack_mode, 1, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ack nack mode value [0..4]"); ++ } ++ ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 2) ++ { ++ if (!(harq_size_value >= 1 && harq_size_value <= 10)) ++ { ++ expert_add_info_format(pinfo, harq_size_item, &ei_invalid_range, "Invalid harq size value [1..10] (Format 1a/1b/3)"); ++ } ++ } ++ else if (ack_nack_mode_value == 3 || ack_nack_mode_value == 4) ++ { ++ if (harq_size_value != 0) ++ { ++ expert_add_info_format(pinfo, harq_size_item, &ei_invalid_range, "Invalid harq size value [0] (Format 4/5)"); ++ } ++ } ++ ++ // Number of PUCCH Resources ++ guint8 number_of_pucch_resources_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_pucch_resource, 1, ENC_BIG_ENDIAN); ++ if (number_of_pucch_resources_value == 0 || number_of_pucch_resources_value == 2) ++ { ++ if (!(number_of_pucch_resources_value >= 1 && number_of_pucch_resources_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq size value [1..4] (Format 1a/1b/3)"); ++ } ++ } ++ else if (number_of_pucch_resources_value == 3 || number_of_pucch_resources_value == 4) ++ { ++ if (number_of_pucch_resources_value != 0) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq size value [0] (Format 4/5)"); ++ } ++ } ++ ++ // n_PUCCH_1_0 ++ guint16 npucch_1_0_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_0, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1) ++ { ++ if (npucch_1_0_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 1 0 value [0..2047] (Format 1a/1b/channel selection)"); ++ } ++ } ++ else if (ack_nack_mode_value == 2) ++ { ++ if (npucch_1_0_value > 549) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 1 0 value [0..549] (Format 3)"); ++ } ++ } ++ ++ // n_PUCCH_1_1 ++ guint16 npucch_1_1_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_1, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1) ++ { ++ if (npucch_1_1_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 1 1 value [0..2047] (Format 1a/1b/channel selection)"); ++ } ++ } ++ ++ // n_PUCCH_1_2 ++ guint16 npucch_1_2_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_2, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1) ++ { ++ if (npucch_1_2_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 1 2 value [0..2047] (Format 1a/1b/channel selection)"); ++ } ++ } ++ ++ // n_PUCCH_1_3 ++ guint16 npucch_1_3_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_1_3, 2, ENC_BIG_ENDIAN); ++ if (ack_nack_mode_value == 0 || ack_nack_mode_value == 1) ++ { ++ if (npucch_1_3_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 1 3 value [0..2047] (Format 1a/1b/channel selection)"); ++ } ++ } ++} ++static void dissect_ul_config_harq_info_uci_rel11_fdd_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Num_ant_ports ++ guint8 num_ant_ports_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_num_ant_ports, 1, ENC_BIG_ENDIAN); ++ if (!(num_ant_ports_value >= 1 && num_ant_ports_value <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid num ant ports value [1..2]"); ++ } ++ ++ // n_PUCCH_2_0 ++ // todo : how to work out the ack nack mode ++ guint16 npucch_2_0_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_2_0, 2, ENC_BIG_ENDIAN); ++ if (npucch_2_0_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 2 0 value [0..2047]"); ++ } ++ ++ // n_PUCCH_2_1 ++ guint16 npucch_2_1_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_2_1, 2, ENC_BIG_ENDIAN); ++ if (npucch_2_1_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 2 1 value [0..2047]"); ++ } ++ ++ // n_PUCCH_2_2 ++ guint16 npucch_2_2_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_2_2, 2, ENC_BIG_ENDIAN); ++ if (npucch_2_2_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 2 2 value [0..2047]"); ++ } ++ ++ // n_PUCCH_2_3 ++ guint16 npucch_2_3_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_pucch_2_3, 2, ENC_BIG_ENDIAN); ++ if (npucch_2_3_value > 2047) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid npucch 2 3 value [0..2047]"); ++ } ++ ++} ++static void dissect_ul_config_harq_info_uci_rel13_fdd_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // HARQ Size 2 ++ ptvcursor_add(ptvc, hf_nfapi_harq_size_2, 2, ENC_BIG_ENDIAN); ++ ++ // Starting PRB ++ guint8 starting_prb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_starting_prb, 1, ENC_BIG_ENDIAN); ++ if (starting_prb_value > 109) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid starting prb value [0..109]"); ++ } ++ ++ // n_PRB ++ guint8 n_prb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nprb, 1, ENC_BIG_ENDIAN); ++ if (n_prb_value > 109) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n prb value [0..7]"); ++ } ++ ++ // cdm_Index ++ guint8 cdm_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cdm_index, 1, ENC_BIG_ENDIAN); ++ if (cdm_index_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cdm index value [0..1]"); ++ } ++ ++ // N srs ++ guint8 n_srs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_nsrs, 1, ENC_BIG_ENDIAN); ++ if (n_srs_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n srs value [0..1]"); ++ } ++} ++static void dissect_ul_config_srs_info_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // Size ++ ptvcursor_add(ptvc, hf_nfapi_size, 2, ENC_BIG_ENDIAN); ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // SRS Bandwidth ++ guint8 srs_bandwidth_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_bandwidth, 1, ENC_BIG_ENDIAN); ++ if (srs_bandwidth_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs bandwidth value [0..3]"); ++ } ++ ++ // Frequency Domain Position ++ guint8 frequency_domain_position_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_domain_position, 1, ENC_BIG_ENDIAN); ++ if (frequency_domain_position_value > 23) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency domain bandwidth value [0..23]"); ++ } ++ ++ // SRS Hopping Bandwidth ++ guint8 srs_hopping_bandwidth_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_hopping_bandwidth, 1, ENC_BIG_ENDIAN); ++ if (srs_hopping_bandwidth_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs hopping bandwidth value [0..3]"); ++ } ++ ++ // Transmission Comb ++ guint8 transmission_comb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_comb, 1, ENC_BIG_ENDIAN); ++ if (transmission_comb_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission comb value [0..3]"); ++ } ++ ++ // ISRS / SRS-ConfigIndex ++ guint16 srs_config_index_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_i_srs, 2, ENC_BIG_ENDIAN); ++ if (srs_config_index_value > 1023) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid isrs/srs-configindex value [0..1023]"); ++ } ++ ++ // Sounding Reference Cyclic Shift ++ guint8 sounding_reference_cyclic_shift_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_sounding_reference_cyclic_shift, 1, ENC_BIG_ENDIAN); ++ if (sounding_reference_cyclic_shift_value > 11) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid sounding reference cyclic shift value [0..11]"); ++ } ++} ++static void dissect_ul_config_srs_info_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 antenna_port_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_antenna_port, 1, ENC_BIG_ENDIAN); ++ if (antenna_port_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid antenna port value [0..2]"); ++ } ++} ++static void dissect_ul_config_srs_info_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 number_of_combs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_number_of_combs, 1, ENC_BIG_ENDIAN); ++ if (number_of_combs_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of combs value [0..1]"); ++ } ++} ++static void dissect_hi_dci0_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ++ // PDU Type ++ guint8 pdu_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_hi_dci0_pdu_type, 1, ENC_BIG_ENDIAN); ++ if (pdu_type_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdu type value [0..3]"); ++ } ++ ++ // PDU Size ++ guint8 size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_size, 1, ENC_BIG_ENDIAN); ++ ++ guint pdu_end = (ptvcursor_current_offset(ptvc) + size - 2); ++ dissect_tlv_list(ptvc, pinfo, pdu_end); ++} ++static void dissect_hi_dci0_request_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // SFN/SF ++ ptvcursor_add(ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ ++ // Number of DCI ++ guint8 num_pdu = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_dci_pdus, 1, ENC_BIG_ENDIAN); ++ ++ // Number of HI ++ num_pdu += tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_hi_pdus, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "HI DCI0 PDU List", ett_nfapi_hi_dci0_request_pdu_list, num_pdu, dissect_hi_dci0_pdu); ++} ++static void dissect_hi_dci0_hi_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Resource block start ++ guint8 resource_block_start_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_start, 1, ENC_BIG_ENDIAN); ++ if (resource_block_start_value > 100) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block start value [0..100]"); ++ } ++ ++ // Cyclic Shift 2 for DMRS ++ guint8 cyclic_shift_2_for_drms_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cyclic_shift_2_for_drms, 1, ENC_BIG_ENDIAN); ++ if (cyclic_shift_2_for_drms_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cyclic shift 2 for drms value [0..7]"); ++ } ++ ++ // HI value ++ guint8 hi_value_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_hi_value, 1, ENC_BIG_ENDIAN); ++ if (hi_value_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid hi value [0..1]"); ++ } ++ ++ // I_PHICH ++ guint8 i_pich_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_i_phich, 1, ENC_BIG_ENDIAN); ++ if (i_pich_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid i phich value [0..1]"); ++ } ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++} ++static void dissect_hi_dci0_hi_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Flag TB2 ++ guint8 flag_tb2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_flag_tb2, 1, ENC_BIG_ENDIAN); ++ if (flag_tb2_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid flag tb2 value [0..1]"); ++ } ++ ++ // HI Value 2 ++ guint8 hi2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_hi_value_2, 1, ENC_BIG_ENDIAN); ++ if (hi2_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid hi2 value [0..1]"); ++ } ++ ++} ++static void dissect_hi_dci0_dci_ul_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // DCI format ++ guint8 dci_format_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_dci_format, 1, ENC_BIG_ENDIAN); ++ if (dci_format_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci format value [0..4]"); ++ } ++ ++ // CCE index ++ guint8 cce_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cce_idx, 1, ENC_BIG_ENDIAN); ++ if (cce_index_value > 88) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cce index value [0..88]"); ++ } ++ ++ // Aggregation level ++ guint8 aggregation_level_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_aggregation_level, 1, ENC_BIG_ENDIAN); ++ if (!(aggregation_level_value == 1 || aggregation_level_value == 2 || aggregation_level_value == 4 || ++ aggregation_level_value == 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid aggregation level value [1, 2, 4, 8]"); ++ } ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // Resource block start ++ guint8 resource_block_start_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_start, 1, ENC_BIG_ENDIAN); ++ if (resource_block_start_value > 100) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block start value [0..100]"); ++ } ++ ++ // Number of resource blocks ++ guint8 number_of_resource_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_resource_blocks, 1, ENC_BIG_ENDIAN); ++ if (number_of_resource_blocks_value > 100) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of resource blocks value [0..100]"); ++ } ++ ++ // MCS_1 ++ guint8 mcs_1_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs_1, 1, ENC_BIG_ENDIAN); ++ if (mcs_1_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs 1 value [0..31]"); ++ } ++ ++ // Cyclic Shift 2 for DMRS ++ guint8 cyclic_shift_2_for_drms_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cyclic_shift_2_for_drms, 1, ENC_BIG_ENDIAN); ++ if (cyclic_shift_2_for_drms_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cyclic shift 2 for drms value [0..7]"); ++ } ++ ++ // Frequency hopping enabled flag ++ guint8 frequency_hopping_enabled_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_enabled_flag, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_enabled_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping enabled flag value [0..1]"); ++ } ++ ++ // Frequency hopping bits ++ guint8 frequency_hopping_bit_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_bits, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_bit_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping bits value [0..3]"); ++ } ++ ++ // New Data indication_1 ++ guint8 new_data_indication_1_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indication, 1, ENC_BIG_ENDIAN); ++ if (new_data_indication_1_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indication value [0..1]"); ++ } ++ ++ // UE TX antenna selection ++ guint8 ue_tx_antenna_selection_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ue_tx_antenna_selection, 1, ENC_BIG_ENDIAN); ++ if (ue_tx_antenna_selection_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ue tx antenna selection value [0..2]"); ++ } ++ ++ // TPC ++ guint8 tpc_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpc, 1, ENC_BIG_ENDIAN); ++ if (tpc_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpc value value [0..3]"); ++ } ++ ++ // CQI/CSI request ++ guint8 cqi_csi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cqi_csi_request, 1, ENC_BIG_ENDIAN); ++ if (cqi_csi_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cqi csi value [0..7]"); ++ } ++ ++ // UL index ++ guint8 ul_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_index, 1, ENC_BIG_ENDIAN); ++ if (ul_index_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul index value [0..3]"); ++ } ++ ++ // DL assignment index ++ guint8 dl_assignment_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dl_assignment_index, 1, ENC_BIG_ENDIAN); ++ if (!(dl_assignment_index_value >= 1 && dl_assignment_index_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dl assignment index value [1..4]"); ++ } ++ ++ // TPC bitmap ++ ptvcursor_add(ptvc, hf_nfapi_tpc_bitmap, 4, ENC_BIG_ENDIAN); ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++} ++static void dissect_hi_dci0_dci_ul_rel10_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Cross carrier scheduling flag ++ guint8 cross_carrier_scheduling_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_cross_carrier_scheduling_flag, 1, ENC_BIG_ENDIAN); ++ if (cross_carrier_scheduling_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cross carrier scheduling flag value [0..1]"); ++ } ++ ++ // Carrier indicator ++ guint8 carrier_indicator_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_carrier_indicator, 1, ENC_BIG_ENDIAN); ++ if (carrier_indicator_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid carrier indicator value [0..7]"); ++ } ++ ++ // Size of CQI/CSI field ++ guint8 size_of_cqi_csi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_size_of_cqi_csi_feild, 1, ENC_BIG_ENDIAN); ++ if (size_of_cqi_csi_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid size of cqi/csi field value [0..2]"); ++ } ++ ++ // SRS flag ++ guint8 srs_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_flag, 1, ENC_BIG_ENDIAN); ++ if (srs_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs field value [0..1]"); ++ } ++ ++ // SRS request ++ //guint8 srs_request_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ //item = ptvcursor_add(ptvc, hf_nfapi_srs_request, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_srs_request, 1, ENC_BIG_ENDIAN); ++ ++ // Resource allocation flag ++ guint8 resource_allocation_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_flag, 1, ENC_BIG_ENDIAN); ++ if (resource_allocation_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocation flag value [0..1]"); ++ } ++ ++ // Resource allocation type ++ guint8 resource_alloction_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_allocation_type, 1, ENC_BIG_ENDIAN); ++ if (resource_alloction_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource allocation type value [0..1]"); ++ } ++ ++ // Resource block coding ++ ptvcursor_add(ptvc, hf_nfapi_resource_block_coding, 4, ENC_BIG_ENDIAN); ++ ++ // MCS_2 ++ guint8 mcs_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs_2, 1, ENC_BIG_ENDIAN); ++ if (mcs_2_value > 31) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs 2 value [0..31]"); ++ } ++ ++ // New data indication_2 ++ guint8 new_data_indication_2_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indication_two, 1, ENC_BIG_ENDIAN); ++ if (new_data_indication_2_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indication 2 value [0..1]"); ++ } ++ ++ // Number of antenna ports ++ guint8 number_of_antenna_ports_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_antenna_ports, 1, ENC_BIG_ENDIAN); ++ if (number_of_antenna_ports_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of antenna ports value [0..2]"); ++ } ++ ++ // TPMI ++ guint8 tpmi_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpmi, 1, ENC_BIG_ENDIAN); ++ if (number_of_antenna_ports_value == 2) ++ { ++ if (tpmi_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi value [0..7]"); ++ } ++ } ++ else if (number_of_antenna_ports_value == 4) ++ { ++ if (tpmi_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpmi value [0..63]"); ++ } ++ } ++ ++ // Total DCI length including padding ++ ptvcursor_add(ptvc, hf_nfapi_total_dci_length_including_padding, 1, ENC_BIG_ENDIAN); ++ ++ // N_UL_RB ++ guint8 n_ul_rb_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_n_ul_rb, 1, ENC_BIG_ENDIAN); ++ if (!(n_ul_rb_value == 6 || n_ul_rb_value == 15 || n_ul_rb_value == 25 || n_ul_rb_value == 50 || ++ n_ul_rb_value == 75 || n_ul_rb_value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid n ul rb value [6, 15, 25, 50, 75, 100]"); ++ } ++} ++static void dissect_hi_dci0_dci_ul_rel12_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // PSCCH Resource ++ guint8 pscch_resource_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pscch_resource, 1, ENC_BIG_ENDIAN); ++ if (pscch_resource_value > 0x3F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pscch resource value [0..0x3F]"); ++ } ++ ++ // Time resource pattern ++ guint8 time_resource_pattern_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_time_resource_pattern, 1, ENC_BIG_ENDIAN); ++ if (time_resource_pattern_value > 0x7F) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid time resource pattern value [0..0x7F]"); ++ } ++ ++} ++static void dissect_hi_dci0_mdpcch_dci_ul_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // MPDCCH Narrowband ++ guint8 mpdcch_narrowband_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_narrowband, 1, ENC_BIG_ENDIAN); ++ if (mpdcch_narrowband_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mpdcch narrowband value [0..15]"); ++ } ++ ++ // Number of PRB pairs ++ guint8 number_of_prb_pairs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_prb_pairs, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_prb_pairs_value == 2 || number_of_prb_pairs_value == 4 || number_of_prb_pairs_value == 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of prb pairs value [2, 4, 6]"); ++ } ++ ++ // Resource Block Assignment ++ guint8 resource_block_assignment_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_assignment, 1, ENC_BIG_ENDIAN); ++ if (resource_block_assignment_value > 14) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block assignment value [0..14]"); ++ } ++ ++ // MPDCCH transmission type ++ guint8 mpdcch_transmission_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_transmission_type, 1, ENC_BIG_ENDIAN); ++ if (mpdcch_transmission_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mpdcch transmission type value [0..1]"); ++ } ++ ++ // Start symbol ++ guint8 start_symbol_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_start_symbol, 1, ENC_BIG_ENDIAN); ++ if (!(start_symbol_value >= 1 && start_symbol_value <=4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid start symbol value [0..1]"); ++ } ++ ++ // ECCE index ++ guint8 ecce_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ecce_index, 1, ENC_BIG_ENDIAN); ++ if (ecce_index_value > 22) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ecce index value [0..22]"); ++ } ++ ++ // Aggregation level ++ guint8 aggregation_level_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_aggregation_level, 1, ENC_BIG_ENDIAN); ++ if (!(aggregation_level_value == 2 || aggregation_level_value == 4 || aggregation_level_value == 8 || ++ aggregation_level_value == 16 || aggregation_level_value == 24)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid aggregation level value [2, 4, 8, 16, 24]"); ++ } ++ ++ // RNTI type ++ guint8 rnti_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_rnti_type, 1, ENC_BIG_ENDIAN); ++ if (!(rnti_type_value == 0 || rnti_type_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti type value [0, 4]"); ++ } ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // CEMode ++ guint8 cemode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ce_mode, 1, ENC_BIG_ENDIAN); ++ if (!(cemode_value == 1 || cemode_value == 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid cemode value [1,2]"); ++ } ++ ++ // DMRS scrambling init ++ guint16 drms_scrambling_init_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_drms_scrambling_init, 2, ENC_BIG_ENDIAN); ++ if (drms_scrambling_init_value < 503) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid drms scrambling init value [0..503]"); ++ } ++ ++ // Initial transmission SF (io) ++ guint16 initial_transmission_sf_io_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_transmission_sf, 2, ENC_BIG_ENDIAN); ++ if (!(initial_transmission_sf_io_value <= 10239 || initial_transmission_sf_io_value == 0xFFFF)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial transmission sf io value [0..10239, 0xFFFF]"); ++ } ++ ++ // Transmission power ++ guint16 transmission_power_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_transmission_power, 2, ENC_BIG_ENDIAN); ++ if (transmission_power_value > 10000) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid transmission power value [0..10000]"); ++ } ++ ++ // DCI format ++ guint8 dci_format_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mpdcch_ul_dci_format, 1, ENC_BIG_ENDIAN); ++ if (!(dci_format_value == 1 || dci_format_value == 2 || dci_format_value == 4 || dci_format_value == 5)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci format value [1, 2, 4, 5]"); ++ } ++ ++ // Resource block start ++ guint8 resource_block_start_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_resource_block_start, 1, ENC_BIG_ENDIAN); ++ if (resource_block_start_value > 99) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid resource block start value [0..99]"); ++ } ++ ++ // Number of resource blocks ++ guint8 number_of_resource_blocks_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_resource_blocks, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_resource_blocks_value >= 1 && number_of_resource_blocks_value <= 6)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of resource blocks value [1..6]"); ++ } ++ ++ // MCS ++ guint8 mcs_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_mcs, 1, ENC_BIG_ENDIAN); ++ if (mcs_value > 15) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mcs value [0..15]"); ++ } ++ ++ // PUSCH repetition levels ++ guint8 pusch_repetition_levels_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_pusch_repetition_levels, 1, ENC_BIG_ENDIAN); ++ if (dci_format_value == 4) ++ { ++ if (!(pusch_repetition_levels_value >= 1 && pusch_repetition_levels_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pusch repetition levels value [1..4]"); ++ } ++ } ++ else if (dci_format_value == 5) ++ { ++ if (!(pusch_repetition_levels_value >= 1 && pusch_repetition_levels_value <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pusch repetition levels value [1..8]"); ++ } ++ } ++ ++ // Frequency hopping flag ++ guint8 frequency_hopping_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_frequency_hopping_flag, 1, ENC_BIG_ENDIAN); ++ if (frequency_hopping_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid frequency hopping flag value [0..1]"); ++ } ++ ++ // New Data indication ++ guint8 new_data_indication_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_new_data_indication, 1, ENC_BIG_ENDIAN); ++ if (new_data_indication_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid new data indication value [0..1]"); ++ } ++ ++ // HARQ process ++ guint8 harq_process_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_process, 1, ENC_BIG_ENDIAN); ++ if (harq_process_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq process value [0..7]"); ++ } ++ ++ // Redundancy version ++ guint8 redundancy_version_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_redundancy_version, 1, ENC_BIG_ENDIAN); ++ if (redundancy_version_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid redundancy version value [0..3]"); ++ } ++ ++ // TPC ++ guint8 tpc_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tpc, 1, ENC_BIG_ENDIAN); ++ if (tpc_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid tpc value [0..3]"); ++ } ++ ++ // CSI request ++ guint8 csi_request_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_csi_request, 1, ENC_BIG_ENDIAN); ++ if (csi_request_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid csi request value [0..1]"); ++ } ++ ++ // UL index ++ guint8 ul_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ul_index, 1, ENC_BIG_ENDIAN); ++ if (ul_index_value > 3) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul index value [0..3]"); ++ } ++ ++ // DAI presence flag ++ guint8 dai_presence_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dai_presence_flag, 1, ENC_BIG_ENDIAN); ++ if (dai_presence_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dai presence value [0..1]"); ++ } ++ ++ // DL assignment index ++ guint8 dl_assignment_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dl_assignment_index, 1, ENC_BIG_ENDIAN); ++ if (!(dl_assignment_value >=1 && dl_assignment_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dl assignment value [1, 2, 3, 4]"); ++ } ++ ++ // SRS request ++ guint8 srs_request_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_srs_request, 1, ENC_BIG_ENDIAN); ++ if (srs_request_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid srs request value [0..1]"); ++ } ++ ++ // DCI subframe repetition number ++ guint8 dci_subframe_repetition_number_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_dci_subframe_repetition_number, 1, ENC_BIG_ENDIAN); ++ if (!(dci_subframe_repetition_number_value >= 1 && dci_subframe_repetition_number_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid dci subframe repetition number value [1..4]"); ++ } ++ ++ //TPC bitmap ++ ptvcursor_add(ptvc, hf_nfapi_tpc_bitmap, 4, ENC_BIG_ENDIAN); ++ ++ // Total DCI length including padding ++ ptvcursor_add(ptvc, hf_nfapi_total_dci_length_include_padding, 1, ENC_BIG_ENDIAN); ++ ++ // Number of TX Antenna ports ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_tx_antenna_ports, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "TX Antenna Ports", ett_nfapi_tx_antenna_ports, count, dissect_precoding_value); ++} ++static void dissect_rx_ue_info_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++} ++static void dissect_rx_indication_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // Data offset ++ ptvcursor_add(ptvc, hf_nfapi_data_offset, 2, ENC_BIG_ENDIAN); ++ ++ // UL_CQI ++ ptvcursor_add(ptvc, hf_nfapi_ul_cqi, 1, ENC_BIG_ENDIAN); ++ ++ // Timing advance ++ guint16 timing_advance_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..63]"); ++ } ++} ++static void dissect_rx_indication_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Timing advance R9 ++ guint16 timing_advance_r9_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_advance_r9, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_r9_value > 7690) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance r9 value [0..7690]"); ++ } ++ ++} ++static void dissect_harq_indication_data_bundling_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++ ++ guint8 value_1 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_1, 1, ENC_BIG_ENDIAN); ++ if (!(value_1 >= 1 && value_1 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 1 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_format_1a_1b_bundling_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_multplexing_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++ ++ guint8 value_1 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_1, 1, ENC_BIG_ENDIAN); ++ if (!(value_1 >= 1 && value_1 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 1 [1..7]"); ++ } ++ ++ guint8 value_2 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_2, 1, ENC_BIG_ENDIAN); ++ if (!(value_2 >= 1 && value_2 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 2 [1..7]"); ++ } ++ ++ guint8 value_3 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_3, 1, ENC_BIG_ENDIAN); ++ if (!(value_3 >= 1 && value_3 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 3 [1..7]"); ++ } ++ ++} ++static void dissect_harq_indication_data_format_1a_1b_multplexing_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_special_bundling_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0_special, 1, ENC_BIG_ENDIAN); ++ if (value_0 > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [0..4]"); ++ } ++} ++static void dissect_harq_indication_data_format_1a_1b_special_bundling_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0_special, 1, ENC_BIG_ENDIAN); ++ if (value_0 > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [0..4]"); ++ } ++} ++static void dissect_harq_indication_data_channel_selection_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_format_3_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_format_4_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_data_format_5_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 value_0 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_data_value_0, 1, ENC_BIG_ENDIAN); ++ if (!(value_0 >= 1 && value_0 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid value 0 [1..7]"); ++ } ++} ++static void dissect_harq_indication_rel8_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ guint8 mode = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tdd_harq_mode, 1, ENC_BIG_ENDIAN); ++ if (mode > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mode value [0..4]"); ++ } ++ ++ guint8 number_of_ack_nack_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ack_nack, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_ack_nack_value >= 1 && number_of_ack_nack_value <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..4]"); ++ } ++ ++ switch (mode) ++ { ++ case 0: ++ { ++ dissect_harq_indication_data_bundling_value(ptvc, pinfo); ++ break; ++ } ++ case 1: ++ { ++ dissect_harq_indication_data_multplexing_value(ptvc, pinfo); ++ break; ++ } ++ case 2: ++ { ++ dissect_harq_indication_data_special_bundling_value(ptvc, pinfo); ++ break; ++ } ++ }; ++} ++static void dissect_harq_indication_rel9_later_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 i; ++ proto_item* item; ++ ++ guint8 mode = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tdd_harq_mode, 1, ENC_BIG_ENDIAN); ++ if (mode > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mode value [0..4]"); ++ } ++ ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ack_nack, 1, ENC_BIG_ENDIAN); ++ if (mode == 0 || mode == 1) ++ { ++ if (!(count >= 1 && count <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..4]"); ++ } ++ } ++ else if (mode == 3) ++ { ++ if (!(count >= 1 && count <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..8]"); ++ } ++ } ++ else if (mode == 4) ++ { ++ if (!(count >= 1 && count <= 21)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..21]"); ++ } ++ } ++ ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_harq_ack_nack_data, "ACK/NACK Data"); ++ ++ for (i = 0; i < count; ++i) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_harq_ack_nack_data, "[%d]", i); ++ ++ switch (mode) ++ { ++ case 0: ++ { ++ dissect_harq_indication_data_format_1a_1b_bundling_value(ptvc, pinfo); ++ break; ++ } ++ case 1: ++ { ++ dissect_harq_indication_data_format_1a_1b_multplexing_value(ptvc, pinfo); ++ break; ++ } ++ case 2: ++ { ++ dissect_harq_indication_data_format_1a_1b_special_bundling_value(ptvc, pinfo); ++ break; ++ } ++ case 3: ++ { ++ dissect_harq_indication_data_channel_selection_value(ptvc, pinfo); ++ break; ++ } ++ case 4: ++ { ++ dissect_harq_indication_data_format_3_value(ptvc, pinfo); ++ break; ++ } ++ }; ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++} ++static void dissect_harq_indication_rel13_later_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 i = 0; ++ proto_item* item; ++ ++ guint8 mode = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_tdd_harq_mode, 1, ENC_BIG_ENDIAN); ++ if (mode > 6) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid mode value [0..6]"); ++ } ++ ++ ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_ack_nack, 2, ENC_BIG_ENDIAN); ++ if (mode == 0 || mode == 1) ++ { ++ if (!(count >= 1 && count <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..4]"); ++ } ++ } ++ else if (mode == 3) ++ { ++ if (!(count >= 1 && count <= 8)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..8]"); ++ } ++ } ++ else if (mode == 4) ++ { ++ if (!(count >= 1 && count <= 21)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [1..21]"); ++ } ++ } ++ else if (mode == 5 || mode == 6) ++ { ++ if (count < 22) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack nack value [>= 22]"); ++ } ++ ++ } ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_harq_ack_nack_data, "ACK/NACK Data"); ++ ++ for (i = 0; i < count; ++i) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_harq_ack_nack_data, "[%d]", i); ++ ++ switch (mode) ++ { ++ case 0: ++ { ++ dissect_harq_indication_data_format_1a_1b_bundling_value(ptvc, pinfo); ++ break; ++ } ++ case 1: ++ { ++ dissect_harq_indication_data_format_1a_1b_multplexing_value(ptvc, pinfo); ++ break; ++ } ++ case 2: ++ { ++ dissect_harq_indication_data_special_bundling_value(ptvc, pinfo); ++ break; ++ } ++ case 3: ++ { ++ dissect_harq_indication_data_channel_selection_value(ptvc, pinfo); ++ break; ++ } ++ case 4: ++ { ++ dissect_harq_indication_data_format_3_value(ptvc, pinfo); ++ break; ++ } ++ case 5: ++ { ++ dissect_harq_indication_data_format_4_value(ptvc, pinfo); ++ break; ++ } ++ case 6: ++ { ++ dissect_harq_indication_data_format_5_value(ptvc, pinfo); ++ break; ++ } ++ }; ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++} ++static void dissect_harq_indication_rel8_fdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ guint8 harq_tb_1 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_tb_1, 1, ENC_BIG_ENDIAN); ++ if (!(harq_tb_1 >= 1 && harq_tb_1 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq tb 1 [1..7]"); ++ } ++ ++ guint8 harq_tb_2 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_harq_tb_2, 1, ENC_BIG_ENDIAN); ++ if (!(harq_tb_2 >= 1 && harq_tb_2 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq tb 2 [1..7]"); ++ } ++ ++} ++static void dissect_harq_tb_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint8 harq_tb_1 = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_harq_tb_n, 1, ENC_BIG_ENDIAN); ++ if (!(harq_tb_1 >= 1 && harq_tb_1 <= 7)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq tb n [1..7]"); ++ } ++} ++static void dissect_harq_indication_rel9_later_fdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Mode ++ guint8 harq_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_fdd_harq_mode, 1, ENC_BIG_ENDIAN); ++ if (harq_mode_value > 2) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq mode value [0..2]"); ++ } ++ ++ // Number of ACK/NACK ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ack_nack, 1, ENC_BIG_ENDIAN); ++ ++ if (harq_mode_value == 0) ++ { ++ if (!(count >=1 && count <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..2]"); ++ } ++ } ++ else if (harq_mode_value == 1) ++ { ++ if (!(count >= 1 && count <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..4]"); ++ } ++ ++ } ++ else if (harq_mode_value == 2) ++ { ++ if (!(count >= 1 && count <= 10)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..10]"); ++ } ++ ++ } ++ ++ dissect_array_value(ptvc, pinfo, "HARQ TB List", ett_nfapi_harq_data, count, dissect_harq_tb_value); ++} ++static void dissect_harq_indication_rel13_later_fdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Mode ++ guint8 harq_mode_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_fdd_harq_mode, 1, ENC_BIG_ENDIAN); ++ if (harq_mode_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid harq mode value [0..4]"); ++ } ++ ++ // Number of ACK/NACK ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_ack_nack, 2, ENC_BIG_ENDIAN); ++ ++ if (harq_mode_value == 0) ++ { ++ if (!(count >= 1 && count <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..2]"); ++ } ++ } ++ else if (harq_mode_value == 1) ++ { ++ if (!(count >= 1 && count <= 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..4]"); ++ } ++ ++ } ++ else if (harq_mode_value == 2) ++ { ++ if (!(count >= 1 && count <= 10)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [1..10]"); ++ } ++ } ++ else if (harq_mode_value == 3 || harq_mode_value == 4) ++ { ++ if (count < 22) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of ack/nack value [>= 22]"); ++ } ++ } ++ ++ dissect_array_value(ptvc, pinfo, "HARQ TB List", ett_nfapi_harq_data, count, dissect_harq_tb_value); ++} ++static void dissect_ul_cqi_information_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // UL_CQI ++ ptvcursor_add(ptvc, hf_nfapi_ul_cqi, 1, ENC_BIG_ENDIAN); ++ ++ // Channel ++ guint8 channel_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_channel, 1, ENC_BIG_ENDIAN); ++ if (channel_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid channel value [0..1]"); ++ } ++} ++static void dissect_crc_indication_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // CRC Flag ++ guint8 crc_flag_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_crc_flag, 1, ENC_BIG_ENDIAN); ++ if (crc_flag_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid crc flag value [0..1]"); ++ } ++} ++static void dissect_rx_cqi_indication_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ //Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // Data Offset ++ ptvcursor_add(ptvc, hf_nfapi_data_offset, 2, ENC_BIG_ENDIAN); ++ ++ // UL_CQI ++ ptvcursor_add(ptvc, hf_nfapi_ul_cqi, 1, ENC_BIG_ENDIAN); ++ ++ // RI ++ guint8 ri_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_ri, 1, ENC_BIG_ENDIAN); ++ if (ri_value > 8) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ri value [0..8]"); ++ } ++ ++ // Timing Advance ++ guint16 timing_advance_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_value > 8) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..63]"); ++ } ++} ++static void dissect_ri_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // RI ++ guint8 ri_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ri, 1, ENC_BIG_ENDIAN); ++ if (ri_value > 8) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ri value [0..8]"); ++ } ++} ++static void dissect_rx_cqi_indication_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Length ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ ++ // Data Offset ++ ptvcursor_add(ptvc, hf_nfapi_data_offset, 2, ENC_BIG_ENDIAN); ++ ++ // UL_CQI ++ ptvcursor_add(ptvc, hf_nfapi_ul_cqi, 1, ENC_BIG_ENDIAN); ++ ++ // Number of CC reported ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_cc_reported, 1, ENC_BIG_ENDIAN); ++ if (!(count >= 1 && count <= 5)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of CC reported value [1..5]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "CC List", ett_nfapi_cc, count, dissect_ri_value); ++ ++ // Timing Advance ++ guint16 timing_advance_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..63]"); ++ } ++ ++ // Timing Advance R9 ++ guint16 timing_advance_r9_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance_r9, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_r9_value > 7690) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..7690]"); ++ } ++} ++static void dissect_rach_indication_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // RNTI ++ guint16 rnti_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_rnti, 2, ENC_BIG_ENDIAN); ++ if (rnti_value < 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rnti value [1..65535]"); ++ } ++ ++ // Preamble ++ guint8 preamble_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_preamble, 1, ENC_BIG_ENDIAN); ++ if (preamble_value > 63) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid preamble value [0..63]"); ++ } ++ ++ // Timing Advance ++ guint16 timing_advance_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_value > 1282) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..1282]"); ++ } ++ ++} ++static void dissect_rach_indication_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Timing Advance R9 ++ guint16 timing_advance_r9_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_advance_r9, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_r9_value > 7690) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..7690]"); ++ } ++} ++static void dissect_rach_indication_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // RACH resource type ++ guint8 rach_resource_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_rach_resource_type, 1, ENC_BIG_ENDIAN); ++ if (rach_resource_type_value > 4) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid rach resource type value [0..4]"); ++ } ++} ++static void dissect_snr_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // SNR ++ ptvcursor_add(ptvc, hf_nfapi_snr, 1, ENC_BIG_ENDIAN); ++} ++static void dissect_srs_indication_rel8_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Doppler estimation ++ ptvcursor_add(ptvc, hf_nfapi_doppler_estimation, 2, ENC_BIG_ENDIAN); ++ ++ // Timing Advance ++ guint16 timing_advance_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_value > 1282) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..1282]"); ++ } ++ ++ // Number of resource blocks ++ guint8 count = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_resource_blocks, 1, ENC_BIG_ENDIAN); ++ ++ // RB start ++ ptvcursor_add(ptvc, hf_nfapi_rb_start, 1, ENC_BIG_ENDIAN); ++ ++ ++ dissect_array_value(ptvc, pinfo, "RB List", ett_nfapi_rbs, count, dissect_snr_value); ++} ++static void dissect_srs_indication_rel9_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Timing Advance R9 ++ guint16 timing_advance_r9_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_timing_advance_r9, 2, ENC_BIG_ENDIAN); ++ if (timing_advance_r9_value > 7690) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid timing advance value [0..7690]"); ++ } ++} ++static void dissect_srs_indication_rel10_tdd_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UpPTS Symbol ++ guint8 uppts_symbol_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_up_pts_symbol, 1, ENC_BIG_ENDIAN); ++ if (uppts_symbol_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid up pts symbol value [0..1]"); ++ } ++ ++} ++static void dissect_tdd_channel_measurement_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint16 i = 0; ++ guint16 j = 0; ++ ++ // numPRBperSubband ++ ptvcursor_add(ptvc, hf_nfapi_number_prb_per_subband, 1, ENC_BIG_ENDIAN); ++ ++ // Number of subbands ++ guint8 num_subbands = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_subbands, 1, ENC_BIG_ENDIAN); ++ ++ // numAntennas ++ guint8 num_phy_ant = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_antennas, 1, ENC_BIG_ENDIAN); ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_subbands, "Subbands"); ++ ++ for (i = 0; i < num_subbands; ++i) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_subbands, "[%d]", i); ++ ++ // subbandIndex ++ ptvcursor_add(ptvc, hf_nfapi_subband_index, 1, ENC_BIG_ENDIAN); ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_antennas, "Physical Antennas"); ++ ++ for (j = 0; j < num_phy_ant; ++j) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_antennas, "[%d]", j); ++ ++ // Channel ++ ptvcursor_add(ptvc, hf_nfapi_channel_coefficient, 2, ENC_BIG_ENDIAN); ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++} ++static void dissect_srs_indication_rel11_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ //UL_RTOA ++ guint16 ul_rtoa_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_ul_rtoa, 2, ENC_BIG_ENDIAN); ++ if (ul_rtoa_value > 4800) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid ul rtoa value [0..4800]"); ++ } ++} ++static void dissect_lbt_dl_config_request_pdsch_req_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // nCCA ++ ptvcursor_add(ptvc, hf_nfapi_mp_cca, 4, ENC_BIG_ENDIAN); ++ ++ // NCCA ++ ptvcursor_add(ptvc, hf_nfapi_n_cca, 4, ENC_BIG_ENDIAN); ++ ++ // Offset ++ guint32 ul_rtoa_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_offset, 4, ENC_BIG_ENDIAN); ++ if (ul_rtoa_value > 999) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid offset value [0..999]"); ++ } ++ ++ // LTE TXOP SF ++ ptvcursor_add(ptvc, hf_nfapi_lte_txop_sf, 4, ENC_BIG_ENDIAN); ++ ++ // TXOP SFN/SF End ++ ptvcursor_add(ptvc, hf_nfapi_txop_sfn_sf_end, 2, ENC_BIG_ENDIAN); ++ ++ // LBT mode ++ guint32 lbt_mode = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_lbt_mode, 4, ENC_BIG_ENDIAN); ++ if (lbt_mode > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid offset value [0..1]"); ++ } ++} ++static void dissect_lbt_dl_config_request_drs_req_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // Offset ++ guint32 ul_rtoa_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_offset, 4, ENC_BIG_ENDIAN); ++ if (ul_rtoa_value > 999) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid offset value [0..999]"); ++ } ++ ++ // SFN/SF End ++ ptvcursor_add(ptvc, hf_nfapi_sfn_sf_end, 2, ENC_BIG_ENDIAN); ++ ++ // LBT mode ++ guint32 lbt_mode = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_lbt_mode, 4, ENC_BIG_ENDIAN); ++ if (lbt_mode > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid offset value [0..1]"); ++ } ++} ++static void dissect_lbt_dl_config_request_pdsch_resp_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // result ++ guint32 result_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_result, 4, ENC_BIG_ENDIAN); ++ if (result_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid result value [0..1]"); ++ } ++ ++ // LTE TXOP symbols ++ ptvcursor_add(ptvc, hf_nfapi_txop_symbols, 4, ENC_BIG_ENDIAN); ++ ++ // Initial Partial SF ++ guint32 initial_partial_sf_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_initial_partial_sf, 4, ENC_BIG_ENDIAN); ++ if (initial_partial_sf_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid initial partial sf value [0..1]"); ++ } ++} ++static void dissect_lbt_dl_config_request_drs_resp_rel13_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // Handle ++ ptvcursor_add(ptvc, hf_nfapi_handle, 4, ENC_BIG_ENDIAN); ++ ++ // result ++ guint32 result_value = tvb_get_guint32(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), ENC_BIG_ENDIAN); ++ item = ptvcursor_add(ptvc, hf_nfapi_result, 4, ENC_BIG_ENDIAN); ++ if (result_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid result value [0..1]"); ++ } ++} ++static void dissect_tx_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PDU length ++ guint16 len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_length, 2, ENC_BIG_ENDIAN); ++ ++ // PDU index ++ ptvcursor_add(ptvc, hf_nfapi_pdu_index, 2, ENC_BIG_ENDIAN); ++ ++ // PDU#N ++ ptvcursor_add(ptvc, hf_nfapi_pdu, len, ENC_NA); ++} ++static void dissect_tx_request_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of PDUs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_pdus, 2, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "TX PDU List", ett_nfapi_tx_request_pdu_list, num_pdu, dissect_tx_pdu); ++} ++static void dissect_harq_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_harq_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of HARQs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_harqs, 2, ENC_BIG_ENDIAN); ++ ++ ++ dissect_array_value(ptvc, pinfo, "HARQ PDU List", ett_nfapi_harq_indication_pdu_list, num_pdu, dissect_harq_indication_pdu); ++} ++static void dissect_crc_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_crc_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of CRCs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_crcs, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "CRC PDU List", ett_nfapi_crc_indication_pdu_list, num_pdu, dissect_crc_indication_pdu); ++} ++static void dissect_sr_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_rx_sr_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of SRs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_srs, 2, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "SR PDU List", ett_nfapi_sr_indication_pdu_list, num_pdu, dissect_sr_indication_pdu); ++} ++static void dissect_cqi_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_rx_cqi_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of PDUs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_cqi, 2, ENC_BIG_ENDIAN); ++ ++ guint16* lengths = (guint16*)wmem_alloc0(wmem_packet_scope(), num_pdu * 2); ++ memset(lengths, 0, num_pdu * 2); ++ ++ tvbuff_t* tvb = ptvcursor_tvbuff(ptvc); ++ guint8 tmp_offset = ptvcursor_current_offset(ptvc); ++ ++ int i = 0; ++ for (i = 0; i < num_pdu; ++i) ++ { ++ guint16 instance_len = tvb_get_ntohs(tvb, tmp_offset); ++ tmp_offset += 2; ++ guint8 pdu_end = tmp_offset + instance_len; ++ ++ while (tmp_offset < pdu_end) ++ { ++ guint16 tlv_id = tvb_get_ntohs(tvb, tmp_offset); ++ tmp_offset += 2; ++ guint16 tlv_len = tvb_get_ntohs(tvb, tmp_offset); ++ tmp_offset += 2; ++ ++ if (tlv_id == 0x202F) ++ { ++ lengths[i] = tvb_get_ntohs(tvb, tmp_offset); ++ } ++ else if (tlv_id == 0x2030) ++ { ++ lengths[i] = tvb_get_ntohs(tvb, tmp_offset); ++ } ++ ++ tmp_offset += tlv_len; ++ } ++ } ++ ++ dissect_array_value(ptvc, pinfo, "CQI PDU List", ett_nfapi_cqi_indication_pdu_list, num_pdu, dissect_cqi_indication_pdu); ++ ++ for (i = 0; i < num_pdu; ++i) ++ { ++ ptvcursor_add(ptvc, hf_nfapi_pdu, lengths[i], ENC_NA); ++ } ++} ++static void dissect_preamble_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_rach_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of Preambles ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_preambles, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "Preamble PDU List", ett_nfapi_preamble_indication_pdu_list, num_pdu, dissect_preamble_indication_pdu); ++} ++static void dissect_srs_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Instance Length ++ guint16 instance_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_instance_length, 2, ENC_BIG_ENDIAN); ++ guint instance_end = (ptvcursor_current_offset(ptvc) + instance_len - 2); ++ dissect_tlv_list(ptvc, pinfo, instance_end); ++} ++static void dissect_srs_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of UEs ++ guint8 num_pdu = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_srss, 1, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "SRS PDU List", ett_nfapi_srs_indication_pdu_list, num_pdu, dissect_srs_indication_pdu); ++} ++static void dissect_lbt_dl_config_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PDU Type ++ guint8 pdu_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_lbt_dl_req_pdu_type, 1, ENC_BIG_ENDIAN); ++ if (pdu_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdu type value [0..1]"); ++ } ++ ++ guint8 size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_size, 1, ENC_BIG_ENDIAN); ++ guint pdu_end = (ptvcursor_current_offset(ptvc) + size - 2); ++ ++ dissect_tlv_list(ptvc, pinfo, pdu_end); ++} ++static void dissect_lbt_dl_config_request_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of PDUs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_number_pdus, 2, ENC_BIG_ENDIAN); ++ if (!(num_pdu >= 1 && num_pdu <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pdus value [1..2]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "LBT DL PDU List", ett_nfapi_lbt_dl_config_pdu_list, num_pdu, dissect_lbt_dl_config_pdu); ++} ++static void dissect_lbt_dl_indication_pdu(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PDU Type ++ guint8 pdu_type_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_lbt_dl_ind_pdu_type, 1, ENC_BIG_ENDIAN); ++ if (pdu_type_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid pdu type value [0..1]"); ++ } ++ ++ // PDU Size ++ guint8 size = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pdu_size, 1, ENC_BIG_ENDIAN); ++ guint pdu_end = (ptvcursor_current_offset(ptvc) + size - 2); ++ dissect_tlv_list(ptvc, pinfo, pdu_end); ++} ++static void dissect_lbt_indication_message_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of PDUs ++ guint16 num_pdu = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_number_pdus, 2, ENC_BIG_ENDIAN); ++ if (!(num_pdu >= 1 && num_pdu <= 2)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of pdus value [1..2]"); ++ } ++ ++ dissect_array_value(ptvc, pinfo, "LBT DL PDU List", ett_nfapi_lbt_dl_indication_pdu_list, num_pdu, dissect_lbt_dl_indication_pdu); ++} ++static void dissect_lte_rssi_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Frequency Band Indicator ++ ptvcursor_add(ptvc, hf_nfapi_frequency_band_indicator, 1, ENC_BIG_ENDIAN); ++ ++ // Measurement Period ++ ptvcursor_add(ptvc, hf_nfapi_measurement_period, 2, ENC_BIG_ENDIAN); ++ ++ // Bandwidth ++ guint8 bandwidth_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_bandwidth, 1, ENC_BIG_ENDIAN); ++ if (!(bandwidth_value == 6 || bandwidth_value == 15 || bandwidth_value == 25 || ++ bandwidth_value == 50 || bandwidth_value == 75 || bandwidth_value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of EARFCNs ++ guint8 num_earfcns = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_earfcns, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "EARFCNs", ett_nfapi_earfcn_list, num_earfcns, dissect_earfcn_value); ++} ++static void dissect_uarfcn_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UARFCN ++ ptvcursor_add(ptvc, hf_nfapi_uarfcn, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_rssi_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Frequency Band Indicator ++ ptvcursor_add(ptvc, hf_nfapi_frequency_band_indicator, 1, ENC_BIG_ENDIAN); ++ ++ // Measurement Period ++ ptvcursor_add(ptvc, hf_nfapi_measurement_period, 2, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of UARFCNs ++ guint8 num_uarfcns = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_uarfcns, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "UARFCNs", ett_nfapi_uarfcn_list, num_uarfcns, dissect_uarfcn_value); ++} ++static void dissect_arfcn_dir_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // ARFCN ++ ptvcursor_add(ptvc, hf_nfapi_arfcn, 2, ENC_BIG_ENDIAN); ++ ++ // Direction ++ guint8 direction_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_arfcn_direction, 1, ENC_BIG_ENDIAN); ++ if (direction_value > 1) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid direction value [0..1]"); ++ } ++ ++} ++static void dissect_geran_rssi_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Frequency Band Indicator ++ ptvcursor_add(ptvc, hf_nfapi_frequency_band_indicator, 1, ENC_BIG_ENDIAN); ++ ++ // Measurement Period ++ ptvcursor_add(ptvc, hf_nfapi_measurement_period, 2, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of ARFCNs ++ guint8 num_arfcns = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_arfcns, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "ARFCNs", ett_nfapi_arfcn_list, num_arfcns, dissect_arfcn_dir_value); ++} ++static void dissect_rssi_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // RSSI ++ ptvcursor_add(ptvc, hf_nfapi_rssi, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_rssi_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of RSSI ++ guint16 num_rssi = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_rssi, 2, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "ARFCNs", ett_nfapi_rssi_list, num_rssi, dissect_rssi_value); ++} ++static void dissect_pci_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PCI ++ ptvcursor_add(ptvc, hf_nfapi_pci, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_cell_search_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // EARFCN ++ ptvcursor_add(ptvc, hf_nfapi_earfcn, 2, ENC_BIG_ENDIAN); ++ ++ // Measurement Bandwidth ++ ptvcursor_add(ptvc, hf_nfapi_measurement_bandwidth, 1, ENC_BIG_ENDIAN); ++ ++ // Exhaustive Search ++ ptvcursor_add(ptvc, hf_nfapi_exhaustive_search, 1, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of PCI ++ guint8 num_pci = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_pci, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "PCIs", ett_nfapi_pci_list, num_pci, dissect_pci_value); ++} ++static void dissect_psc_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PSC ++ ptvcursor_add(ptvc, hf_nfapi_psc, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_cell_search_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UARFCN ++ ptvcursor_add(ptvc, hf_nfapi_uarfcn, 2, ENC_BIG_ENDIAN); ++ ++ // Exhaustive Search ++ ptvcursor_add(ptvc, hf_nfapi_exhaustive_search, 1, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of PSC ++ guint8 num_psc = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_psc, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "PSCs", ett_nfapi_psc_list, num_psc, dissect_psc_value); ++} ++static void dissect_arfcn_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // ARFCN ++ ptvcursor_add(ptvc, hf_nfapi_arfcn, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_geran_cell_search_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++ ++ // Number of ARFCN ++ guint8 num_arfcn = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_arfcns, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "ARFCNs", ett_nfapi_arfcn_list, num_arfcn, dissect_arfcn_value); ++} ++ ++static void dissect_lte_cell_found_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PCI ++ ptvcursor_add(ptvc, hf_nfapi_pci, 2, ENC_BIG_ENDIAN); ++ ++ // RSRP ++ ptvcursor_add(ptvc, hf_nfapi_rsrp, 1, ENC_BIG_ENDIAN); ++ ++ // RSRQ ++ ptvcursor_add(ptvc, hf_nfapi_rsrq, 1, ENC_BIG_ENDIAN); ++ ++ // Frequency Offset ++ ptvcursor_add(ptvc, hf_nfapi_frequency_offset, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_cell_search_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of LTE Cells Found ++ guint16 num_lte_cells = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_lte_cells_found, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "LTE Cells Found", ett_nfapi_lte_cells_found_list, num_lte_cells, dissect_lte_cell_found_value); ++} ++static void dissect_utran_cell_found_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // PSC ++ ptvcursor_add(ptvc, hf_nfapi_psc, 2, ENC_BIG_ENDIAN); ++ ++ // RSCP ++ ptvcursor_add(ptvc, hf_nfapi_rscp, 1, ENC_BIG_ENDIAN); ++ ++ // EcN0 ++ ptvcursor_add(ptvc, hf_nfapi_enco, 1, ENC_BIG_ENDIAN); ++ ++ // Frequency Offset ++ ptvcursor_add(ptvc, hf_nfapi_frequency_offset, 2, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_cell_search_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of UTRAN Cells Found ++ guint16 num_utran_cells = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_utran_cells_found, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "UTRAN Cells Found", ett_nfapi_utran_cells_found_list, num_utran_cells, dissect_utran_cell_found_value); ++} ++static void dissect_geran_cell_found_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // ARFCN ++ ptvcursor_add(ptvc, hf_nfapi_arfcn, 2, ENC_BIG_ENDIAN); ++ ++ // BSIC ++ ptvcursor_add(ptvc, hf_nfapi_bsic, 1, ENC_BIG_ENDIAN); ++ ++ // RxLev ++ ptvcursor_add(ptvc, hf_nfapi_rxlev, 1, ENC_BIG_ENDIAN); ++ ++ // RxQual ++ ptvcursor_add(ptvc, hf_nfapi_rxqual, 1, ENC_BIG_ENDIAN); ++ ++ // Frequency Offset ++ ptvcursor_add(ptvc, hf_nfapi_frequency_offset, 2, ENC_BIG_ENDIAN); ++ ++ // SFN Offset ++ ptvcursor_add(ptvc, hf_nfapi_sfn_offset, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_geran_cell_search_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of GSM Cells Found ++ guint16 num_geran_cells = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_geran_cells_found, 2, ENC_BIG_ENDIAN); ++ dissect_array_value(ptvc, pinfo, "GERAN Cells Found", ett_nfapi_geran_cells_found_list, num_geran_cells, dissect_geran_cell_found_value); ++} ++static void dissect_pnf_cell_search_state_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint len = tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_search_state, len, ENC_NA); ++} ++static void dissect_pnf_cell_broadcast_state_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint len = tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_pnf_broadcast_state, len, ENC_NA); ++} ++static void dissect_lte_broadcast_detect_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // EARFCN ++ ptvcursor_add(ptvc, hf_nfapi_earfcn, 2, ENC_BIG_ENDIAN); ++ ++ // PCI ++ ptvcursor_add(ptvc, hf_nfapi_pci, 2, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_broadcast_detect_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UARFCN ++ ptvcursor_add(ptvc, hf_nfapi_uarfcn, 2, ENC_BIG_ENDIAN); ++ ++ // PSC ++ ptvcursor_add(ptvc, hf_nfapi_psc, 2, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_broadcast_detect_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // Number of Tx Antenna ++ guint8 number_of_tx_antenna_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_number_of_tx_antenna, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_tx_antenna_value == 1 || number_of_tx_antenna_value == 2 || number_of_tx_antenna_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of tx antenna value [1, 2, 4]"); ++ } ++ ++ ++ // MIB Length ++ guint16 mib_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_mib_length, 2, ENC_BIG_ENDIAN); ++ ++ // MIB[MIB Length] ++ ptvcursor_add(ptvc, hf_nfapi_mib, mib_len, ENC_NA); ++ ++ // SFN Offset ++ ptvcursor_add(ptvc, hf_nfapi_sfn_offset, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_broadcast_detect_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // MIB Length ++ guint16 mib_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_mib_length, 2, ENC_BIG_ENDIAN); ++ ++ // MIB[MIB Length] ++ ptvcursor_add(ptvc, hf_nfapi_mib, mib_len, ENC_NA); ++ ++ // SFN Offset ++ ptvcursor_add(ptvc, hf_nfapi_sfn_offset, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_system_information_schedule_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // EARFCN ++ ptvcursor_add(ptvc, hf_nfapi_earfcn, 2, ENC_BIG_ENDIAN); ++ ++ // PCI ++ ptvcursor_add(ptvc, hf_nfapi_pci, 2, ENC_BIG_ENDIAN); ++ ++ // Bandwidth ++ guint16 bandwidth_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_bandwidth, 2, ENC_BIG_ENDIAN); ++ if (!(bandwidth_value == 6 || bandwidth_value == 15 || bandwidth_value == 25 || ++ bandwidth_value == 50 || bandwidth_value == 75 || bandwidth_value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++ ++ // PHICH Configuration ++ // todo : phich bit decode ++ ptvcursor_add(ptvc, hf_nfapi_phich_configuration, 1, ENC_BIG_ENDIAN); ++ ++ // Number of Tx Antenna ++ guint8 number_of_tx_antenna_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_tx_antenna, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_tx_antenna_value == 1 || number_of_tx_antenna_value == 2 || number_of_tx_antenna_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of tx antenna value [1, 2, 4]"); ++ } ++ ++ // retryCount ++ ptvcursor_add(ptvc, hf_nfapi_retry_count, 1, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_system_information_schedule_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // this needs to be SIB 1 ++ guint len = tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_sib1, len, ENC_NA); ++} ++static void dissect_si_periodicity_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ proto_item* item; ++ ++ // SI Periodicity ++ guint8 si_periodicity_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_si_periodicity, 1, ENC_BIG_ENDIAN); ++ if (si_periodicity_value > 7) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid si periodicity value [0..7]"); ++ } ++ ++ // SI Index ++ guint8 si_index_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_si_index, 1, ENC_BIG_ENDIAN); ++ if (si_index_value > 32) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid si index value [0..32]"); ++ } ++} ++ ++static void dissect_lte_system_information_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // EARFCN ++ ptvcursor_add(ptvc, hf_nfapi_earfcn, 2, ENC_BIG_ENDIAN); ++ ++ // PCI ++ ptvcursor_add(ptvc, hf_nfapi_pci, 2, ENC_BIG_ENDIAN); ++ ++ // Downlink channel bandwidth ++ guint16 bandwidth_value = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_downlink_channel_bandwidth, 2, ENC_BIG_ENDIAN); ++ if (!(bandwidth_value == 6 || bandwidth_value == 15 || bandwidth_value == 25 || ++ bandwidth_value == 50 || bandwidth_value == 75 || bandwidth_value == 100)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid bandwidth value [6, 15, 25, 50, 75, 100]"); ++ } ++ ++ // PHICH Configuration ++ ptvcursor_add(ptvc, hf_nfapi_phich_configuration, 1, ENC_BIG_ENDIAN); ++ ++ // Number of Tx Antenna ++ guint8 number_of_tx_antenna_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_number_of_tx_antenna, 1, ENC_BIG_ENDIAN); ++ if (!(number_of_tx_antenna_value == 1 || number_of_tx_antenna_value == 2 || number_of_tx_antenna_value == 4)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid number of tx antenna value [1, 2, 4]"); ++ } ++ ++ // Number of SI Periodicity ++ guint8 si_priodicity = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_of_si_periodicity, 1, ENC_BIG_ENDIAN); ++ ++ dissect_array_value(ptvc, pinfo, "Number SI Periodicity", ett_nfapi_si_periodicity_list, si_priodicity, dissect_si_periodicity_value); ++ ++ // SI Window Length ++ guint8 si_window_length_value = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ item = ptvcursor_add(ptvc, hf_nfapi_si_window_length, 1, ENC_BIG_ENDIAN); ++ if (!(si_window_length_value == 1 || si_window_length_value == 2 || si_window_length_value == 5 || si_window_length_value == 10 || ++ si_window_length_value == 15 || si_window_length_value == 20 || si_window_length_value == 40)) ++ { ++ expert_add_info_format(pinfo, item, &ei_invalid_range, "Invalid si window length value [1, 2, 5, 10, 15, 20, 40]"); ++ } ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_utran_system_information_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // UARFCN ++ ptvcursor_add(ptvc, hf_nfapi_uarfcn, 2, ENC_BIG_ENDIAN); ++ ++ // PSC ++ ptvcursor_add(ptvc, hf_nfapi_psc, 2, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_geran_system_information_request_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // ARFCN ++ ptvcursor_add(ptvc, hf_nfapi_arfcn, 2, ENC_BIG_ENDIAN); ++ ++ // BSIC ++ ptvcursor_add(ptvc, hf_nfapi_bsic, 1, ENC_BIG_ENDIAN); ++ ++ // Timeout ++ ptvcursor_add(ptvc, hf_nfapi_timeout, 4, ENC_BIG_ENDIAN); ++} ++static void dissect_lte_system_information_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // SIB Type ++ ptvcursor_add(ptvc, hf_nfapi_sib_type, 1, ENC_BIG_ENDIAN); ++ ++ // SIB Length ++ guint16 sib_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_sib_len, 2, ENC_BIG_ENDIAN); ++ ++ // SIB[SIB Length] ++ ptvcursor_add(ptvc, hf_nfapi_sib, sib_len, ENC_NA); ++} ++static void dissect_utran_system_information_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // SIB Length ++ guint16 sib_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_sib_len, 2, ENC_BIG_ENDIAN); ++ ++ // SIB[SIB Length] ++ ptvcursor_add(ptvc, hf_nfapi_sib, sib_len, ENC_NA); ++} ++static void dissect_geran_system_information_indication_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ // SI Length ++ guint16 si_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_si_len, 2, ENC_BIG_ENDIAN); ++ ++ // SI[SI Length] ++ ptvcursor_add(ptvc, hf_nfapi_si, si_len, ENC_NA); ++} ++ ++static void dissect_rx_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_); ++ ++// Important the tags must be in numerical order so that they can be indexed correctly ++const tlv_t nfapi_tags[] = ++{ ++ { 0x1000, "PNF Param General", dissect_pnf_param_general_value }, ++ { 0x1001, "PNF PHY", dissect_pnf_phy_value }, ++ { 0x1002, "PNF RF", dissect_pnf_rf_value }, ++ { 0x1003, "PNF PHY RF Config", dissect_pnf_phy_rf_config_value }, ++ { 0x1004, "DL RS Tx power", dissect_dl_rs_tx_power_value }, ++ { 0x1005, "Received interference power", dissect_received_interference_power_value }, ++ { 0x1006, "Thermal noise power", dissect_thermal_noise_power_value }, ++ { 0x1007, "DL RS TX Power measurement", dissect_dl_rs_tx_power_measurement_value }, ++ { 0x1008, "Received Interference power measurement", dissect_received_interference_power_measurement_value }, ++ { 0x1009, "Thermal noise power measurement", dissect_thermal_noise_power_measurement_value }, ++ { 0x100A, "PNF PHY Rel 10", dissect_pnf_phy_rel10_value }, ++ { 0x100B, "PNF PHY Rel 11", dissect_pnf_phy_rel11_value }, ++ { 0x100C, "PNF PHY Rel 12", dissect_pnf_phy_rel12_value }, ++ { 0x100D, "PNF PHY Rel 13", dissect_pnf_phy_rel13_value }, ++}; ++ ++const tlv_t configuration_tags[] = ++{ ++ { 0x0000, NULL, NULL }, ++ { 0x0001, "Subframe config - Duplex Mode", dissect_duplex_mode_value }, ++ { 0x0002, "Subframe config - PCFICH power offset TLV", dissect_pcfich_power_offset_value }, ++ { 0x0003, "Subframe config - P-B", dissect_pb_value }, ++ { 0x0004, "Subframe config - DL cyclic prefix type", dissect_dl_cyclic_prefix_value }, ++ { 0x0005, "Subframe config - UL cyclic prefix type", dissect_ul_cyclic_prefix_value }, ++ { 0x0006, NULL, NULL }, ++ { 0x0007, NULL, NULL }, ++ { 0x0008, NULL, NULL }, ++ { 0x0009, NULL, NULL }, ++ { 0x000A, "RF config - Downlink channel bandwidth", dissect_dl_channel_bandwidth_value }, ++ { 0x000B, "RF config - Uplink channel bandwidth", dissect_ul_channel_bandwidth_value }, ++ { 0x000C, "RF config - Reference signal power", dissect_reference_signal_power_value }, ++ { 0x000D, "RF config - Tx antenna ports", dissect_tx_antenna_ports_value }, ++ { 0x000E, "RF config - Rx Antenna ports", dissect_rx_antenna_ports_value }, ++ { 0x000F, NULL, NULL }, ++ { 0x0010, NULL, NULL }, ++ { 0x0011, NULL, NULL }, ++ { 0x0012, NULL, NULL }, ++ { 0x0013, NULL, NULL }, ++ { 0x0014, "PHICH config - PHICH resource", dissect_phich_resource_value }, ++ { 0x0015, "PHICH config - PHICH duration", dissect_phich_duration_value }, ++ { 0x0016, "PHICH config - PHICH power offset", dissect_phich_power_offset_value }, ++ { 0x0017, NULL, NULL }, ++ { 0x0018, NULL, NULL }, ++ { 0x0019, NULL, NULL }, ++ { 0x001A, NULL, NULL }, ++ { 0x001B, NULL, NULL }, ++ { 0x001C, NULL, NULL }, ++ { 0x001D, NULL, NULL }, ++ { 0x001E, "SCH config - Primary synchronization signal EPRE/EPRERS", dissect_psch_synch_signal_epre_eprers_value }, ++ { 0x001F, "SCH config - Secondary synchronization signal EPRE/EPRERS", dissect_ssch_synch_signal_epre_eprers_value }, ++ { 0x0020, "SCH config - Physical Cell Id", dissect_physical_cell_id_value }, ++ { 0x0021, NULL, NULL }, ++ { 0x0022, NULL, NULL }, ++ { 0x0023, NULL, NULL }, ++ { 0x0024, NULL, NULL }, ++ { 0x0025, NULL, NULL }, ++ { 0x0026, NULL, NULL }, ++ { 0x0027, NULL, NULL }, ++ { 0x0028, "PRACH config - Configuration index", dissect_prach_configuration_index_value }, ++ { 0x0029, "PRACH config - Root sequence index", dissect_prach_root_sequence_index_value }, ++ { 0x002A, "PRACH config - Zero correlation zone configuration", dissect_prach_zero_correlation_zone_configuration_value }, ++ { 0x002B, "PRACH config - High speed flag", dissect_prach_high_speed_flag_value }, ++ { 0x002C, "PRACH config - Frequency offset", dissect_prach_frequency_offset_value }, ++ { 0x002D, NULL, NULL }, ++ { 0x002E, NULL, NULL }, ++ { 0x002F, NULL, NULL }, ++ { 0x0030, NULL, NULL }, ++ { 0x0031, NULL, NULL }, ++ { 0x0032, "PUSCH config - Hopping mode", dissect_pusch_hopping_mode_value }, ++ { 0x0033, "PUSCH config - Hopping offset", dissect_pusch_hopping_offset_value }, ++ { 0x0034, "PUSCH config - Number of sub-bands", dissect_pusch_number_of_subbands_value }, ++ { 0x0035, NULL, NULL }, ++ { 0x0036, NULL, NULL }, ++ { 0x0037, NULL, NULL }, ++ { 0x0038, NULL, NULL }, ++ { 0x0039, NULL, NULL }, ++ { 0x003A, NULL, NULL }, ++ { 0x003B, NULL, NULL }, ++ { 0x003C, "PUCCH config - Delta PUCCH Shift", dissect_pucch_delta_pucch_shift_value }, ++ { 0x003D, "PUCCH config - N_CQI RB", dissect_pucch_n_cqi_rb_value }, ++ { 0x003E, "PUCCH config - N_AN CS", dissect_pucch_n_an_cs_value }, ++ { 0x003F, "PUCCH config - N1Pucch-AN", dissect_pucch_n1_pucch_an_value }, ++ { 0x0040, NULL, NULL }, ++ { 0x0041, NULL, NULL }, ++ { 0x0042, NULL, NULL }, ++ { 0x0043, NULL, NULL }, ++ { 0x0044, NULL, NULL }, ++ { 0x0045, NULL, NULL }, ++ { 0x0046, "SRS config - Bandwidth configuration", dissect_srs_bandwidth_configuration_value }, ++ { 0x0047, "SRS config - MaxUpPTS", dissect_srs_max_uppts_value }, ++ { 0x0048, "SRS config - SRS subframe configuration", dissect_srs_subframe_configuration_value }, ++ { 0x0049, "SRS config - SRS AckNack SRS simultaneous transmission", dissect_srs_acknack_srs_sim_tx_value }, ++ { 0x004A, NULL, NULL }, ++ { 0x004B, NULL, NULL }, ++ { 0x004C, NULL, NULL }, ++ { 0x004D, NULL, NULL }, ++ { 0x004E, NULL, NULL }, ++ { 0x004F, NULL, NULL }, ++ { 0x0050, "Uplink reference signal config - Uplink RS hopping", dissect_uplink_rs_hopping_value }, ++ { 0x0051, "Uplink reference signal config - Group assignment (delta sequence-shift pattern)", dissect_group_assignment_value }, ++ { 0x0052, "Uplink reference signal config - Cyclic Shift 1 for DMRS", dissect_cyclic_shift_1_for_drms_value }, ++ { 0x0053, NULL, NULL }, ++ { 0x0054, NULL, NULL }, ++ { 0x0055, NULL, NULL }, ++ { 0x0056, NULL, NULL }, ++ { 0x0057, NULL, NULL }, ++ { 0x0058, NULL, NULL }, ++ { 0x0059, NULL, NULL }, ++ { 0x005A, "TDD frame structure config - Subframe assignment", dissect_tdd_subframe_assignement_value }, ++ { 0x005B, "TDD frame structure config - Special sub-frame patterns", dissect_tdd_subframe_patterns_value }, ++ { 0x005C, NULL, NULL }, ++ { 0x005D, NULL, NULL }, ++ { 0x005E, NULL, NULL }, ++ { 0x005F, NULL, NULL }, ++ { 0x0060, NULL, NULL }, ++ { 0x0061, NULL, NULL }, ++ { 0x0062, NULL, NULL }, ++ { 0x0063, NULL, NULL }, ++ { 0x0064, "LAA config - ED Threshold for LBT for PDSCH", dissect_laa_ed_threashold_for_lbt_for_pdsch_value }, ++ { 0x0065, "LAA config - ED Threshold for LBT for DRS", dissect_laa_ed_threashold_for_lbt_for_drs_value }, ++ { 0x0066, "LAA config - PD Threshold", dissect_laa_pd_threshold_value }, ++ { 0x0067, "LAA config - Multi carrier type", dissect_laa_multi_carrier_type_value }, ++ { 0x0068, "LAA config - Multi carrier TX", dissect_laa_multi_carrier_tx_value }, ++ { 0x0069, "LAA config - Multi carrier freeze", dissect_laa_multi_carrier_freeze_value }, ++ { 0x006A, "LAA config - Tx antenna ports for DRS", dissect_laa_tx_antenna_port_for_drs_value }, ++ { 0x006B, "LAA config - Transmission power for DRS", dissect_laa_transmission_power_for_drs_value }, ++ { 0x006C, NULL, NULL }, ++ { 0x006D, NULL, NULL }, ++ { 0x006E, NULL, NULL }, ++ { 0x006F, NULL, NULL }, ++ { 0x0070, NULL, NULL }, ++ { 0x0071, NULL, NULL }, ++ { 0x0072, NULL, NULL }, ++ { 0x0073, NULL, NULL }, ++ { 0x0074, NULL, NULL }, ++ { 0x0075, NULL, NULL }, ++ { 0x0076, NULL, NULL }, ++ { 0x0077, NULL, NULL }, ++ { 0x0078, "eMTC config - PBCH Repetitions enable R13", dissect_emtc_pbch_repeitions_enabled_r13_value }, ++ { 0x0079, "eMTC config - PRACH CAT-M Root sequence index", dissect_emtc_prach_cat_m_root_sequence_index_value }, ++ { 0x007A, "eMTC config - PRACH CAT-M Zero correlation zone configuration", dissect_emtc_prach_cat_m_zero_correlation_zone_configuration_value }, ++ { 0x007B, "eMTC config - PRACH CAT-M High speed flag", dissect_emtc_prach_cat_m_high_speed_flag_value }, ++ { 0x007C, "eMTC config - PRACH CE level #0 Enable", dissect_emtc_prach_ce_level_0_enabled_value }, ++ { 0x007D, "eMTC config - PRACH CE level #0 Configuration index", dissect_emtc_prach_ce_level_0_configuration_offset_value }, ++ { 0x007E, "eMTC config - PRACH CE level #0 Frequency offset", dissect_emtc_prach_ce_level_0_frequency_offset_value }, ++ { 0x007F, "eMTC config - PRACH CE level #0 Number of repetitions per attempt", dissect_emtc_preach_ce_level_0_num_of_repeitions_per_attempt_value }, ++ { 0x0080, "eMTC config - CE level #0 Starting subframe periodicity", dissect_emtc_ce_level_0_starting_subframe_periodicity_value }, ++ { 0x0081, "eMTC config - PRACH CE level #0 Hopping Enable", dissect_emtc_preach_ce_level_0_hopping_enabled_value }, ++ { 0x0082, "eMTC config - PRACH CE level #0 Hopping Offset", dissect_emtc_preach_ce_level_0_hopping_offset_value }, ++ { 0x0083, "eMTC config - PRACH CE level #1 Enable", dissect_emtc_prach_ce_level_1_enabled_value }, ++ { 0x0084, "eMTC config - PRACH CE level #1 Configuration index", dissect_emtc_prach_ce_level_1_configuration_offset_value }, ++ { 0x0085, "eMTC config - PRACH CE level #1 Frequency offset", dissect_emtc_prach_ce_level_1_frequency_offset_value }, ++ { 0x0086, "eMTC config - PRACH CE level #1 Number of repetitions per attempt", dissect_emtc_preach_ce_level_1_num_of_repeitions_per_attempt_value }, ++ { 0x0087, "eMTC config - CE level #1 Starting subframe periodicity", dissect_emtc_ce_level_1_starting_subframe_periodicity_value }, ++ { 0x0088, "eMTC config - PRACH CE level #1 Hopping Enable", dissect_emtc_preach_ce_level_1_hopping_enabled_value }, ++ { 0x0089, "eMTC config - PRACH CE level #1 Hopping Offset", dissect_emtc_preach_ce_level_1_hopping_offset_value }, ++ { 0x008A, "eMTC config - PRACH CE level #2 Enable", dissect_emtc_prach_ce_level_2_enabled_value }, ++ { 0x008B, "eMTC config - PRACH CE level #2 Configuration index", dissect_emtc_prach_ce_level_2_configuration_offset_value }, ++ { 0x008C, "eMTC config - PRACH CE level #2 Frequency offset", dissect_emtc_prach_ce_level_2_frequency_offset_value }, ++ { 0x008D, "eMTC config - PRACH CE level #2 Number of repetitions per attempt", dissect_emtc_preach_ce_level_2_num_of_repeitions_per_attempt_value }, ++ { 0x008E, "eMTC config - CE level #2 Starting subframe periodicity", dissect_emtc_ce_level_2_starting_subframe_periodicity_value }, ++ { 0x008F, "eMTC config - PRACH CE level #2 Hopping Enable", dissect_emtc_preach_ce_level_2_hopping_enabled_value }, ++ { 0x0090, "eMTC config - PRACH CE level #2 Hopping Offset", dissect_emtc_preach_ce_level_2_hopping_offset_value }, ++ { 0x0091, "eMTC config - PRACH CE level #3 Enable", dissect_emtc_prach_ce_level_3_enabled_value }, ++ { 0x0092, "eMTC config - PRACH CE level #3 Configuration index", dissect_emtc_prach_ce_level_3_configuration_offset_value }, ++ { 0x0093, "eMTC config - PRACH CE level #3 Frequency offset", dissect_emtc_prach_ce_level_3_frequency_offset_value }, ++ { 0x0094, "eMTC config - PRACH CE level #3 Number of repetitions per attempt", dissect_emtc_preach_ce_level_3_num_of_repeitions_per_attempt_value }, ++ { 0x0095, "eMTC config - CE level #3 Starting subframe periodicity", dissect_emtc_ce_level_3_starting_subframe_periodicity_value }, ++ { 0x0096, "eMTC config - PRACH CE level #3 Hopping Enable", dissect_emtc_preach_ce_level_3_hopping_enabled_value }, ++ { 0x0097, "eMTC config - PRACH CE level #3 Hopping Offset", dissect_emtc_preach_ce_level_3_hopping_offset_value }, ++ { 0x0098, "eMTC config - PUCCH Interval - ULHoppingConfigCommonModeA", dissect_emtc_pucch_interval_ul_hopping_config_common_mode_a_value }, ++ { 0x0099, "eMTC config - PUCCH Interval - ULHoppingConfigCommonModeB", dissect_emtc_pucch_interval_ul_hopping_config_common_mode_b_value }, ++ { 0x009A, NULL, NULL }, ++ { 0x009B, NULL, NULL }, ++ { 0x009C, NULL, NULL }, ++ { 0x009D, NULL, NULL }, ++ { 0x009E, NULL, NULL }, ++ { 0x009F, NULL, NULL }, ++ { 0x00A0, NULL, NULL }, ++ { 0x00A1, NULL, NULL }, ++ { 0x00A2, NULL, NULL }, ++ { 0x00A3, NULL, NULL }, ++ { 0x00A4, NULL, NULL }, ++ { 0x00A5, NULL, NULL }, ++ { 0x00A6, NULL, NULL }, ++ { 0x00A7, NULL, NULL }, ++ { 0x00A8, NULL, NULL }, ++ { 0x00A9, NULL, NULL }, ++ { 0x00AA, NULL, NULL }, ++ { 0x00AB, NULL, NULL }, ++ { 0x00AC, NULL, NULL }, ++ { 0x00AD, NULL, NULL }, ++ { 0x00AE, NULL, NULL }, ++ { 0x00AF, NULL, NULL }, ++ { 0x00B0, NULL, NULL }, ++ { 0x00B1, NULL, NULL }, ++ { 0x00B2, NULL, NULL }, ++ { 0x00B3, NULL, NULL }, ++ { 0x00B4, NULL, NULL }, ++ { 0x00B5, NULL, NULL }, ++ { 0x00B6, NULL, NULL }, ++ { 0x00B7, NULL, NULL }, ++ { 0x00B8, NULL, NULL }, ++ { 0x00B9, NULL, NULL }, ++ { 0x00BA, NULL, NULL }, ++ { 0x00BB, NULL, NULL }, ++ { 0x00BC, NULL, NULL }, ++ { 0x00BD, NULL, NULL }, ++ { 0x00BE, NULL, NULL }, ++ { 0x00BF, NULL, NULL }, ++ { 0x00C0, NULL, NULL }, ++ { 0x00C1, NULL, NULL }, ++ { 0x00C2, NULL, NULL }, ++ { 0x00C3, NULL, NULL }, ++ { 0x00C4, NULL, NULL }, ++ { 0x00C5, NULL, NULL }, ++ { 0x00C6, NULL, NULL }, ++ { 0x00C7, NULL, NULL }, ++ { 0x00C8, "Layer 2/3 - Downlink Bandwidth Support", dissect_dl_bandwidth_support_value }, ++ { 0x00C9, "Layer 2/3 - Uplink Bandwidth Support", dissect_ul_bandwidth_support_value }, ++ { 0x00CA, "Layer 2/3 - Downlink modulation support", dissect_dl_modulation_value }, ++ { 0x00CB, "Layer 2/3 - Uplink modulation support", dissect_ul_modulation_value }, ++ { 0x00CC, "Layer 2/3 - PHY antenna capability", dissect_phy_antenna_capability_value }, ++ { 0x00CD, "Layer 2/3 - Release capability", dissect_release_capability_value }, ++ { 0x00CE, "Layer 2/3 - MBSFN capability", dissect_mbsfn_value }, ++ { 0x00CF, NULL, NULL }, ++ { 0x00D0, NULL, NULL }, ++ { 0x00D1, "LAA Capability - LAA support", dissect_laa_support_value }, ++ { 0x00D2, "LAA Capability - PD sensing LBT support", dissect_laa_pd_sensing_lbt_support_value }, ++ { 0x00D3, "LAA Capability - Multi carrier LBT support", dissect_laa_multi_carrier_lbt_support_value }, ++ { 0x00D4, "LAA Capability - Partial SF support", dissect_laa_partial_sf_support_value }, ++ { 0x00D5, NULL, NULL }, ++ { 0x00D6, NULL, NULL }, ++ { 0x00D7, NULL, NULL }, ++ { 0x00D8, NULL, NULL }, ++ { 0x00D9, NULL, NULL }, ++ { 0x00DA, NULL, NULL }, ++ { 0x00DB, NULL, NULL }, ++ { 0x00DC, NULL, NULL }, ++ { 0x00DD, NULL, NULL }, ++ { 0x00DE, NULL, NULL }, ++ { 0x00DF, NULL, NULL }, ++ { 0x00E0, NULL, NULL }, ++ { 0x00E1, NULL, NULL }, ++ { 0x00E2, NULL, NULL }, ++ { 0x00E3, NULL, NULL }, ++ { 0x00E4, NULL, NULL }, ++ { 0x00E5, NULL, NULL }, ++ { 0x00E6, NULL, NULL }, ++ { 0x00E7, NULL, NULL }, ++ { 0x00E8, NULL, NULL }, ++ { 0x00E9, NULL, NULL }, ++ { 0x00EA, NULL, NULL }, ++ { 0x00EB, NULL, NULL }, ++ { 0x00EC, NULL, NULL }, ++ { 0x00ED, NULL, NULL }, ++ { 0x00EE, NULL, NULL }, ++ { 0x00EF, NULL, NULL }, ++ { 0x00F0, "Layer 2/3 - Data report mode", dissect_data_report_mode_value }, ++ { 0x00F1, "Layer 2/3 - SFN/SF", dissect_sfn_sf_value }, ++ { 0x00F2, NULL, NULL }, ++ { 0x00F3, NULL, NULL }, ++ { 0x00F4, NULL, NULL }, ++ { 0x00F5, NULL, NULL }, ++ { 0x00F6, NULL, NULL }, ++ { 0x00F7, NULL, NULL }, ++ { 0x00F8, NULL, NULL }, ++ { 0x00F9, NULL, NULL }, ++ { 0x00FA, "Layer 1 - PHY state", dissect_phy_state_value }, ++ { 0x00FB, NULL, NULL }, ++ { 0x00FC, NULL, NULL }, ++ { 0x00FD, NULL, NULL }, ++ { 0x00FE, NULL, NULL }, ++ { 0x00FF, NULL, NULL }, ++ { 0x0100, "NFAPI - P7 VNF Address IPv4", dissect_p7_vnf_address_ipv4_value }, ++ { 0x0101, "NFAPI - P7 VNF Address IPv4", dissect_p7_vnf_address_ipv6_value }, ++ { 0x0102, "NFAPI - P7 Port", dissect_p7_vnf_port_value }, ++ { 0x0103, "NFAPI - P7 PNF Address IPv4", dissect_p7_pnf_address_ipv4_value }, ++ { 0x0104, "NFAPI - P7 PNF Address IPv4", dissect_p7_pnf_address_ipv6_value }, ++ { 0x0105, "NFAPI - P7 Port", dissect_p7_pnf_port_value }, ++ { 0x0106, NULL, NULL }, ++ { 0x0107, NULL, NULL }, ++ { 0x0108, NULL, NULL }, ++ { 0x0109, NULL, NULL }, ++ { 0x010A, "NFAPI - Downlink UEs per Subframe", dissect_downlink_ues_per_subframe_value }, ++ { 0x010B, "NFAPI - Uplink UEs per Subframe", dissect_uplink_ues_per_subframe_value }, ++ { 0x010C, NULL, NULL }, ++ { 0x010D, NULL, NULL }, ++ { 0x010E, NULL, NULL }, ++ { 0x010F, NULL, NULL }, ++ { 0x0110, NULL, NULL }, ++ { 0x0111, NULL, NULL }, ++ { 0x0112, NULL, NULL }, ++ { 0x0113, NULL, NULL }, ++ { 0x0114, "NFAPI - nFAPI RF Bands", dissect_rf_bands_value }, ++ { 0x0115, NULL, NULL }, ++ { 0x0116, NULL, NULL }, ++ { 0x0117, NULL, NULL }, ++ { 0x0118, NULL, NULL }, ++ { 0x0119, NULL, NULL }, ++ { 0x011A, NULL, NULL }, ++ { 0x011B, NULL, NULL }, ++ { 0x011C, NULL, NULL }, ++ { 0x011D, NULL, NULL }, ++ { 0x011E, "NFAPI - Timing window", dissect_timing_window_value }, ++ { 0x011F, "NFAPI - Timing info mode", dissect_timing_info_mode_value }, ++ { 0x0120, "NFAPI - Timing info period", dissect_timing_info_period_value }, ++ { 0x0121, NULL, NULL }, ++ { 0x0122, NULL, NULL }, ++ { 0x0123, NULL, NULL }, ++ { 0x0124, NULL, NULL }, ++ { 0x0125, NULL, NULL }, ++ { 0x0126, NULL, NULL }, ++ { 0x0127, NULL, NULL }, ++ { 0x0128, "NFAPI - Maximum Transmit Power", dissect_maximum_transmit_power_value }, ++ { 0x0129, "NFAPI - EARFCN", dissect_earfcn_value }, ++ { 0x012A, NULL, NULL }, ++ { 0x012B, NULL, NULL }, ++ { 0x012C, NULL, NULL }, ++ { 0x012D, NULL, NULL }, ++ { 0x012E, NULL, NULL }, ++ { 0x012F, NULL, NULL }, ++ { 0x0130, "NFAPI - NMM GSM Frequency Bands", dissect_nmm_gsm_frequency_bands_value }, ++ { 0x0131, "NFAPI - NMM UMTS Frequency Bands", dissect_nmm_umts_frequency_bands_value }, ++ { 0x0132, "NFAPI - NMM LTE Frequency Bands", dissect_nmm_lte_frequency_bands_value }, ++ { 0x0133, "NFAPI - NMM Uplink RSSI supported", dissect_nmm_uplink_rssi_supported_value }, ++}; ++ ++const tlv_t p7_tags[] = ++{ ++ { 0x2000, "DL Config Request Body", dissect_dl_config_request_body_value }, ++ { 0x2001, "DL DCI PDU Release 8", dissect_dl_config_request_dl_dci_pdu_rel8_value }, ++ { 0x2002, "DL DCI PDU Release 9", dissect_dl_config_request_dl_dci_pdu_rel9_value }, ++ { 0x2003, "DL DCI PDU Release 10", dissect_dl_config_request_dl_dci_pdu_rel10_value }, ++ { 0x2004, "BCH PDU Release 8", dissect_dl_config_request_bch_pdu_rel8_value }, ++ { 0x2005, "MCH PDU Release 8", dissect_dl_config_request_mch_pdu_rel8_value }, ++ { 0x2006, "DLSCH PDU Release 8", dissect_dl_config_request_dlsch_pdu_rel8_value }, ++ { 0x2007, "DLSCH PDU Release 9", dissect_dl_config_request_dlsch_pdu_rel9_value }, ++ { 0x2008, "DLSCH PDU Release 10", dissect_dl_config_request_dlsch_pdu_rel10_value }, ++ { 0x2009, "PCH PDU Release 8", dissect_dl_config_request_pch_pdu_rel8_value }, ++ { 0x200A, "PRS PDU Release 9", dissect_dl_config_request_prs_pdu_rel9_value }, ++ { 0x200B, "CSI-RS PDU Release 10", dissect_dl_config_request_csi_rs_pdu_rel10_value }, ++ { 0x200C, "UL Config Request Body", dissect_ul_config_request_body_value }, ++ { 0x200D, "ULSCH PDU Release 8", dissect_ul_config_ulsch_pdu_rel8_value }, ++ { 0x200E, "ULSCH PDU Release 10", dissect_ul_config_ulsch_pdu_rel10_value }, ++ { 0x200F, "Initial Transmission Parameters Release 8", dissect_ul_config_init_tx_params_rel8_value }, ++ { 0x2010, "CQI RI Information Release 8", dissect_ul_config_cqi_ri_info_rel8_value }, ++ { 0x2011, "CQI RI Information Release 9 or later", dissect_ul_config_cqi_ri_info_rel9_later_value }, ++ { 0x2012, "HARQ Information (ULSCH) Release 10", dissect_ul_config_harq_info_ulsch_rel10_value }, ++ { 0x2013, "UE Information Release 8", dissect_ul_config_ue_info_rel8_value }, ++ { 0x2014, "CQI Information Release 8", dissect_ul_config_cqi_info_rel8_value }, ++ { 0x2015, "CQI Information Release 10", dissect_ul_config_cqi_info_rel10_value }, ++ { 0x2016, "SR Information Release 8", dissect_ul_config_sr_info_rel8_value }, ++ { 0x2017, "SR Information Release 10", dissect_ul_config_sr_info_rel10_value }, ++ { 0x2018, "HARQ Information (UCI) Release 10 TDD", dissect_ul_config_harq_info_uci_rel10_tdd_value }, ++ { 0x2019, "HARQ Information (UCI) Release 8 FDD", dissect_ul_config_harq_info_uci_rel8_fdd_value }, ++ { 0x201A, "HARQ Information (UCI) Release 9 or later FDD", dissect_ul_config_harq_info_uci_rel9_later_fdd_value }, ++ { 0x201B, "SRS Information Release 8", dissect_ul_config_srs_info_rel8_value }, ++ { 0x201C, "SRS Information Release 10", dissect_ul_config_srs_info_rel10_value }, ++ { 0x201D, "HI DCI0 Request Body", dissect_hi_dci0_request_body_value }, ++ { 0x201E, "HI PDU Release 8", dissect_hi_dci0_hi_rel8_value }, ++ { 0x201F, "HI PDU Release 10", dissect_hi_dci0_hi_rel10_value }, ++ { 0x2020, "DCI UL PDU Release 8", dissect_hi_dci0_dci_ul_rel8_value }, ++ { 0x2021, "DCI UL PDU Release 10", dissect_hi_dci0_dci_ul_rel10_value }, ++ { 0x2022, "Tx Request Body", dissect_tx_request_body_value }, ++ { 0x2023, "RX Indication Body", dissect_rx_indication_body_value }, ++ { 0x2024, "RX PDU Release 8", dissect_rx_indication_rel8_value }, ++ { 0x2025, "RX PDU Release 9", dissect_rx_indication_rel9_value }, ++ { 0x2026, "HARQ Indication Body", dissect_harq_indication_body_value }, ++ { 0x2027, "HARQ PDU Release 8 TDD", dissect_harq_indication_rel8_tdd_value }, ++ { 0x2028, "HARQ PDU Release 9 or later TDD", dissect_harq_indication_rel9_later_tdd_value }, ++ { 0x2029, "HARQ PDU Release 8 FDD", dissect_harq_indication_rel8_fdd_value }, ++ { 0x202A, "HARQ PDU Release 9 or later FDD", dissect_harq_indication_rel9_later_fdd_value }, ++ { 0x202B, "CRC Indication Body", dissect_crc_indication_body_value }, ++ { 0x202C, "CRC PDU Release 8", dissect_crc_indication_rel8_value }, ++ { 0x202D, "RX SR Indication Body", dissect_rx_sr_indication_body_value }, ++ { 0x202E, "RX CQI Indication Body", dissect_rx_cqi_indication_body_value }, ++ { 0x202F, "CQI PDU Release 8", dissect_rx_cqi_indication_rel8_value }, ++ { 0x2030, "CQI PDU Release 9", dissect_rx_cqi_indication_rel9_value }, ++ { 0x2031, "RACH Indication Body", dissect_rach_indication_body_value }, ++ { 0x2032, "Preamable PDU Release 8", dissect_rach_indication_rel8_value }, ++ { 0x2033, "Preamable PDU Release 9", dissect_rach_indication_rel9_value }, ++ { 0x2034, "SRS Indication Body", dissect_srs_indication_body_value }, ++ { 0x2035, "SRS PDU Release 8", dissect_srs_indication_rel8_value }, ++ { 0x2036, "SRS PDU Release 9", dissect_srs_indication_rel9_value }, ++ { 0x2037, "SRS PDU Release 10 TDD", dissect_srs_indication_rel10_tdd_value }, ++ { 0x2038, "RX UE Information", dissect_rx_ue_info_value }, ++ { 0x2039, "DL DCI PDU Release 11", dissect_dl_config_request_dl_dci_pdu_rel11_value }, ++ { 0x203A, "DL DCI PDU Release 12", dissect_dl_config_request_dl_dci_pdu_rel12_value }, ++ { 0x203B, "DL DCI PDU Release 13", dissect_dl_config_request_dl_dci_pdu_rel13_value }, ++ { 0x203C, "DLSCH PDU Release 11", dissect_dl_config_request_dlsch_pdu_rel11_value }, ++ { 0x203D, "DLSCH PDU Release 12", dissect_dl_config_request_dlsch_pdu_rel12_value }, ++ { 0x203E, "DLSCH PDU Release 13", dissect_dl_config_request_dlsch_pdu_rel13_value }, ++ { 0x203F, "PCH PDU Release 13", dissect_dl_config_request_pch_pdu_rel13_value }, ++ { 0x2040, "CSI-RS PDU Release 13", dissect_dl_config_request_csi_rs_pdu_rel13_value }, ++ { 0x2041, "EDPCCH PDU Release 11 Parameters", dissect_dl_config_request_edpcch_params_rel11_value }, ++ { 0x2042, "EDPCCH PDU Release 13 Parameters", dissect_dl_config_request_edpcch_params_rel13_value }, ++ { 0x2043, "ULSCH PDU Release 11", dissect_ul_config_ulsch_pdu_rel11_value }, ++ { 0x2044, "ULSCH PDU Release 13", dissect_ul_config_ulsch_pdu_rel13_value }, ++ { 0x2045, "CQI RI Information Release 13", dissect_ul_config_cqi_ri_info_rel13_value }, ++ { 0x2046, "HARQ Information (ULSCH) Release 13", dissect_ul_config_harq_info_ulsch_rel13_value }, ++ { 0x2047, "UE Information Release 11", dissect_ul_config_ue_info_rel11_value }, ++ { 0x2048, "UE Information Release 13", dissect_ul_config_ue_info_rel13_value }, ++ { 0x2049, "CQI Information Release 13", dissect_ul_config_cqi_info_rel13_value }, ++ { 0x204A, "HARQ Information (UCI) Release 11 FDD/TDD", dissect_ul_config_harq_info_uci_rel11_fdd_tdd_value }, ++ { 0x204B, "HARQ Information (UCI) Release 13 FDD/TDD", dissect_ul_config_harq_info_uci_rel13_fdd_tdd_value }, ++ { 0x204C, "SRS Information Release 13", dissect_ul_config_srs_info_rel13_value }, ++ { 0x204D, "DCI UL PDU Release 12", dissect_hi_dci0_dci_ul_rel12_value }, ++ { 0x204E, "MDPCCH DCI UL PDU Release 13", dissect_hi_dci0_mdpcch_dci_ul_rel13_value }, ++ { 0x204F, "HARQ PDU Release 13 or later TDD", dissect_harq_indication_rel13_later_tdd_value }, ++ { 0x2050, "HARQ PDU Release 13 or later FDD", dissect_harq_indication_rel13_later_fdd_value }, ++ { 0x2051, "Preamable PDU Release 13", dissect_rach_indication_rel13_value }, ++ { 0x2052, "UL CQI Information", dissect_ul_cqi_information_value }, ++ { 0x2053, "SRS PDU Release 11", dissect_srs_indication_rel11_value }, ++ { 0x2054, "TDD Channel Measurement", dissect_tdd_channel_measurement_value }, ++ { 0x2055, "LBT DL Config Request Body", dissect_lbt_dl_config_request_body_value }, ++ { 0x2056, "LBT PDSCH Req PDU Release 13", dissect_lbt_dl_config_request_pdsch_req_rel13_value }, ++ { 0x2057, "LBT DRS req PDU Release 13", dissect_lbt_dl_config_request_drs_req_rel13_value }, ++ { 0x2058, "LBT DL Indication Message Body", dissect_lbt_indication_message_body_value }, ++ { 0x2059, "LBT PDSCH Resp PDU Release 13", dissect_lbt_dl_config_request_pdsch_resp_rel13_value }, ++ { 0x205A, "LBT DRS Resp PDU Release 13", dissect_lbt_dl_config_request_drs_resp_rel13_value }, ++ { 0x205B, "MPDCCH PDU Release 13", dissect_dl_config_request_mpdpcch_pdu_rel13_value }, ++}; ++ ++const tlv_t p4_tags[] = ++{ ++ { 0x3000, "LTE RSSI Request", dissect_lte_rssi_request_value }, ++ { 0x3001, "UTRAN RSSI Request", dissect_utran_rssi_request_value }, ++ { 0x3002, "GERAN RSSI Request", dissect_geran_rssi_request_value }, ++ { 0x3003, "RSSI Indication", dissect_rssi_indication_value }, ++ { 0x3004, "LTE CELL SEARCH Request", dissect_lte_cell_search_value }, ++ { 0x3005, "UTRAN CELL SEARCH Request", dissect_utran_cell_search_value }, ++ { 0x3006, "GERAN CELL SEARCH Request", dissect_geran_cell_search_value }, ++ { 0x3007, "LTE CELL SEARCH Indication", dissect_lte_cell_search_indication_value }, ++ { 0x3008, "UTRAN CELL SEARCH Indication", dissect_utran_cell_search_indication_value }, ++ { 0x3009, "GERAN CELL SEARCH Indication", dissect_geran_cell_search_indication_value }, ++ { 0x300A, "PNF CELL SEARCH STATE", dissect_pnf_cell_search_state_value }, ++ { 0x300B, "LTE BROADCAST DETECT Request", dissect_lte_broadcast_detect_request_value }, ++ { 0x300C, "UTRAN BROADCAST DETECT Request", dissect_utran_broadcast_detect_request_value }, ++ { 0x300D, "PNF CELL SEARCH STATE", dissect_pnf_cell_search_state_value }, ++ { 0x300E, "LTE BROADCAST DETECT Indication", dissect_lte_broadcast_detect_indication_value }, ++ { 0x300F, "UTRAN BROADCAST DETECT Indication", dissect_utran_broadcast_detect_indication_value }, ++ { 0x3010, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, ++ { 0x3011, "LTE SYSTEM INFORMATION SCHEDULE Request", dissect_lte_system_information_schedule_request_value }, ++ { 0x3012, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, ++ { 0x3013, "LTE SYSTEM INFORMATION SCHEDULE Indication", dissect_lte_system_information_schedule_indication_value }, ++ { 0x3014, "LTE SYSTEM INFORMATION Request", dissect_lte_system_information_request_value }, ++ { 0x3015, "UTRAN SYSTEM INFORMATION Request", dissect_utran_system_information_request_value }, ++ { 0x3016, "GERAN SYSTEM INFORMATION Request", dissect_geran_system_information_request_value }, ++ { 0x3017, "PNF CELL BROADCAST STATE", dissect_pnf_cell_broadcast_state_value }, ++ { 0x3018, "LTE SYSTEM INFORMATION Indication", dissect_lte_system_information_indication_value }, ++ { 0x3019, "UTRAN SYSTEM INFORMATION Indication", dissect_utran_system_information_indication_value }, ++ { 0x301A, "GERAN SYSTEM INFORMATION Indication", dissect_geran_system_information_indication_value }, ++}; ++ ++ ++static const tlv_t* look_up_tlv(int tag_id) ++{ ++ const tlv_t* tlv = NULL; ++ ++ static const gint num_configuration_tags = sizeof(configuration_tags) / sizeof(tlv_t); ++ static const gint num_nfapi_tags = sizeof(nfapi_tags) / sizeof(tlv_t); ++ static const gint num_p7_tags = sizeof(p7_tags) / sizeof(tlv_t); ++ static const gint num_p4_tags = sizeof(p4_tags) / sizeof(tlv_t); ++ ++ if (tag_id >= 0x0000 && tag_id <= (0x0000 + num_configuration_tags - 1)) // 0x0133) ++ { ++ tlv = &configuration_tags[tag_id]; ++ } ++ else if (tag_id >= 0x1000 && tag_id <= (0x1000 + num_nfapi_tags - 1)) // 0x100D) ++ { ++ tlv = &nfapi_tags[tag_id - 0x1000]; ++ } ++ else if (tag_id >= 0x2000 && tag_id <= (0x2000 + num_p7_tags - 1)) //0x205B) ++ { ++ tlv = &p7_tags[tag_id - 0x2000]; ++ } ++ else if (tag_id >= 0x3000 && tag_id <= (0x3000 + num_p4_tags - 1)) // 0x301A) ++ { ++ tlv = &p4_tags[tag_id - 0x3000]; ++ } ++ return tlv; ++} ++ ++ ++static proto_item* dissect_tl_header(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tl, "TL"); ++ ptvcursor_add(ptvc, hf_nfapi_tl_tag, 2, ENC_BIG_ENDIAN); ++ proto_item* item = ptvcursor_add(ptvc, hf_nfapi_tl_length, 2, ENC_BIG_ENDIAN); ++ ptvcursor_pop_subtree(ptvc); ++ ++ return item; ++} ++ ++static void dissect_tlv_list(ptvcursor_t* ptvc, packet_info* pinfo, gint len) ++{ ++ while (ptvcursor_current_offset(ptvc) < len) ++ { ++ guint16 tlv_id = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ guint16 tlv_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc) + 2); ++ ++ const tlv_t* tlv = look_up_tlv(tlv_id); ++ ++ if (tlv != NULL && tlv->name != NULL && tlv->tag_id == tlv_id) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "%s", tlv->name); ++ proto_item* tlv_length_item = dissect_tl_header(ptvc, pinfo); ++ ++ // There are rare cases where the len of the tlv is 0. ++ if (tlv_len > 0) ++ { ++ ++ if (tlv->decode != NULL) ++ { ++ // Create a sub buff with the correct length, so we can detect reading off the end ++ tvbuff_t* sub_tvbuff = tvb_new_subset_length(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc), tlv_len); ++ ptvcursor_t* sub_ptvc = ptvcursor_new(ptvcursor_tree(ptvc), sub_tvbuff, 0); ++ ++ tlv->decode(sub_ptvc, pinfo); ++ ++ if (ptvcursor_current_offset(sub_ptvc) != tlv_len) ++ { ++ // error in the tlv length ++ expert_add_info_format(pinfo, tlv_length_item, &ei_invalid_tlv_length, "TLV length does not match decoded length"); ++ } ++ ++ ptvcursor_free(sub_ptvc); ++ } ++ ++ ptvcursor_advance(ptvc, tlv_len); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ else ++ { ++ if (tlv_id >= 0xF000 /* && tlv_id <= 0xFFFF*/) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "Unknown Vendor Extension Tag"); ++ } ++ else ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_tlv_tree, "Unknown"); ++ } ++ ++ dissect_tl_header(ptvc, pinfo); ++ ptvcursor_advance(ptvc, tlv_len); ++ ptvcursor_pop_subtree(ptvc); ++ } ++ } ++} ++ ++ ++static void dissect_rx_indication_body_value(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ guint number_of_pdu_addr = ptvcursor_current_offset(ptvc); // *offset; ++ guint16 count = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_number_pdus, 2, ENC_BIG_ENDIAN); ++ ++ guint16* lengths = (guint16*)wmem_alloc0(wmem_packet_scope(), count * 2); ++ memset(lengths, 0, count * 2); ++ ++ guint16 i = 0; ++ ++ if (count > 0) ++ { ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_rx_indication_pdu_list, "RX PDU List"); ++ gint pdu_end = tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)) + ptvcursor_current_offset(ptvc); ++ ++ while (tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)) > 0 && ++ ptvcursor_current_offset(ptvc) < pdu_end ) ++ { ++ guint16 tlv_id = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ //guint16 tlv_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc) + 2); ++ ++ if (tlv_id == 0x2038) ++ { ++ if (i != 0) ++ ptvcursor_pop_subtree(ptvc); ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_rx_indication_pdu_list, "[%d]", i); ++ ++ i++; ++ } ++ ++ char* tlv_name = "Unknown"; ++ const tlv_t* tlv = look_up_tlv(tlv_id); ++ ++ if (tlv != NULL && tlv->name != NULL && tlv->tag_id == tlv_id) ++ { ++ tlv_name = tlv->name; ++ } ++ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_rx_indication_pdu_list, "%s", tlv_name); ++ ++ dissect_tl_header(ptvc, pinfo); ++ ++ ++ if (tlv_id == 0x2038) ++ { ++ dissect_rx_ue_info_value(ptvc, pinfo); ++ } ++ else if (tlv_id == 0x2024) ++ { ++ lengths[i - 1] = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_length, 2, ENC_BIG_ENDIAN); ++ int data_offset = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_data_offset, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_ul_cqi, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_advance, 2, ENC_BIG_ENDIAN); ++ ++ if ((data_offset > 0) && (pdu_end == (tvb_reported_length_remaining(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)) + ptvcursor_current_offset(ptvc)))) ++ { ++ pdu_end = number_of_pdu_addr + data_offset; ++ } ++ ++ } ++ else if (tlv_id == 0x2025) ++ { ++ dissect_rx_indication_rel9_value(ptvc, pinfo); ++ } ++ ++ ptvcursor_pop_subtree(ptvc); ++ ++ } ++ ++ // pop the last pdu index. ++ ptvcursor_pop_subtree(ptvc); ++ ++ ptvcursor_pop_subtree(ptvc); ++ } ++ ++ for (i = 0; i < count; ++i) ++ { ++ ptvcursor_add(ptvc, hf_nfapi_pdu, lengths[i], ENC_NA); ++ } ++} ++ ++ ++// ----------------------------------------------------------------------------| ++ ++static void dissect_p45_header(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_p4_p5_message_header, "P4 P5 Header"); ++ ptvcursor_add(ptvc, hf_nfapi_p4_p5_message_header_phy_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p4_p5_message_header_message_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p4_p5_message_header_message_length, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p4_p5_message_header_spare, 2, ENC_BIG_ENDIAN); ++ ptvcursor_pop_subtree(ptvc); ++ ++} ++ ++static void dissect_p7_header_new(ptvcursor_t* ptvc, guint8* m, guint8* seg, guint8* seq) ++{ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_p7_message_header, "P7 Header"); ++ ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_phy_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_message_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_message_length, 2, ENC_BIG_ENDIAN); ++ ++ guint8 m_seg = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ *m = (m_seg & 0x80) >> 7; ++ *seg = m_seg & 0x7F; ++ ++ proto_tree_add_bits_item(ptvcursor_tree(ptvc), hf_nfapi_p7_message_header_m, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8, 1, ENC_NA); ++ proto_tree_add_bits_item(ptvcursor_tree(ptvc), hf_nfapi_p7_message_header_segment, ptvcursor_tvbuff(ptvc), ((ptvcursor_current_offset(ptvc)) * 8) + 1, 7, ENC_NA); ++ ptvcursor_advance(ptvc, 1); ++ ++ ++ *seq = tvb_get_guint8(ptvcursor_tvbuff(ptvc), ptvcursor_current_offset(ptvc)); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_sequence_number, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_checksum, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_transmit_timestamp, 4, ENC_BIG_ENDIAN); ++ ++ ptvcursor_pop_subtree(ptvc); ++} ++ ++ ++static void dissect_p7_header(ptvcursor_t * ptvc, packet_info* pinfo _U_) ++{ ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_p7_message_header, "P7 Header"); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_phy_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_message_id, 2, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_message_length, 2, ENC_BIG_ENDIAN); ++ ++ proto_tree_add_bits_item(ptvcursor_tree(ptvc), hf_nfapi_p7_message_header_m, ptvcursor_tvbuff(ptvc), (ptvcursor_current_offset(ptvc)) * 8, 1, ENC_NA); ++ proto_tree_add_bits_item(ptvcursor_tree(ptvc), hf_nfapi_p7_message_header_segment, ptvcursor_tvbuff(ptvc), ((ptvcursor_current_offset(ptvc)) * 8) + 1, 7, ENC_NA); ++ ptvcursor_advance(ptvc, 1); ++ ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_sequence_number, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_checksum, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_p7_message_header_transmit_timestamp, 4, ENC_BIG_ENDIAN); ++ ++ ptvcursor_pop_subtree(ptvc); ++} ++ ++static reassembly_table ul_p7_reassemble_table; ++static reassembly_table dl_p7_reassemble_table; ++ ++static int hf_msg_fragments = -1; ++static int hf_msg_fragment = -1; ++static int hf_msg_fragment_overlap = -1; ++static int hf_msg_fragment_overlap_conflicts = -1; ++static int hf_msg_fragment_multiple_tails = -1; ++static int hf_msg_fragment_too_long_fragment = -1; ++static int hf_msg_fragment_error = -1; ++static int hf_msg_fragment_count = -1; ++static int hf_msg_reassembled_in = -1; ++static int hf_msg_reassembled_length = -1; ++static gint ett_msg_fragment = -1; ++static gint ett_msg_fragments = -1; ++ ++static const fragment_items msg_frag_items = { ++ /* Fragment subtrees */ ++ &ett_msg_fragment, ++ &ett_msg_fragments, ++ /* Fragment fields */ ++ &hf_msg_fragments, ++ &hf_msg_fragment, ++ &hf_msg_fragment_overlap, ++ &hf_msg_fragment_overlap_conflicts, ++ &hf_msg_fragment_multiple_tails, ++ &hf_msg_fragment_too_long_fragment, ++ &hf_msg_fragment_error, ++ &hf_msg_fragment_count, ++ /* Reassembled in field */ ++ &hf_msg_reassembled_in, ++ /* Reassembled length field */ ++ &hf_msg_reassembled_length, ++ NULL, ++ /* Tag */ ++ "Message fragments" ++}; ++ ++static void dissect_nfapi_ul_p7(ptvcursor_t *ptvc, packet_info *pinfo) ++{ ++ guint8 m; ++ guint8 seg; ++ guint8 seq; ++ ++ guint8 save_fragmented; ++ ptvcursor_t* sub_ptvc = 0; ++ ++ guint16 msg_id = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), 2); ++ guint16 msg_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), 4); ++ ++ dissect_p7_header_new(ptvc, &m, &seg, &seq); ++ save_fragmented = pinfo->fragmented; ++ ++ if (m == 1 || (m == 0 && seg > 0)) ++ { ++ tvbuff_t* tvbuff = ptvcursor_tvbuff(ptvc); ++ guint offset = ptvcursor_current_offset(ptvc); ++ proto_tree* tree = ptvcursor_tree(ptvc); ++ ++ pinfo->fragmented = TRUE; ++ ++ fragment_head *fd_head = fragment_add_seq_check(&ul_p7_reassemble_table, tvbuff, offset, pinfo, seq, NULL, seg, msg_len - offset, (m == 1)); ++ ++ if (fd_head) ++ { ++ tvbuff_t * new_tvb = process_reassembled_data(tvbuff, offset, pinfo, "Reassembled UL P7", fd_head, &msg_frag_items, NULL, tree); ++ if (new_tvb) ++ { ++ sub_ptvc = ptvcursor_new(tree, new_tvb, 0); ++ ++ col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Reassembled %d]", seg); ++ } ++ else ++ { ++ col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Segment %d]", seg); ++ return; ++ } ++ } ++ else ++ { ++ return; ++ } ++ } ++ ++ pinfo->fragmented = save_fragmented; ++ ++ { ++ switch (msg_id) ++ { ++ case NFAPI_HARQ_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_CRC_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_RX_ULSCH_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_RACH_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_SRS_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_RX_SR_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_RX_CQI_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ ++ }; ++ } ++ ++ if (sub_ptvc) ++ ptvcursor_free(sub_ptvc); ++} ++ ++static void dissect_nfapi_dl_p7(ptvcursor_t *ptvc, packet_info *pinfo) ++{ ++ guint8 m; ++ guint8 seg; ++ guint8 seq; ++ ++ guint8 save_fragmented; ++ ptvcursor_t* sub_ptvc = 0; ++ ++ guint16 msg_id = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), 2); ++ guint16 msg_len = tvb_get_ntohs(ptvcursor_tvbuff(ptvc), 4); ++ ++ dissect_p7_header_new(ptvc, &m, &seg, &seq); ++ save_fragmented = pinfo->fragmented; ++ ++ if (m == 1 || (m == 0 && seg > 0)) ++ { ++ tvbuff_t* tvbuff = ptvcursor_tvbuff(ptvc); ++ guint offset = ptvcursor_current_offset(ptvc); ++ proto_tree* tree = ptvcursor_tree(ptvc); ++ ++ pinfo->fragmented = TRUE; ++ ++ fragment_head *fd_head = fragment_add_seq_check(&dl_p7_reassemble_table, tvbuff, offset, pinfo, seq, NULL, seg, msg_len - offset, (m == 1)); ++ ++ if (fd_head) ++ { ++ tvbuff_t * new_tvb = process_reassembled_data(tvbuff, offset, pinfo, "Reassembled DL P7", fd_head, &msg_frag_items, NULL, tree); ++ if (new_tvb) ++ { ++ sub_ptvc = ptvcursor_new(tree, new_tvb, 0); ++ col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Reassembled %d]", seg); ++ } ++ else ++ { ++ col_append_fstr(pinfo->cinfo, COL_INFO, "[NFAPI P7 Segment %d]", seg); ++ return; ++ } ++ } ++ else ++ { ++ return; ++ } ++ } ++ ++ pinfo->fragmented = save_fragmented; ++ ++ switch (msg_id) ++ { ++ case NFAPI_DL_CONFIG_REQUEST_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ break; ++ } ++ case NFAPI_UL_CONFIG_REQUEST_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_HI_DCI0_REQUEST_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_TX_REQUEST_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_LBT_DL_CONFIG_REQUEST_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ } ++ break; ++ case NFAPI_LBT_DL_INDICATION_MSG_ID: ++ { ++ ptvcursor_add(sub_ptvc ? sub_ptvc : ptvc, hf_nfapi_sfn_sf, 2, ENC_BIG_ENDIAN); ++ dissect_tlv_list(sub_ptvc ? sub_ptvc : ptvc, pinfo, msg_len); ++ break; ++ } ++ } ++ ++ if (sub_ptvc) ++ ptvcursor_free(sub_ptvc); ++} ++ ++ ++static int dissect_nfapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) ++{ ++ col_set_str(pinfo->cinfo, COL_PROTOCOL, "NFAPI"); ++ ++ ptvcursor_t* ptvc = ptvcursor_new(tree, tvb, 0); ++ ++ guint16 msg_id = tvb_get_ntohs(tvb, 2); ++ ++ // Get the name of the message ++ const gchar* message_str = val_to_str_const(msg_id, message_id_vals, "Unknown"); ++ ++ // Append to the Info string the nFAPI messages ++ col_clear(pinfo->cinfo, COL_INFO); ++ col_append_fstr(pinfo->cinfo, COL_INFO, " %s ", message_str); ++ ++ // Flag if this is a vendor extention message, could do it for P4, 5, 7 ++ if (msg_id >= 0x0300 && msg_id <= 0x03FF) ++ { ++ col_append_fstr(pinfo->cinfo, COL_INFO, " Vendor Extension"); ++ } ++ ++ // Create the top level tree ++ ptvcursor_add_text_with_subtree(ptvc, SUBTREE_UNDEFINED_LENGTH, ett_nfapi_message_tree, "%s", message_str); ++ ++ switch (msg_id) ++ { ++ case NFAPI_HARQ_INDICATION_MSG_ID: ++ case NFAPI_CRC_INDICATION_MSG_ID: ++ case NFAPI_RX_ULSCH_INDICATION_MSG_ID: ++ case NFAPI_RACH_INDICATION_MSG_ID: ++ case NFAPI_SRS_INDICATION_MSG_ID: ++ case NFAPI_RX_SR_INDICATION_MSG_ID: ++ case NFAPI_RX_CQI_INDICATION_MSG_ID: ++ { ++ dissect_nfapi_ul_p7(ptvc, pinfo); ++ } + break; +- // LBT_DL.indication +- case 0x8D: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint16_with_conversion(msg_tree, hf_nfapi_sfn_sf, tvb, &offset, sfn_sf_conversion); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // PNF_PARAM.request +- case 0x100: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // PNF_PARAM.response +- case 0x101: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // PNF_CONFIG.request +- case 0x102: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // PNF_CONFIG.response +- case 0x103: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // PNF_START.request +- case 0x104: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; +- } +- // PNF_START.response +- case 0x105: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // PNF_STOP.response +- case 0x106: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; +- } +- // PNF_STOP.request +- case 0x107: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // PARAM.request +- case 0x108: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; +- } +- // PARAM.response +- case 0x109: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // CONFIG.request +- case 0x10A: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_num_tlv, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- // CONFIG.response +- case 0x10B: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // START.request +- case 0x10C: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; +- } +- // START.response +- case 0x10D: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // STOP.request +- case 0x10E: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; +- } +- // STOP.response +- case 0x10F: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- break; +- } +- // MEASUREMENT.request +- case 0x110: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ ++ case NFAPI_DL_CONFIG_REQUEST_MSG_ID: ++ case NFAPI_UL_CONFIG_REQUEST_MSG_ID: ++ case NFAPI_HI_DCI0_REQUEST_MSG_ID: ++ case NFAPI_TX_REQUEST_MSG_ID: ++ case NFAPI_LBT_DL_CONFIG_REQUEST_MSG_ID: ++ case NFAPI_LBT_DL_INDICATION_MSG_ID: ++ { ++ dissect_nfapi_dl_p7(ptvc, pinfo); ++ break; ++ } ++ ++ case NFAPI_PNF_PARAM_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_PNF_PARAM_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ ++ break; ++ } ++ case NFAPI_PNF_CONFIG_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_PNF_CONFIG_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_PNF_START_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; ++ } ++ case NFAPI_PNF_START_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_PNF_STOP_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; ++ } ++ case NFAPI_PNF_STOP_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_PARAM_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; ++ } ++ case NFAPI_PARAM_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 1, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_num_tlv, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_CONFIG_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_CONFIG_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_START_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; ++ } ++ case NFAPI_START_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_STOP_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; ++ } ++ case NFAPI_STOP_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_MEASUREMENT_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_MEASUREMENT_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ ++ // P4 ++ case NFAPI_RSSI_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_rat_type, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_RSSI_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; ++ } ++ case NFAPI_RSSI_INDICATION_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; ++ } ++ case NFAPI_CELL_SEARCH_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_rat_type, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // MEASUREMENT.response +- case 0x111: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; +- } +- +- // P4 +- // RSSI.request +- case 0x200: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_rat_type, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_CELL_SEARCH_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; + } +- // RSSI.response +- case 0x201: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; ++ case NFAPI_CELL_SEARCH_INDICATION_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // RSSI.indication +- case 0x202: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_BROADCAST_DETECT_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_rat_type, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // CELL_SEARCH.request +- case 0x203: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_rat_type, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_BROADCAST_DETECT_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; + } +- // CELL_SEARCH.response +- case 0x204: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; ++ case NFAPI_BROADCAST_DETECT_INDICATION_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // CELL_SEARCH.indication +- case 0x205: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_rat_type, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // BROADCAST_DETECT.request +- case 0x206: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_rat_type, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; + } +- // BROADCAST_DETECT.response +- case 0x207: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; ++ case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // BROADCAST_DETECT.indication +- case 0x208: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_SYSTEM_INFORMATION_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_rat_type, 1, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // SYSTEM_INFORMATION_SCHEDULE.request +- case 0x209: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_rat_type, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_SYSTEM_INFORMATION_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; + } +- // SYSTEM_INFORMATOIN_SCHEDULE.response +- case 0x20A: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; ++ case NFAPI_SYSTEM_INFORMATION_INDICATION_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ dissect_tlv_list(ptvc, pinfo, tvb_reported_length(tvb)); ++ break; + } +- // SYSTEM_INFORMATION_SCHEDULE.indication +- case 0x20B: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_NMM_STOP_REQUEST_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ break; + } +- // SYSTEM_INFORMATION.request +- case 0x20C: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint8(msg_tree, hf_nfapi_rat_type, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_NMM_STOP_RESPONSE_MSG_ID: ++ { ++ dissect_p45_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_p4_error_code, 4, ENC_BIG_ENDIAN); ++ break; + } +- // SYSTEM_INFORMATION.response +- case 0x20D: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; ++ case NFAPI_DL_NODE_SYNC_MSG_ID: ++ { ++ dissect_p7_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_ul_node_sync_t1, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_ul_node_sync_t2, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_ul_node_sync_t3, 4, ENC_BIG_ENDIAN); ++ break; + } +- // SYSTEM_INFORMATION.indication +- case 0x20E: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- dissect_tlv_list(tvb, pinfo, msg_tree, data, &offset, tvb_reported_length(tvb)); +- break; ++ case NFAPI_UL_NODE_SYNC_MSG_ID: ++ { ++ dissect_p7_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_dl_node_sync_t1, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_dl_node_sync_delta_sfn_sf, 4, ENC_BIG_ENDIAN); ++ break; + } +- // NMM_STOP.request +- case 0x20F: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- break; ++ case NFAPI_TIMING_INFO_MSG_ID: ++ { ++ dissect_p7_header(ptvc, pinfo); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_last_sfn_sf, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_time_since_last_timing_info, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_dl_config_jitter, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_tx_request_jitter, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_ul_config_jitter, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_hi_dci0_jitter, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_dl_config_latest_delay, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_tx_request_latest_delay, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_ul_config_latest_delay, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_hi_dci0_latest_delay, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_dl_config_earliest_arrival, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_tx_request_earliest_arrival, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_ul_config_earliest_arrival, 4, ENC_BIG_ENDIAN); ++ ptvcursor_add(ptvc, hf_nfapi_timing_info_hi_dci0_earliest_arrival, 4, ENC_BIG_ENDIAN); ++ break; + } +- // NMM_STOP_response +- case 0x210: +- { +- dissect_p45_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_p4_error_code, tvb, &offset, 0); +- break; +- } +- +- // DL_NODE.sync +- case 0x0180: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_ul_node_sync_t1, tvb, &offset, "microseconds"); +- proto_tree_add_uint32(msg_tree, hf_nfapi_ul_node_sync_t2, tvb, &offset, "microseconds"); +- proto_tree_add_uint32(msg_tree, hf_nfapi_ul_node_sync_t3, tvb, &offset, "microseconds"); +- break; +- } +- // UL_NODE.sync +- case 0x0181: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_dl_node_sync_t1, tvb, &offset, "microseconds"); +- proto_tree_add_uint32(msg_tree, hf_nfapi_dl_node_sync_delta_sfn_sf, tvb, &offset, 0); +- break; +- } +- // TIMING_INFO +- case 0x0182: +- { +- dissect_p7_header(tvb, pinfo, msg_tree, data, &offset); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_last_sfn_sf, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_time_since_last_timing_info, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_dl_config_jitter, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_tx_request_jitter, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_ul_config_jitter, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_hi_dci0_jitter, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_dl_config_latest_delay, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_tx_request_latest_delay, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_ul_config_latest_delay, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_hi_dci0_latest_delay, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_dl_config_earliest_arrival, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_tx_request_earliest_arrival, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_ul_config_earliest_arrival, tvb, &offset, 0); +- proto_tree_add_uint32(msg_tree, hf_nfapi_timing_info_hi_dci0_earliest_arrival, tvb, &offset, 0); +- break; +- } +- default: +- { +- // todo : is this vendor extention? +- break; +- } +- }; +- +- return tvb_captured_length(tvb); +-} +- +-static void nfapi_tag_vals_fn(gchar* s, guint32 v) +-{ +- int index = look_up_tlv(v); +- if (v >= 0) +- { +- g_snprintf(s, ITEM_LABEL_LENGTH, "%s (0x%x)", tags[index].name, v); +- } +- else +- { +- g_snprintf(s, ITEM_LABEL_LENGTH, "%s (0x%x)", "Unknown", v); +- } +-} +- +-// ----------------------------------------------------------------------------| +- +-void proto_register_nfapi(void) +-{ +- +- static hf_register_info hf[] = +- { +- { &hf_msg_fragments, { "Message fragments", "afs.fragments", FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment, { "Message fragment", "afs.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_overlap, { "Message fragment overlap", "afs.fragment.overlap", FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_overlap_conflicts, { "Message fragment overlapping with conflicting data", "afs.fragment.overlap.conflicts", FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_multiple_tails, { "Message has multiple tail fragments", "afs.fragment.multiple_tails", FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_too_long_fragment, { "Message fragment too long", "afs.fragment.too_long_fragment", FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_error, { "Message defragmentation error", "afs.fragment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_fragment_count, { "Message fragment count", "afs.fragment.count", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_reassembled_in, { "Reassembled in", "afs.reassembled.in", FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_reassembled_length, { "Reassembled length", "afs.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, +- { &hf_msg_reassembled_data, { "Reassembled data", "afs.reassembled.data", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, +- { &hf_nfapi_message_tree, { "Message tree", "nfapi.message_tree", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_p5_message_header, { "P4 P5 Header", "nfapi.p4_p5_message_header", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_p5_message_header_phy_id, { "PHY ID", "nfapi.p4_p5_message_header.phy_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_p5_message_header_message_id, { "Message ID", "nfapi.p4_p5_message_header.message_id", FT_UINT16, BASE_HEX_DEC, VALS(message_id_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_p5_message_header_message_length, { "Message Length", "nfapi.p4_p5_message_header.message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_p5_message_header_spare, { "Spare", "nfapi.p4_p5_message_header.spare", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header, { "P7 Header", "nfapi.p7_message_header", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_phy_id, { "Phy ID", "nfapi.p7_message_header.phy_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_message_id, { "Message ID", "nfapi.p7.message_header.message_id", FT_UINT16, BASE_HEX_DEC, VALS(message_id_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_message_length, { "Message Length", "nfapi.p7_message_header.message_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_m, { "M", "nfapi.p7_message_header.m_segment_sequence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_segment, { "Segment Number", "nfapi.p7_message_header.m_segment_sequence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_sequence_number, { "Sequence Number", "nfapi.p7_message_header.m_segment_sequence", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_checksum, { "Checksum", "nfapi.p7_message_header.checksum", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_p7_message_header_transmit_timestamp, { "Transmit Timestamp", "nfapi.p7_message_header.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tlv_tree, { "TAG", "nfapi.tlv.tree", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tl, { "TL", "nfapi.tl", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tl_tag, { "TL Tag", "nfapi.tl_tag", FT_UINT16, BASE_CUSTOM, CF_FUNC(nfapi_tag_vals_fn), 0x0, NULL, HFILL } }, +- { &hf_nfapi_tl_length, { "TL Length", "nfapi.tl_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tag_uint8_value, { "Value", "nfapi.tag.uint8.value", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tag_uint16_value, { "Value", "nfapi.tag.uint16.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_param_response, { "Param Request", "nfapi.param.request", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_error_code, { "Error Code", "nfapi.error.code", FT_UINT8, BASE_DEC, VALS(nfapi_error_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_p4_error_code, { "Error Code", "nfapi.p4_error.code", FT_UINT8, BASE_DEC, VALS(nfapi_p4_error_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_rat_type, { "RAT Type", "nfapi.rat_type", FT_UINT8, BASE_DEC, VALS(nfapi_rat_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_num_tlv, { "Number of TLV", "nfapi.param.response.num_tlv", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phy_state, { "Phy state value", "nfapi.phy.state", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_modulation_support, { "Modulation value", "nfapi.modulation.support", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_ue_per_sf, { "Downlink UEs per Subframe", "nfapi.dl.ue.per.sf", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_ue_per_sf, { "Uplink UEs per Subframe", "nfapi.ul.ue.per.sf", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_duplex_mode, { "Duplex Mode", "nfapi.duplex.mode", FT_UINT16, BASE_DEC, VALS(nfapi_duplex_mode_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_bandwidth_support, { "Downlink bandwidth support", "nfapi.dl.bandwidth.support", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_bandwidth_support, { "Uplink bandwidth support", "nfapi.ul.bandwidth.support", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_modulation_support, { "Downlink modulation support", "nfapi.dl.modulation.support", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_modulation_support, { "Uplink modulation support", "nfapi.ul.modulation.support", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phy_antenna_capability, { "Phy Antenna capability", "nfapi.phy.antenna.capability", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_release_capability, { "Release capability", "nfapi.release.capability", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mbsfn_capability, { "MBSFN capability", "nfapi.mbsfn.capability", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_capability, { "LAA Support", "nfapi.laa.support", FT_BOOLEAN, 8, TFS(&support_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_pd_sensing_lbt_support, { "PD sensing LBT support", "nfapi.pd.sensing.lbt.support", FT_BOOLEAN, 8, TFS(&support_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_multi_carrier_lbt_support, { "Multi carrier LBT support", "nfapi.multi.carrier.lbt.support", FT_UINT16, BASE_DEC, VALS(nfapi_mutli_carrier_lbt_support_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_partial_sf_support, { "Partial SF support", "nfapi.partial.sf.support", FT_BOOLEAN, 8, TFS(&partial_sf_support_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_reference_signal_power, { "Reference signal power", "nfapi.ref_sig_power", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_primary_synchronization_signal_epre_eprers, { "Primary synchronization signal EPRE/EPRERS", "nfapi.primary.sync.signal", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_secondary_synchronization_signal_epre_eprers, { "Secondary synchronization signal EPRE/EPRERS", "nfapi.secondary.sync.signal", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_physical_cell_id, { "Physical Cell ID", "nfapi.physical.cell.id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phich_resource, { "PHICH Resource", "nfapi.phich.resource", FT_UINT16, BASE_DEC, VALS(nfapi_phich_resource_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_phich_duration, { "PHICH Duration", "nfapi.phich.duration", FT_BOOLEAN, 8, TFS(&phich_duration_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_phich_power_offset, { "PHICH Power Offset", "nfapi.phich.power.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_configuration_index, { "Configuration Index", "nfapi.configuration.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_root_sequence_index, { "Root sequence Index", "nfapi.root.sequence.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_zero_correlation_zone_configuration, { "Zero correlation zone configuration", "nfapi.zero.correlation.zone.configuration", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_high_speed_flag, { "High Speed Flag", "nfapi.high.speed.flag", FT_BOOLEAN, 8, TFS(&high_speed_flag_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_offset, { "Frequency offset", "nfapi.frequency.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_hopping_mode, { "Hopping Mode", "nfapi.hopping.mode", FT_BOOLEAN, 8, TFS(&hopping_mode_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_hopping_offset, { "Hopping offset", "nfapi.hopping.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_pucch_shift, { "Delta PUCCH Shift", "nfapi.delta.pucch.shift", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_cqi_rb, { "N CQI RB", "nfapi.n.cqi.rb", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_an_cs, { "N AN CS", "nfapi.n.an.cs", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n1_pucch_an, { "N1 PUCCH AN", "nfapi.n1.pucch.an", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bandwidth_configuration, { "Bandwidth configuration", "nfapi.bw.configuration", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_subframe_configuration, { "SRS subframe configuration", "nfapi.srs.subframe.configuration", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uplink_rs_hopping, { "Uplink RS hopping", "nfapi.uplink.rs.hopping", FT_UINT16, BASE_DEC, VALS(nfapi_uplink_rs_hopping_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_group_assignment, { "Group assigment", "nfapi.group.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cyclic_shift_1_for_drms, { "Cyclic Shift 1 for DRMS", "nfapi.cyclic.shift.1.for.drms", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_subframe_assignment, { "Subframe_assignment", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_special_subframe_patterns, { "Special Subframe patterns", "nfapi.special.subframe.patterns", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ed_threshold_for_lbt_for_pdsch, { "ED Threshold for LBT for PDSCH", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ed_threshold_for_lbt_for_drs, { "ED Threshold for LBT for DRS", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pd_threshold, { "PD Threshold", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_multi_carrier_type, { "Multi carrier type", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, VALS(nfapi_laa_carrier_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_multi_carrier_tx, { "Multi carrier TX", "nfapi.subframe.assignment", FT_BOOLEAN, 8, TFS(&nfapi_multi_carrier_tx_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_multi_carrier_freeze, { "Multi carrier freeze ", "nfapi.subframe.assignment", FT_BOOLEAN, 8, TFS(&nfapi_multi_carrier_freeze_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_tx_antenna_ports_for_drs, { "Tx antenna ports for DRS", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_power_for_drs, { "Transmission power for DRS", "nfapi.subframe.assignment", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pbch_repetitions_enabled_r13, { "PBCH Repetitions enable R13", "nfapi.pbch.repetitions.enabled_r13", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_cat_m_root_sequence_index, { "PRACH CAT-M Root sequence index", "nfapi.prach.cat_m.root.squence.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_cat_m_zero_correlation_zone_configuration, { "PRACH CAT-M Zero correlation zone configuration", "nfapi.prach.cat_m.zero.correlation.zone.configuration", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_cat_m_high_speed_flag, { "PRACH CAT-M High speed flag", "nfapi.prach.cat_m.high.speed.flag", FT_BOOLEAN, 8, TFS(&high_speed_flag_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_enable, { "PRACH CE level #0 Enable", "nfapi.prach.ce.level.0.enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_configuration_index, { "PRACH CE level #0 Configuration index", "nfapi.prach.ce.level.0.configuration.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_frequency_offset, { "PRACH CE level #0 Frequency offset", "nfapi.prach.ce.level.0.frequency_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt, { "PRACH CE level #0 Number of repetitions per attempt", "nfapi.prach.ce.level.0.number.of.repetitions.per_attempt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_starting_subframe_periodicity, { "CE level #0 Starting subframe periodicity", "nfapi.prach.ce.level.0.starting.subframe_periodicity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_hopping_enabled, { "PRACH CE level #0 Hopping Enable", "nfapi.prach.ce.level.0.hopping_enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_0_hopping_offset, { "PRACH CE level #0 Hopping Offset", "nfapi.prach.ce.level.0.hopping.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_enable, { "PRACH CE level #1 Enable", "nfapi.prach.ce.level.0.enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_configuration_index, { "PRACH CE level #1 Configuration index", "nfapi.prach.ce.level.0.configuration.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_frequency_offset, { "PRACH CE level #1 Frequency offset", "nfapi.prach.ce.level.0.frequency_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt, { "PRACH CE level #1 Number of repetitions per attempt", "nfapi.prach.ce.level.0.number.of.repetitions.per_attempt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_starting_subframe_periodicity, { "CE level #1 Starting subframe periodicity", "nfapi.prach.ce.level.0.starting.subframe_periodicity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_hopping_enabled, { "PRACH CE level #1 Hopping Enable", "nfapi.prach.ce.level.0.hopping_enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_1_hopping_offset, { "PRACH CE level #1 Hopping Offset", "nfapi.prach.ce.level.0.hopping.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_enable, { "PRACH CE level #2 Enable", "nfapi.prach.ce.level.0.enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_configuration_index, { "PRACH CE level #2 Configuration index", "nfapi.prach.ce.level.0.configuration.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_frequency_offset, { "PRACH CE level #2 Frequency offset", "nfapi.prach.ce.level.0.frequency_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt, { "PRACH CE level #2 Number of repetitions per attempt", "nfapi.prach.ce.level.0.number.of.repetitions.per_attempt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_starting_subframe_periodicity, { "CE level #2 Starting subframe periodicity", "nfapi.prach.ce.level.0.starting.subframe_periodicity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_hopping_enabled, { "PRACH CE level #2 Hopping Enable", "nfapi.prach.ce.level.0.hopping_enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_2_hopping_offset, { "PRACH CE level #2 Hopping Offset", "nfapi.prach.ce.level.0.hopping.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_enable, { "PRACH CE level #3 Enable", "nfapi.prach.ce.level.0.enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_configuration_index, { "PRACH CE level #3 Configuration index", "nfapi.prach.ce.level.0.configuration.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_frequency_offset, { "PRACH CE level #3 Frequency offset", "nfapi.prach.ce.level.0.frequency_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt, { "PRACH CE level #3 Number of repetitions per attempt", "nfapi.prach.ce.level.0.number.of.repetitions.per_attempt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_starting_subframe_periodicity, { "CE level #3 Starting subframe periodicity", "nfapi.prach.ce.level.0.starting.subframe_periodicity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_hopping_enabled, { "PRACH CE level #3 Hopping Enable", "nfapi.prach.ce.level.0.hopping_enable", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_ce_level_3_hopping_offset, { "PRACH CE level #3 Hopping Offset", "nfapi.prach.ce.level.0.hopping.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a, { "PUCCH Interval-ULHoppingConfigCommonModeA", "nfapi.pucch.interval.ulhopping.config.common.mode.a", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b, { "PUCCH Interval-ULHoppingConfigCommonModeB", "nfapi.pucch.interval.ulhopping.config.common.mode.b", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_data_report_mode, { "Data Report Mode", "nfapi.data.report.mode", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sfnsf, { "SFN/SF", "nfapi.sfn.sf", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_max_up_pts, { "Max UpPTS frames", "nfapi.max.uppts.frame", FT_BOOLEAN, 8, TFS(&enabled_disabled_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_acknack_srs_simultaneous_transmission, { "SRS AckNack Simultaneous transmission", "nfapi.srs.acknack.simult.tx", FT_BOOLEAN, 8, TFS(&srs_simult_tx_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_address, { "PNF address", "nfapi.p7.pnf.address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_address_ipv4, { "PNF IPV4", "nfapi.pnf.address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_address_ipv6, { "PNF IPV6", "nfapi.pnf.address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_vnf_address, { "VNF address", "nfapi.vnf.address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_vnf_address_ipv4, { "VNF IPV4 Address", "nfapi.vnf.address.ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_vnf_address_ipv6, { "VNF IPV6 Address", "nfapi.vnf.address.ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_port, { "PNF PORT value", "nfapi.config.pnf.port.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_vnf_port, { "VNF PORT value", "nfapi.config.vnf.port.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rf_bands, { "RF Bands", "nfapi.rf.bands", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rf_bands_count, { "Number of RF Bands", "nfapi.rf.bands.count", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rf_bands_value, { "Band value", "nfapi.rf.bands.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_param_request, { "PNF Param Request", "nfapi.pnf.param.request", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_param_response, { "PNF Param Response", "nfapi.pnf.param.response", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_config_request, { "PNF Config Request", "nfapi.pnf.config.request", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_config_response, { "PNF Config Response", "nfapi.pnf.config.response", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_start_request, { "PNF Start Request", "nfapi.pnf.start.request", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_start_response, { "PNF Start Response", "nfapi.pnf.start.response", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_start_request, { "PNF Start Request", "nfapi.start.request", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_start_response, { "PNF Start Response", "nfapi.start.response", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_param_general, { "PNF Param General ", "nfapi.pnf.param.general", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sync_mode, { "Sync Mode", "nfapi.sync.mode", FT_UINT8, BASE_DEC, VALS(nfapi_sync_mode_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_location_mode, { "Location Mode", "nfapi.location.mode", FT_UINT8, BASE_DEC, VALS(location_mode_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_location_coordinates_length, { "Location Coordinates Length", "nfapi.location.coordinates.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_location_coordinates, { "Location Coordinates", "nfapi.location.coordinates", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdu, { "PDU", "nfapi.pdu", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_timing, { "DL config Timing", "nfapi.dl.config.timing", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tx_timing, { "Tx Timing", "nfapi.general.tx.timing", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_timing, { "UL Config Timing", "nfapi.ul.config.timing", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_hi_dci0_timing, { "HI DCi0 Timing", "nfapi.hi.dci0.timing", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_number_phys, { "Maximum number of Phys", "nfapi.maximum.number.phys", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_total_bandwidth, { "Maximum Total Bandwidth", "nfapi.maximum.total.bandwidth", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_total_number_dl_layers, { "Maximum Total Number DL Layers", "nfapi.maximum.total.number.dl.layers", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_total_number_ul_layers, { "Maximum Total Number UL Layers", "nfapi.maximum.total.number.ul.layers", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_shared_bands, { "Shared bands", "nfapi.shared.bands", FT_BOOLEAN, 8, TFS(&true_false_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_shared_pa, { "Shared pa", "nfapi.shared.pa", FT_BOOLEAN, 8, TFS(&true_false_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_total_power, { "Maximum total power", "nfapi.maximum.total.power", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_oui, { "OUI", "nfapi.oui", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy, { "PNF Phy", "nfapi.pnf.phy", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy_number_phy, { "PNF Phy Number of Phy", "nfapi.pnf.phy.number.phy", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy_config_index, { "PNF Phy Config Index", "nfapi.pnf.phy.config.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_rf, { "PNF Phy RF", "nfapi.pnf.rf", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_rfs, { "Number of RFs", "nfapi.pnf.rf.number.rf", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phy_rf_config_info, { "Phy RF Config Info", "nfapi.phy.rf.config.info", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phy_rf_config_info_phy_id, { "Phy ID", "nfapi.pnf.phy.rf.config.phy.id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phy_rf_config_info_band, { "RF Band", "nfapi.pnf.phy.rf.config.phy.id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy_rf_config, { "PNF Phy RF Config", "nfapi.pnf.phy.rf.config", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy_rf_config_number_phy_rf_config_info, { "Number of RF Config Info(s)", "nfapi.pnf.phy.rf.config.number.phy.rf.config.info", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_phy_rf_config_array_phy_rf_config_info, { "PNF Phy RF Config array phy rf config info ", "nfapi.pnf.phy.rf.config.array.phy.rf.config.info", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rf_config_index, { "RF Config Index", "nfapi.rf_config_index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_rf_exclusions, { "Number of RF exclusions", "nfapi.hf_nfapi_number_of_rf_exclusions", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_3gpp_release_supported, { "Maximum 3gpp Release Supported", "nfapi.maximum_3gpp_release_supported", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_downlink_channel_bandwidth_supported, { "Maximum Channel Downlink Bandwidth Supported", "nfapi.downlink_channel_bandwidth_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uplink_channel_bandwidth_supported, { "Maximum Channel Uplink Bandwidth Supported", "nfapi.uplink_channel_bandwidth_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_dl_layers_supported, { "Number of DL Layers Supported", "nfapi.number_of_dl_layer_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_ul_layers_supported, { "Number of UL Layers Supported", "nfapi.number_of_ul_layer_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_nmm_modes_supported, { "NMM modes supported", "nfapi.nmm_modes_supported", FT_UINT8, BASE_DEC, VALS(nmm_modes_supported_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_band, { "Band", "nfapi.band", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_transmit_power, { "Maximum transmit power", "nfapi.maximum_transmit_power", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_earfcn, { "EARFCN", "nfapi.earfcn", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_rf_bands, { "Number of RF Bands", "nfapi.num.rf_bands", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_nmm_uplink_rssi_supported, { "NMM Uplink RSSI supported", "nfapi.nmm.uplink.rssi.supported", FT_UINT16, BASE_DEC, VALS(ul_rssi_supported_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_minimum_transmit_power, { "Minimum transmit power", "nfapi.minimum_transmit_power", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_antennas_suppported, { "Number of Supported Antennas", "nfapi.number_of_antennas_suppported", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_minimum_downlink_frequency, { "Minimum downlink frequency", "nfapi.minimum_downlink_frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_downlink_frequency, { "Maximum downlink frequency", "nfapi.maximum_downlink_frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_minimum_uplink_frequency, { "Minimum uplink frequency", "nfapi.minimum_downlink_frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_maximum_uplink_frequency, { "Maximum uplink frequency", "nfapi.maximum_downlink_frequency", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_mode7_supported, { "Transmission Mode 7 Supported", "nfapi.pnf.phy_rel10.tx_mode7_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_transmission_mode8_supported, { "Transmission Mode 8 Supported", "nfapi.pnf.phy_rel10.tx_mode8_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_two_antennas_ports_for_pucch, { "Two antennas ports for PUCCH", "nfapi.pnf.phy_rel10.two_antennas_ports_for_pucch", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_transmission_mode_9_supported, { "Transmission Mode 9 Supported", "nfapi.pnf.phy_rel10.tx_mode9_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_simultaneous_pucch_pusch, { "Simultaneous PUCCH PUSCH", "nfapi.pnf.simultaneous_pucch_pusch", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_for_layer_tx_with_tm3_and_tm4, { "Four layer Tx with TM3 and TM4", "nfapi.pnf.phy_rel10.layer_tx_with_tm3_and_tm4", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_supported, { "ePDCCH supported", "nfapi.pnf.phy_rel11.epdcch_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_multi_ack_csi_reporting, { "Multi ACK CSI reporting", "nfapi.pnf.phy_rel11.mutli_ack_csi_reporting", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_pucch_tx_diversity_with_channel_selection, { "PUCCH Tx diversity with channel selection", "nfapi.pnf.phy_rel11.tx_div_with_channel_selection", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_ul_comp_supported, { "UL CoMP supported", "nfapi.pnf.phy_rel11.ul_comp_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_transmission_mode_5_supported, { "Transmission mode 5 supported", "nfapi.pnf.phy_rel11.tx_mode5_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_subframe_set, { "CSI subframe set", "nfapi.pnf.phy_rel12.csi_subframe_set", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_enhanced_4tx_codebook, { "Enhanced 4TX codebook", "nfapi.pnf.phy_rel12.exhanced_t4x_codebook", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_drs_supported, { "DRS supported", "nfapi.pnf.phy_rel12.drs_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_ul_64qam_supported, { "UL 64QAM supported", "nfapi.pnf.phy_rel12.ul_64qam_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_transmission_mode_10_supported, { "Transmission mode 10 supported", "nfapi.pnf.phy_rel12.tx_mode10_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hi_nfapi_alternative_tbs_indices, { "Alternative TBS indices", "nfapi.pnf.phy_rel12.alternative_tbs_indices", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_format_4_supported, { "PUCCH format 4 supported", "nfapi.pnf.phy_rel13.pucch_format4_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_format_5_supported, { "PUCCH format 5 supported", "nfapi.pnf.phy_rel13.pucch_format5_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_more_than_5_ca_supported, { "More than 5 CA support", "nfapi.pnf.phy_rel13.mode_than_5_ca_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_supported, { "LAA supported", "nfapi.pnf.phy_rel13.laa_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_ending_in_dwpts_supported, { "LAA ending in DwPTS supported", "nfapi.pnf.phy_rel13.laa_ending_in_dwpts_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_starting_in_second_slot_supported, { "LAA starting in second slot Supported", "nfapi.pnf.phy_rel13.laa_starting_in_second_slot_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_beamforming_supported, { "Beamforming Supported", "nfapi.pnf.phy_rel13.beamingforming_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_enhancements_supported, { "CSI-RS enhancements supported", "nfapi.pnf.phy_rel13.csi_rs_enchancements_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_drms_enhancements_supported, { "DMRS enhancements supported", "nfapi.pnf.phy_rel13.drms_enhancements_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_enhancements_supported, { "SRS enhancements supported", "nfapi.pnf.phy_rel13.srs_enhancements_supported", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sfn_sf, { "SFN_SF", "nfapi.sfn_sf", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_request_body, { "DL Config Request body", "nfapi.dl.config.request.body", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_pdcch_ofdm_symbols, { "Number of PDCCH OFDM Symbols", "nfapi.number_pdcch_ofdm_symbols", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_dci, { "Number of DCI", "nfapi.number_dci", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_pdus, { "Number of PDUs", "nfapi.number_pdu", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_harqs, { "Number of HARQs", "nfapi.number_harqs", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_crcs, { "Number of CRCs", "nfapi.number_crcs", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_srs, { "Number of SRs", "nfapi.number_srs", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_cqi, { "Number of CQIs", "nfapi.number_cqi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_preambles, { "Number of Preambles", "nfapi.number_preambles", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_srss, { "Number of SRSs", "nfapi.number_srss", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_lbt_dl_req_pdu_type, { "LBT DL Request PDU Type", "nfapi.number_srss", FT_UINT16, BASE_DEC, VALS(nfapi_lbt_dl_req_pdu_type), 0x0, NULL, HFILL } }, +- { &hf_nfapi_lbt_dl_ind_pdu_type, { "LBT DL Indication PDU Type", "nfapi.number_srss", FT_UINT16, BASE_DEC, VALS(nfapi_lbt_dl_ind_pdu_type), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_pdsch_rnti, { "Number of PDSCH RNTI", "nfapi.number_pdsch_rnti", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_power_pcfich, { "Transmission Power PCFICH", "nfapi.transmission_power_pcfich", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_request_pdu_list, { "DL Config Request body", "nfapi.dl.config.request.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_request_pdu_list, { "UL Config Request body", "nfapi.ul.config.request.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_hi_dci0_request_pdu_list, { "HI DCI0 Request body", "nfapi.hi.dci0.config.request.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tx_request_pdu_list, { "Tx Request body", "nfapi.tx.request.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rx_indication_pdu_list, { "Rx Indication body", "nfapi.rx.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_indication_pdu_list, { "Harq Indication body", "nfapi.harq.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_crc_indication_pdu_list, { "CRC Indication body", "nfapi.crc.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sr_indication_pdu_list, { "SR Indication body", "nfapi.sr.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cqi_indication_pdu_list, { "CQI Indication body", "nfapi.cqi.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_preamble_indication_pdu_list, { "Preamble Indication body", "nfapi.preamble.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_indication_pdu_list, { "SRS Indication body", "nfapi.srs.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_lbt_dl_config_pdu_list, { "LBT DL Config Request body", "nfapi.lbt.dl.request.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_lbt_dl_indication_pdu_list, { "LBT DL Indicatoin body", "nfapi.lbt.dl.indication.pdu_list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_pdu_type, { "PDU Type", "nfapi.pdu.type", FT_UINT8, BASE_DEC, VALS(nfapi_dl_config_pdu_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdu_size, { "PDU size", "nfapi.pdu.size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_instance_length, { "Instance length", "nfapi.instance.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dlsch_pdu_rel8, { "DL CONFIG DLSCH PDU REL8", "nfapi.dl.config.dlsch.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_length, { "PDU length", "nfapi.pdu.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdu_index, { "PDU Index", "nfapi.pdu.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rnti, { "RNTI", "nfapi.rnti", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_resource_allocation_type, { "Resource Allocation Type", "nfapi.resource.allocation.type", FT_UINT8, BASE_DEC, VALS(resource_allocation_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_virtual_resource_block_assignment_flag, { "Virtual resource block assignment flag", "nfapi.resource.block.assignment.flag", FT_UINT8, BASE_DEC, VALS(local_distributed_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_resource_block_coding, { "Resource block coding", "nfapi.resource.block.coding", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_modulation, { "Modulation", "nfapi.modulation", FT_UINT8, BASE_DEC, VALS(modulation_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_redundancy_version, { "Redundancy version", "nfapi.redundancy.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transport_blocks, { "Transport blocks", "nfapi.transport.blocks", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transport_block_to_codeword_swap_flag, { "Transport block to codeword swap flag", "nfapi.transport.block.to.codeword.swap.flag", FT_UINT8, BASE_DEC, VALS(transport_block_to_codeword_swap_flag_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_scheme, { "Transmission scheme", "nfapi.transmission.scheme", FT_UINT8, BASE_DEC, VALS(transmission_scheme_vals), 0x0, "The MIMO mode used in the PDU", HFILL } }, +- { &hf_nfapi_ul_transmission_scheme, { "Transmission scheme", "nfapi.transmission.scheme", FT_UINT8, BASE_DEC, VALS(ul_transmission_scheme_vals), 0x0, "The MIMO mode used in the PDU", HFILL } }, +- { &hf_nfapi_number_of_layers, { "Number of layers", "nfapi.number.of.layers", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_subbands, { "Number of subbands", "nfapi.number.of.subbands", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_codebook_index, { "Codebook index", "nfapi.number.of.codebook.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ue_category_capacity, { "UE category capacity", "nfapi.ue.category.capacity", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pa, { "P-A", "nfapi.pa", FT_UINT8, BASE_DEC, VALS(pa_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_power_offset_index, { "Delta Power offset index", "nfapi.delta.power.offset.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_nprb, { "Nprb", "nfapi.nprb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_mode, { "Transmission Mode", "nfapi.transmission_nprb", FT_UINT8, BASE_DEC, VALS(transmission_mode_vals), 0x0, "Transmission mode associated with the UE", HFILL } }, +- { &hf_nfapi_prnti, { "P-RNTI", "nfapi.prnti", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mcs, { "MCS", "nfapi.mcs", FT_UINT8, BASE_DEC, VALS(pch_modulation_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_transport_blocks, { "Number of transport blocks", "nfapi.number_of_transport_blocks", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ue_mode, { "UE Mode", "nfapi.ue.mode", FT_UINT8, BASE_DEC, VALS(ue_mode_vals), 0x0, NULL, HFILL } }, +- { &hf_prs_bandwidth, { "PRS bandwidth", "nfapi.prs.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_prs_cyclic_prefix_type, { "PRS cyclic prefix type", "nfapi.prs.cyclic.prefix.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_prs_muting, { "PRS muting", "nfapi.prs.muting", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_num_bf_prb_per_subband, { "Num of BF PRB per Subband", "nfapi.num.bf.prb.per.subband", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_num_bf_vector, { "Num of BF Vector", "nfapi.num.bf.vector", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_resource_config, { "CSI-RS resource config", "nfapi.csi.rs.resource.config", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bf_vector_subband_index, { "BF Subband Index", "nfapi.num.bf.vector.subband.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bf_vector_num_antennas, { "BF Num of Antennas", "nfapi.num.bf.vector.bf.value", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bf_vector_bf_value, { "BF Value per Antenna", "nfapi.num.bf.vector.bf.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dlsch_pdu_rel9, { "DL CONFIG DLSCH PDU REL9", "nfapi.dl.config.dlsch.pdu.rel9", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_nscid, { "NSC id", "nfapi.nscid", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dlsch_pdu_rel10, { "DL CONFIG DLSCH PDU REL10", "nfapi.dl.config.dlsch.pdu.rel10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_flag, { "CSI RS Flag", "nfapi.csi.rs.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_subbands, { "Subbands", "nfapi.subbands", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bf_vectors, { "BF Vectors", "nfapi.bf.vectors", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bf_vector_antennas, { "Antennas", "nfapi.antennas", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_resource_config_r10, { "CSI RS resource config R10", "nfapi.csi.rs.resource_config_r10", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, { "CSI-RS Number of NZP configuration", "nfapi.csi.rs.num.of.nzp.configurations", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_number_if_nzp_configurations, { "CSI RS zero Tx Power Resource config bitmap R10", "nfapi.csi.rs.zero.tx.power.resource.config.bitmap.r10", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_resource_configs, { "CSR/RS Resource Configs", "nfapi.csi.rs.resource.configs", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_start, { "PDSCH_start", "nfapi.pdsch.start", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_drms_config_flag, { "DMRS Config flag", "nfapi.drms.config.flag", FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_drms_scrambling, { "DMRS Scrambling", "nfapi.drms.scrambling", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_config_flag, { "CSI Config flag", "nfapi.csi.config.flag", FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_scrambling, { "CSI Scrambling", "nfapi.csi.scrambling", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_re_mapping_flag, { "PDSCH RE mapping flag", "nfapi.pdsch.remapping.flag", FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_re_mapping_antenna_ports, { "PDSCH RE mapping antenna ports", "nfapi.pdsch.remapping.antenna.ports", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_re_mapping_freq_shift, { "PDSCH RE mapping freq shift", "nfapi.pdsch.remapping.freq.shift", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_alt_cqi_table_r12, { "altCQI-Table-r12", "nfapi.alt.cqi.table.r12", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_max_layers, { "MaxLayers", "nfapi.max.layers", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_dl_harq, { "N_DL_HARQ", "nfapi.n.dl.harq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dwpts_symbols, { "DwPTS Symbols", "nfapi.dwpts.symbols", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_initial_lbt_sf, { "Initial LBT SF", "nfapi.initial.lbt.sf", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ue_type, { "UE Type", "nfapi.ue.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_payload_type, { "PDSCH Payload Type", "nfapi.pdsch.payload.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_initial_transmission_sf, { "Initial transmission SF (io) ", "nfapi.init.tx.sf.io", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_req13_drms_table_flag, { "Rel-13-DMRS-tabe flag", "nfapi.r13.drms.table.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_resource_index, { "CSI-RS resource index", "nfapi.csi.rs.resource.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_class, { "Class", "nfapi.csi.rs.class", FT_UINT8, BASE_DEC, VALS(csi_rs_class_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_cdm_type, { "CDM Type", "nfapi.cdm.type", FT_UINT8, BASE_DEC, VALS(csi_rs_cdm_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_bf_vector, { "BF Vector", "nfapi.bf.vector", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_edpcch_prb_index, { "EPDCCH PRB index", "nfapi.edpcch.prb.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_resource_assignment_flag, { "EPDCCH Resource assignment flag", "nfapi.epdcch.resource.assignment.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_id, { "EPDCCH ID", "nfapi.epdcch.id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_start_symbol, { "EPDCCH Start Symbol", "nfapi.epdcch.start.symbol", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_num_prb, { "EPDCCH NumPRB", "nfapi.epdcch.num.prb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_epdcch_prbs, { "EPDCCH PRBs", "nfapi.epdcch.prbs", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_precoding_value, { "Precoding value", "nfapi.precoding.value", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mpdcch_narrowband, { "MPDCCH Narrowband", "nfapi.mpdcch.narrowband", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_prb_pairs, { "Number of PRB pairs", "nfapi.number.prb.pairs", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_resource_block_assignment, { "Resource Block Assignment", "nfapi.resource.block.assignement", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_start_symbol, { "Start symbol", "nfapi.start.symbol", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ecce_index, { "ECCE index", "nfapi.ecce.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ce_mode, { "Rel-13-DMRS-tabe flag", "nfapi.r13.drms.table.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_drms_scrabmling_init, { "DMRS scrambling init", "nfapi.drms.scrambling.init", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_reception_levels, { "PDSCH repetition levels", "nfapi.pdsch.repetition.levels", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_new_data_indicator, { "New data indicator", "nfapi.new.data.indicator", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tpmi_length, { "TPMI length", "nfapi.tpmi.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pmi_flag, { "PMI flag", "nfapi.pmi.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_resource_offset, { "HARQ resource offset", "nfapi.harq.resource.offset", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dci_subframe_repetition_number, { "DCI subframe repetition number", "nfapi.dci.subframe.repetition.number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_downlink_assignment_index_length, { "Downlink assignment index Length", "nfapi.dl.assignement.index.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_starting_ce_level, { "Starting CE Level", "nfapi.starting.ce.level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antenna_ports_and_scrambling_identity_flag, { "Antenna ports and scrambling identity flag", "nfapi.antenna.ports.and.scrambling.identity.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antenna_ports_and_scrambling_identity, { "Antenna ports and scrambling identity", "nfapi.antenna.ports.and.scrambling.identit", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_paging_direct_indication_differentiation_flag, { "Paging/Direct indication differentiation flag", "nfapi.paging.direct.indictation.differentiation.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_direct_indication, { "Direct indication", "nfapi.direct.indication", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_tx_antenna_ports, { "Number of TX Antenna ports", "nfapi.num.of.tx.antenna.ports.", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_precoding, { "Precoding", "nfapi.precodiing", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_bch_pdu_rel8, { "DL CONFIG BCH PDU Rel8", "nfapi.dl.config.bch.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_value_float, { "Value", "nfapi.value.float", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_power, { "Transmission Power", "nfapi.transmission_power", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_mch_pdu_rel8, { "DL CONFIG MCH PDU Rel8", "nfapi.dl.config.mch.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mbsfn_area_id, { "MBSFN Area id", "nfapi.mbsfn.area.id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_pch_pdu_rel8, { "DL CONFIG MCH PDU Rel8", "nfapi.dl.config.mch.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dci_dl_pdu_rel8, { "DL CONFIG DCI DL PDU Rel8", "nfapi.dl.config.mch.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dci_format, { "DCI format", "nfapi.dci.format", FT_UINT8, BASE_DEC, VALS(dci_format_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_cce_idx, { "CCE index", "nfapi.cce.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_aggregation_level, { "Aggregation level", "nfapi.aggregation.level", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mcs_1, { "MCS_1", "nfapi.mcs_1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mcs_2, { "MCS_2", "nfapi.mcs_2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_redundancy_version_1, { "Redundancy version_1", "nfapi.redundancy.version.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_redundancy_version_2, { "Redundancy version_2", "nfapi.redundancy.version.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_new_data_indicator_1, { "New data indicator_1", "nfapi.new.data.indicator.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_new_data_indicator_2 ,{ "New data indicator_2", "nfapi.new.data.indicator.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_process, { "HARQ process", "nfapi.harq.process", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tpmi, { "TPMI", "nfapi.tpmi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pmi, { "PMI", "nfapi.pmi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_precoding_information, { "Precoding information", "nfapi.precoding.information", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tpc, { "TPC", "nfapi.tpc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_downlink_assignment_index, { "Downlink assignment index", "nfapi.downlink.assignment.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ngap, { "Ngap", "nfapi.ngap", FT_UINT8, BASE_DEC, VALS(ngap_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_transport_block_size_index, { "Transport block size index", "nfapi.transport.block.size.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_downlink_power_offset, { "Downlink power offset", "nfapi.downlink.power.offset", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_allocate_prach_flag, { "Allocation PRACH flag", "nfapi.allocation.prach.flag", FT_UINT8, BASE_DEC, VALS(true_false_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_preamble_index, { "Preamble index", "nfapi.preamable.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prach_mask_index, { "PRACH mask index", "nfapi.prach.mask.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rnti_type, { "RNTI type", "nfapi.rnti.type", FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dci_dl_pdu_rel9, { "DL CONFIG DCI DL PDU Rel9", "nfapi.dl.config.mch.pdu.rel9", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mcch_flag, { "MCCH flag", "nfapi.mcch.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mcch_change_notification, { "MCCH change notification", "nfapi.mcch.change.notification", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_scrambling_identity, { "Scrambling identity", "nfapi.scrambling.identity", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_dci_dl_pdu_rel10, { "DL CONFIG DCI DL PDU Rel10", "nfapi.dl.config.mch.pdu.rel10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cross_carrier_scheduling_flag, { "Cross Carrier scheduling flag", "nfapi.cross.carrier.scheduling.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_carrier_indicator, { "Carrier Indicator", "nfapi.carrier.indicator", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_flag, { "SRS flag", "nfapi.srs.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_request, { "SRS request", "nfapi.srs.request", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antenna_ports_scrambling_and_layers, { "Antenna ports scrambling and layers", "nfapi.antenna.ports.scrambling.and.layers", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_total_dci_length_including_padding, { "Total DCI length including padding", "nfapi.total.dci.length.including.padding", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_dl_rb, { "N_DL_RB", "nfapi.n.dl.rb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_ul_rb, { "N_UL_RB", "nfapi.n.dl.rb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_ack_resource_offset, { "HARQ-ACK resource offset", "nfapi.harq.ack.resource.offset", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator, { "PDSCH RE Mapping and Quasi-Co-Location Indicator", "nfapi.pdsch.re.mapping", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_primary_cell_type, { "Primary cell type", "nfapi.primary.cell.type", FT_UINT8, BASE_DEC, VALS(primary_cells_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_dl_configuration_flag, { "UL/DL configuration flag", "nfapi.ul.dl.configuration.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_ul_dl_configurations, { "Number of UL/DL configurations", "nfapi.number.ul.dl.configurations", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_dl_configuration_index, { "UL/DL configuration indication", "nfapi.ul.dl.configuration.indication", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_end_partial_sf_flag, { "LAA end partial SF flag", "nfapi.laa.end.partial.sf.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_laa_end_partial_sf_configuration, { "LAA end partial SF configuration", "nfapi.laa.end.partial.sf.configuration", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_codebooksize_determination_r13, { "Codebook Size Determination R13", "nfapi.codebook.size.determination.r13", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rel13_drms_table_flag, { "Rel-13-DMRS-tabe flag", "nfapi.drms.table.flag.r13", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pscch_resource, { "PSCCH Resource", "nfapi.pscch.resource", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_time_resource_pattern, { "Time resource pattern", "nfapi.time.resource.pattern", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mpdcch_transmission_type, { "MPDCCH transmission type", "nfapi.mpdcch.transmission.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_drms_scrambling_init, { "DMRS scrambling init", "nfapi.drms.scrambling.init", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pusch_repetition_levels, { "PUSCH repetition levels", "nfapi.pusch.repetition.levels", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_hopping_flag, { "Frequency hopping flag", "nfapi.frequency.hopping.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_request, { "CSI request", "nfapi.csi.request", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dai_presence_flag, { "DAI presence flag", "nfapi.dia.presence.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_total_dci_length_include_padding, { "Total DCI length including padding", "nfapi.total.dci.length.including.padding", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_prs_pdu_rel9, { "DL CONFIG PRS PDU Rel9", "nfapi.dl.config.prs.pdu.rel9", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prs_bandwidth, { "PRS Bandwidth", "nfapi.prs.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_prs_cyclic_prefix_type, { "PRS cyclic prefix type", "nfapi.prs.cyclic.prefix.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_config_csi_rs_pdu_rel10, { "DL CONFIG CSI RS PDU Rel10", "nfapi.dl.config.csi.rs.pdu.rel10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_rs_antenna_port_count_r10, { "Antenna port count r10", "nfapi.csi.rs.antenna.port.count.r10", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_request_body, { "UL Config Request body", "nfapi.ul.config.request.body", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_pdu_type, { "UL Config PDU Type", "nfapi.ul.config.pdu.type", FT_UINT8, BASE_DEC, VALS(nfapi_ul_config_pdu_type_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_rach_prach_frequency_resources, { "RACH PRACH Frequency resources", "nfapi.rach.prach.frequency.resources", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_present, { "SRS present", "nfapi.srs.present", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_harq_buffer_pdu, { "HARQ Buffer PDU", "nfapi.ul.config.harq.buffer.pdu", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_ue_information_rel8, { "UE Information Rel 8", "nfapi.ul.config.ue.information.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_handle, { "Handle", "nfapi.handle", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_sr_information_pdu_rel8, { "SR Information Rel 8", "nfapi.ul.config.sr.information.pdu.rel8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_index, { "PUCCH Index", "nfapi.pucch.index", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_size, { "Size", "nfapi.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_resource_block_start, { "Resource block start", "nfapi.resource.block.start", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_resource_blocks, { "Number of resource blocks", "nfapi.resource.blocks", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cyclic_shift_2_for_drms, { "Cyclic Shift 2 for DRMS", "nfapi.cyclic.shift.2.for.drms", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_hopping_enabled_flag, { "Frequency hopping enabled flag", "nfapi.frequency.hopping.enabled.flag", FT_UINT8, BASE_DEC, VALS(hopping_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_hopping_bits, { "Frequency hopping bits", "nfapi.frequency.hopping.bits", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_new_data_indication, { "New Data inidication", "nfapi.new.data.indication", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_process_number, { "HARQ Process number", "nfapi.harq.process.number", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_tx_mode, { "UL Tx Mode", "nfapi.ul.tx.mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_current_tx_nb, { "Current Tx nb", "nfapi.current.tx.nb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_srs, { "N SRS", "nfapi.n.srs", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_disable_sequence_hopping_flag, { "Disable seqeunce hopping flag", "nfapi.disable.sequence.hopping.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_virtual_cell_id_enabled_flag, { "Virtual cell ID enabled flag", "nfapi.virtual.cell.id.enabled.flag", FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_npusch_identity, { "nPUSCH Identity", "nfapi.npusch.identity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ndrms_csh_identity, { "nDMRS-CSH Identity", "nfapi.ndrms.csh.identity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_total_number_of_repetitions, { "Total Number of repetitions", "nfapi.total.number.of.repetitions", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_repetition_number, { "Repetition Number", "nfapi.repetition.number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_initial_sf_io, { "Initial transmission SF (io) ", "nfapi.initial.sf.io", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_empty_symbols_due_to_retunning, { "Empy symbols due to re-tunning", "nfapi.empty.symbols.due.to.retunning", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_ri_pmi_size_2, { "DL CQI/PMI/RI size 2", "nfapi.dl.cqi.ri.pmi.size.2", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_size_2, { "HARQ Size 2", "nfapi.harq.size2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_offset_harq_2, { "Delta Offset HARQ 2", "nfapi.delta.offset.harq.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_starting_prb, { "Starting PRB", "nfapi.starting.prb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antenna_port, { "Antenna Port", "nfapi.antenna.port", FT_UINT8, BASE_DEC, VALS(antenna_ports_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_combs, { "Number of Combs", "nfapi.num.of.combs", FT_UINT8, BASE_DEC, VALS(combs_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_npucch_identity, { "nPUCCH Identity", "nfapi.npucch.identity", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_empty_symbols, { "Empty symbols", "nfapi.empty.symbols", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_csi_mode, { "CSI_mode", "nfapi.csi.mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_pmi_size_2, { "DL CQI/PMI Size 2", "nfapi.dl.cqi.pmi.size.2", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_statring_prb, { "Starting PRB", "nfapi.starting.prb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cdm_index, { "cdm_Index", "nfapi.cdm.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_nsrs, { "N srs", "nfapi.n.srs", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_num_ant_ports, { "Num_ant_ports", "nfapi.num.ant.port", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_2_0, { "n_PUCCH_2_0", "nfapi.n.pucch.2.0", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_2_1, { "n_PUCCH_2_1", "nfapi.n.pucch.2.1", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_2_2, { "n_PUCCH_2_2", "nfapi.n.pucch.2.2", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_2_3, { "n_PUCCH_2_3", "nfapi.n.pucch.2.3", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_pmi_size_rank_1, { "DL CQI PMI size rank 1", "nfapi.dl.cqi.pmi.size.rank.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_pmi_size_rank_greater_1, { "DL CQI PMI size rank greater 1", "nfapi.dl.cqi.pmi.size.rank.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ri_size, { "RI size", "nfapi.ri.size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_offset_cqi, { "Delta offset cqi", "nfapi.delta.offset.cqi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_offset_ri, { "Delta offset ri", "nfapi.delta.offset.ri", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_size, { "HARQ size", "nfapi.harq_size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_delta_offset_harq, { "Delta offset HARQ", "nfapi.delta.offset.harq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ack_nack_mode, { "ACK NACK mode", "nfapi.ack.nack.mode", FT_UINT8, BASE_DEC, VALS(nfapi_ack_nack_mode_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_srs_initial, { "N srs initial", "nfapi.n.srs.initial", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_initial_number_of_resource_blocks, { "Initial number of resource blocks", "nfapi.initial.number.of.resource.blocks", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_pmi_size, { "DL cqi pmi size", "nfapi.dl.cqi.pmi.size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_report_type, { "Report type", "nfapi.report.type", FT_BOOLEAN, 8, TFS(&nfapi_csi_report_type_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cqi_ri_pmi_size, { "DL CQI RI PMI size", "nfapi.dl.cqi.ri.pmi.size", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_control_type, { "Control type", "nfapi.control.type", FT_BOOLEAN, 8, TFS(&nfapi_control_type_string_name), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_cc, { "Number of cc", "nfapi.number.of.cc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_pucch_resource, { "Number of PUCCH Resource", "nfapi.number.of.pucch.resource", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pucch_index_p1, { "PUCCH Index P1", "nfapi.pucch.index.p1", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_1_0, { "N PUCCH 1 0", "nfapi.n.pucch.1.0", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_1_1, { "N PUCCH 1 1", "nfapi.n.pucch.1.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_1_2, { "N PUCCH 1 2", "nfapi.n.pucch.1.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_n_pucch_1_3, { "N PUCCH 1 3", "nfapi.n.pucch.1.3", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_bandwidth, { "SRS Bandwidth", "nfapi.srs.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_domain_position, { "Frequency Domain position", "nfapi.frequency.domain.position", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_srs_hopping_bandwidth, { "SRS hopping bandwidth", "nfapi.srs.hopping.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_transmission_comb, { "Transmission comb", "nfapi.transmission.comb", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_i_srs, { "I SRS", "nfapi.i.srs", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sounding_reference_cyclic_shift, { "Sounding reference cyclic shift", "nfapi.sounding.reference.cyclic.shift", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antenna_ports, { "Antenna port(s)", "nfapi.antenna.port", FT_UINT8, BASE_DEC, VALS(nfapi_antenna_port_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_srs_pdu_rel10, { "SRS PDU Rel 10", "nfapi.srs.pdu.rel.10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_srs_pdu_rel8, { "SRS PDU Rel 8", "nfapi.srs.pdu.rel.8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_harq_information_rel9_fdd, { "HARQ information Rel 9 FDD", "nfapi.harq.information.rel.9.fdd", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_harq_information_rel8_fdd, { "HARQ information Rel 8 FDD", "nfapi.harq.information.rel.8.fdd", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_harq_information_rel10_tdd, { "HARQ information Rel 10 TDD", "nfapi.harq.information.rel.10.tdd", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_sr_information_rel10, { "SR information Rel 10", "nfapi.sr.information.rel.10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_sr_information_rel8, { "SR information Rel 8", "nfapi.sr.information.rel.8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_cqi_information_rel10, { "CQI information Rel 10", "nfapi.cqi.information.rel.10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_cqi_information_rel8, { "CQI information Rel 8", "nfapi.cqi.information.rel.8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_initial_transmission_parameters_rel8, { "Initial transmission parameters Rel 8", "nfapi.initial.transmission.parameters.rel.8", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_config_ulsch_harq_information_rel10, { "HARQ Information Rel 10", "nfapi.harq.information.rel.10", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdu_length, { "PDU length", "nfapi.pdu.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_num_segments, { "Num segments", "nfapi.num.segments", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_segment_length, { "Segment length", "nfapi.segment.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_segment_data, { "Segment data", "nfapi.segment.data", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_crc_indication_body, { "CRC Indication Body", "nfapi.crc_indication_body", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_crc_flag, { "CRC flag", "nfapi.crc.flag", FT_BOOLEAN, 8, TFS(&crc_flag_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_hi_pdus, { "Number of HI Pdu's", "nfapi.number_of_hi_pdus", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_dci_pdus, { "Number of DCI Pdu's", "nfapi.number_of_dci_pdus", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pdu_type, { "PDU Type", "nfapi.pdu_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_hi_value, { "HI Value", "nfapi.hi_value", FT_BOOLEAN, 8, TFS(&hi_value_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_i_phich, { "i phich", "nfapi.i_phich", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_flag_tb2, { "Flag TB2", "nfapi.flag_tb2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_hi_value_2, { "HI Value 2", "nfapi.hi_value_2", FT_BOOLEAN, BASE_NONE, TFS(&hi_value_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_ue_tx_antenna_selection, { "UE Tx Antenna selection", "nfapi.ue_tx_antenna_selection", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cqi_csi_request, { "cqi csi request", "nfapi.cqi_csi_request", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_index, { "UL index", "nfapi.ul_index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_assignment_index, { "DL Assignment index", "nfapi.dl_assignment_index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tpc_bitmap, { "TPC bitmap", "nfapi.tpc_bitmap", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_antenna_ports, { "Number of antenna ports", "nfapi.number.of.antenna.ports", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_size_of_cqi_csi_feild, { "Size of cqi csi feild", "nfapi.size.of.cqi.csi.feild", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_new_data_indication_two, { "New data indicatipon 2", "nfapi.new.data.indication.two", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_resource_allocation_flag, { "Resource allocation flag", "nfapi.resource.allocation.flag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_node_sync, { "DL Node Sync", "nfapi.dl.node.sync", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_node_sync_t1, { "DL Node Sync t1", "nfapi.dl.node.sync.t1", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_node_sync_delta_sfn_sf, { "DL Node Sync Delta SFN SF", "nfapi.dl.node.sync.delta_sfn_sf", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_dl_cyclic_prefix_type, { "DL Cyclic Prefix type", "nfapi.dl.cyclic.prefix.type", FT_BOOLEAN, 8, TFS(&cyclic_prefix_type_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_cyclic_prefix_type, { "UL Cyclic Prefix type", "nfapi.ul.cyclic.prefix.type", FT_BOOLEAN, 8, TFS(&cyclic_prefix_type_strname), 0x0, NULL, HFILL } }, +- { &hf_nfapi_downlink_channel_bandwidth, { "Downlink Channel Bandwidth", "nfapi.dl.channel.bandwidth", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uplink_channel_bandwidth, { "Uplink Channel Bandwidth", "nfapi.ul.channel_bandwidth", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_tx_antenna_ports, { "Tx Antenna Ports", "nfapi.tx.antenna.ports", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rx_antenna_ports, { "Tx Antenna Ports", "nfapi.rx.antenna.ports", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_node_sync, { "UL Node Sync", "nfapi.ul.node.sync", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_node_sync_t1, { "UL Node Sync t1", "nfapi.ul.node.sync.t1", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_node_sync_t2, { "UL Node Sync t2", "nfapi.ul.node.sync.t2", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_node_sync_t3, { "UL Node Sync t3", "nfapi.ul.node.sync.t3", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pb, { "P-B", "nfapi.pb.allocation", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_last_sfn_sf, { "Last SFN/SF", "nfapi.timing.info.last.sfn.sf", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_time_since_last_timing_info, { "Time since last Timing Info", "nfapi.timing.info.time.since.last.timing.info", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_dl_config_jitter, { "DL Config Jitter", "nfapi.timing.info.dl.config.jitter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_tx_request_jitter, { "Tx Request Jitter", "nfapi.timing.info.tx.req.jitter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_ul_config_jitter, { "UL Config Jitter", "nfapi.timing.info.ul.config.jitter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_hi_dci0_jitter, { "HI_DCI0 Jitter", "nfapi.timing.info.hi.dci0.jitter", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_dl_config_latest_delay, { "DL Config Latest Delay", "nfapi.timing.info.dl.config.latest.delay", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_tx_request_latest_delay, { "Tx Request Latest Delay", "nfapi.timing.info.tx.request.latest.delay", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_ul_config_latest_delay, { "UL Config Latest Delay", "nfapi.timing.info.ul.config.latest.delay", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_hi_dci0_latest_delay, { "HI_DCI0 Latest Delay", "nfapi.timing.info.hi.dci0.latest.delay", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_dl_config_earliest_arrival, { "DL Config Earliest Arrival", "nfapi.timing.info.dl.config.earliest.arrival", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_tx_request_earliest_arrival, { "Tx Request Earliest Arrival", "nfapi.timing.info.tx.request.earliest.arrival", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_ul_config_earliest_arrival, { "UL Config Earliest Arrival", "nfapi.timing.info.ul.config.earliest.arrival", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_hi_dci0_earliest_arrival, { "HI_DCI0 Earliest Arrival", "nfapi.timing.info.hi.dci0.earliest.arrival", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pcfich_power_offset, { "PCFICH Power Offset", "nfapi.pcfich.power.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_window, { "NFAPI Timing window", "nfapi.timing.window", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_mode, { "Timing Info mode", "nfapi.timing.info.mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_info_period, { "Timing info period", "nfapi.timing.info.period", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_max_transmit_power, { "Max transmit power", "nfapi.max.transmit.power", FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uint8_tag, { "uint8 tag", "nfapi.uint8.tag", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uint16_tag, { "uint16 tag", "nfapi.uint16.tag", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_mode, { "Mode", "nfapi.harq.mode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_ack_nack, { "Number of ACK/NACK", "nfapi.uint16.tag", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_data_value_0, { "Value 0", "nfapi.harq.value.0", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_data_value_1, { "Value 1", "nfapi.harq.value.1", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_data_value_2, { "Value 2", "nfapi.harq.value.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_data_value_3, { "Value 3", "nfapi.harq.value.3", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_tb_1, { "HARQ TB1", "nfapi.harq.tb.", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_tb_2, { "HARQ TB2", "nfapi.harq.tb.2", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_tb_n, { "HARQ TB_N", "nfapi.harq.tb.n", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_cqi, { "UL_CQI", "nfapi.ul.cqi", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_channel, { "Channel", "nfapi.channel", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_data_offset, { "Data Offset", "nfapi.data.offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ri, { "RI", "nfapi.ri", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_ack_nack_data, { "HARQ Ack/Nack Data", "nfapi.harq.ack.nack.data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_harq_data, { "HARQ TB Data", "nfapi.harq.tb.data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_cc, { "CC", "nfapi.cc", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rbs, { "RBs", "nfapi.rbs", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_antennas, { "Physical Antennas", "nfapi.physical.antennas", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_advance, { "Timing Advance", "nfapi.timing.advance", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timing_advance_r9, { "Timing Advance R9", "nfapi.timing.advance.r9", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_cc_reported, { "Number of CC reported", "nfapi.number.of.cc.reported", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_preamble, { "Preamble", "nfapi.preamble", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rach_resource_type, { "RACH resource type", "nfapi.rach.resource.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_doppler_estimation, { "Doppler estimation", "nfapi.doppler.estimation", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rb_start, { "RB Start", "nfapi.rb.start", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_snr, { "SNR", "nfapi.snr", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_up_pts_symbol, { "UpPTS Symbol", "nfapi.uppts.symbol", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_prb_per_subband, { "numPRBperSubband", "nfapi.num.prb.per.subband", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_antennas, { "numAntennas", "nfapi.num.antennas", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_subband_index, { "subbandIndex", "nfapi.subband.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_channel_coefficient, { "Channel", "nfapi.channel.coefficient", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_ul_rtoa, { "UL_RTOA", "nfapi.ul.rtoa", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_frequency_band_indicator, { "Frequency Band Indicator", "nfapi.frequency.band.indicator", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_measurement_period, { "Measurement Period", "nfapi.measurement.period", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bandwidth, { "Bandwidth", "nfapi.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_timeout, { "Timeout", "nfapi.timeout", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_earfcns, { "Number of EARFCNs", "nfapi.number.of.earfcns", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_earfcn_list, { "EARFCN List", "nfapi.earfcn.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uarfcn, { "UARFCN", "nfapi.uarfcn", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_uarfcns, { "Number of UARFCNs", "nfapi.number.of.uarfcn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_uarfcn_list, { "UARFCN List", "nfapi.uarfcn.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_arfcn, { "ARFCN", "nfapi.arfcn", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_arfcn_direction, { "Direction", "nfapi.arfcn.direction", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_arfcns, { "Number of ARFCNs", "nfapi.number.of.arfcn", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_arfcn_list, { "ARFCN List", "nfapi.arfcn.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rssi, { "RSSI", "nfapi.rssi", FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_rssi, { "Number of RSSI", "nfapi.number.of.rssi", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rssi_list, { "RSSI List", "nfapi.rssi.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pci, { "PCI", "nfapi.pci", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_measurement_bandwidth, { "Measurement Bandwidth", "nfapi.measurement.bandwidth", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_exhaustive_search, { "Exhaustive Search", "nfapi.exhaustive.search", FT_UINT8, BASE_DEC, VALS(exhustive_search_vals), 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_pci, { "Number of PCI", "nfapi.number.of.pci", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pci_list, { "PCI List", "nfapi.pci.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_psc, { "PSC", "nfapi.psc", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_psc, { "Number of PSC", "nfapi.number.of.psc", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_psc_list, { "PCS List", "nfapi.psc.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rsrp, { "RSRP", "nfapi.rsrp", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rsrq, { "RSRQ", "nfapi.rsrq", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_lte_cells_found, { "Number of LTE Cells Found", "nfapi.number.of.lte.cells.found", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_lte_cells_found_list, { "LTE Cells Found List", "nfapi.lte.cells.found.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rscp, { "RSCP", "nfapi.rscp", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_enco, { "EcNo", "nfapi.ecno", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_utran_cells_found, { "Number of UTRAN Cells Found", "nfapi.number.of.utran.cells.found", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_utran_cells_found_list, { "UTRAN Cells Found List", "nfapi.utran.cells.found.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_bsic, { "BSIC", "nfapi.bsic", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rxlev, { "RxLev", "nfapi.rxlev", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_rxqual, { "RxQual", "nfapi.rxqual", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sfn_offset, { "SFN Offset", "nfapi.sfn.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_geran_cells_found, { "Number of GSM Cells Found", "nfapi.number.of.geran.cells.found", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_geran_cells_found_list, { "GERAN Cells Found List", "nfapi.geran.cells.found.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_tx_antenna, { "Number of Tx Antenna", "nfapi.number.of.tx.antenna", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mib_length, { "MIB Length", "nfapi.mib.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_mib, { "MIB", "nfapi.mib", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_phich_configuration, { "PHICH Configuration", "nfapi.phich.configuration", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_retry_count, { "retryCount", "nfapi.retry.count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sib1, { "SIB1", "nfapi.sib1", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si_periodicity, { "SI Periodicity", "nfapi.si.periodicity", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si_index, { "SI Index", "nfapi.si.index", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_number_of_si_periodicity, { "Number of SI Periodicity", "nfapi.number.of.si.periodicity", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si_periodicity_list, { "SI Periodicity List", "nfapi.si.periodicity.list", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si_window_length, { "SI Window Length", "nfapi.si.window.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sib_type, { "SIB Type", "nfapi.sib.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sib_len, { "SIB Length", "nfapi.sib.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_sib, { "SIB", "nfapi.sib", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si_len, { "SI Length", "nfapi.si.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_si, { "SI", "nfapi.si", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_search_state, { "State", "nfapi.state", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- { &hf_nfapi_pnf_broadcast_state, { "State", "nfapi.state", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }, +- +- }; +- +- /* Setup protocol subtree array */ +- static gint *ett[] = { +- &ett_nfapi_message_tree, +- &ett_nfapi_p4_p5_message_header, +- &ett_nfapi_p7_message_header, +- &ett_nfapi_tlv_tree, +- &ett_nfapi_tl, +- &ett_nfapi_pnf_param_response, +- &ett_nfapi_pnf_phy_rf_config, +- &ett_nfapi_pnf_phy_rf_config_instance, +- &ett_nfapi_pnf_phy, +- &ett_nfapi_pnf_phy_rel10, +- &ett_nfapi_pnf_phy_rel11, +- &ett_nfapi_pnf_phy_rel12, +- &ett_nfapi_pnf_phy_rel13, +- &ett_nfapi_pnf_rf, +- &ett_nfapi_phy_state, +- &ett_nfapi_rf_bands, +- &ett_nfapi_bf_vectors, +- &ett_nfapi_csi_rs_bf_vector, +- &ett_nfapi_csi_rs_resource_configs, +- &ett_nfapi_tx_antenna_ports, +- &ett_nfapi_harq_ack_nack_data, +- &ett_nfapi_harq_data, +- &ett_nfapi_cc, +- &ett_nfapi_rbs, +- &ett_nfapi_antennas, +- &ett_nfapi_epdcch_prbs, +- &ett_nfapi_dl_config_request_body, +- &ett_nfapi_dl_config_request_pdu_list, +- &ett_nfapi_ul_config_request_pdu_list, +- &ett_nfapi_hi_dci0_request_pdu_list, +- &ett_nfapi_tx_request_pdu_list, +- &ett_nfapi_rx_indication_pdu_list, +- &ett_nfapi_harq_indication_pdu_list, +- &ett_nfapi_crc_indication_pdu_list, +- &ett_nfapi_sr_indication_pdu_list, +- &ett_nfapi_cqi_indication_pdu_list, +- &ett_nfapi_preamble_indication_pdu_list, +- &ett_nfapi_srs_indication_pdu_list, +- &ett_nfapi_lbt_dl_config_pdu_list, +- &ett_nfapi_lbt_dl_indication_pdu_list, +- &ett_nfapi_dl_config_request_dlsch_pdu_rel8, +- &ett_nfapi_dl_config_request_dlsch_pdu_rel9, +- &ett_nfapi_dl_config_request_dlsch_pdu_rel10, +- &ett_nfapi_dl_config_bch_pdu_rel8, +- &ett_nfapi_dl_config_mch_pdu_rel8, +- &ett_nfapi_dl_config_pch_pdu_rel8, +- &ett_nfapi_dl_config_dci_dl_pdu_rel8, +- &ett_nfapi_dl_config_dci_dl_pdu_rel9, +- &ett_nfapi_dl_config_dci_dl_pdu_rel10, +- &ett_nfapi_dl_config_prs_pdu_rel9, +- &ett_nfapi_dl_config_csi_rs_pdu_rel10, +- &ett_nfapi_subbands, +- &ett_nfapi_precoding, +- &ett_nfapi_bf_vector_antennas, +- &ett_nfapi_ul_config_request_body, +- &ett_nfapi_ul_config_harq_buffer_pdu, +- &ett_nfapi_ul_config_ue_information_rel8, +- &ett_nfapi_ul_config_sr_information_pdu_rel8, +- &ett_nfapi_ul_config_ulsch_pdu_rel8, +- &ett_nfapi_ul_config_ulsch_pdu_rel10, +- &ett_nfapi_ul_config_cqi_ri_information_rel8, +- &ett_nfapi_ul_config_cqi_ri_information_rel9, +- &ett_nfapi_ul_config_ulsch_harq_information_rel10, +- &ett_nfapi_ul_config_initial_transmission_parameters_rel8, +- &ett_nfapi_ul_config_cqi_information_rel8, +- &ett_nfapi_ul_config_cqi_information_rel10, +- &ett_nfapi_ul_config_sr_information_rel8, +- &ett_nfapi_ul_config_sr_information_rel10, +- &ett_nfapi_ul_config_harq_information_rel10_tdd, +- &ett_nfapi_ul_config_harq_information_rel8_fdd, +- &ett_nfapi_ul_config_harq_information_rel9_fdd, +- &ett_nfapi_ul_config_srs_pdu_rel8, +- &ett_nfapi_ul_config_srs_pdu_rel10, +- &ett_nfapi_crc_indication_body, +- +- &ett_nfapi_earfcn_list, +- &ett_nfapi_uarfcn_list, +- &ett_nfapi_arfcn_list, +- &ett_nfapi_rssi_list, +- &ett_nfapi_pci_list, +- &ett_nfapi_psc_list, +- &ett_nfapi_lte_cells_found_list, +- &ett_nfapi_utran_cells_found_list, +- &ett_nfapi_geran_cells_found_list, +- &ett_nfapi_si_periodicity_list, +- +- /* for fragmentation support*/ +- &ett_msg_fragment, +- &ett_msg_fragments +- }; +- +- static ei_register_info ei[] = +- { +- { &ei_power_invalid, { "nfapi.power.invalid", PI_PROTOCOL, PI_ERROR, "Tx Power range invalid [0 - 10000]", EXPFILL } }, +- { &ei_ref_sig_power_invalid, { "nfapi.ref_sig_power.invalid", PI_PROTOCOL, PI_ERROR, "Ref Sig Power range invalid [0 - 255]", EXPFILL }}, +- { &ei_invalid_range, { "nfapi.invalid.range", PI_PROTOCOL, PI_ERROR, "Out of valid range. Todo create more specific error", EXPFILL } }, +- }; +- +- +- +- expert_module_t* expert_nfapi; +- +- /* Register protocol */ +- proto_nfapi = proto_register_protocol("Nfapi", "NFAPI", "nfapi"); +- +- expert_nfapi = expert_register_protocol(proto_nfapi); +- +- expert_register_field_array(expert_nfapi, ei, array_length(ei)); +- +- proto_register_field_array(proto_nfapi, hf, array_length(hf)); +- proto_register_subtree_array(ett, array_length(ett)); +- +- reassembly_table_register(&ul_p7_reassemble_table, &addresses_ports_reassembly_table_functions); +- reassembly_table_register(&dl_p7_reassemble_table, &addresses_ports_reassembly_table_functions); +- +- register_dissector("nfapi", dissect_nfapi, proto_nfapi); +- +-} +- +-// ----------------------------------------------------------------------------| +- +-void proto_reg_handoff_nfapi(void) +-{ +- static dissector_handle_t nfapi_handle; +- +- nfapi_handle = create_dissector_handle(dissect_nfapi, proto_nfapi); +- +- dissector_add_for_decode_as("sctp.port", nfapi_handle); +- +- dissector_add_uint("udp.port", 41700, nfapi_handle); +- +-} ++ ++ default: ++ { ++ if (msg_id >= 0x112 && msg_id <= 0x017f) ++ { ++ // reserved P5 message ++ } ++ else if (msg_id >= 0x183 && msg_id <= 0x01ff) ++ { ++ // reserved P7 message ++ } ++ else if (msg_id >= 0x0200 && msg_id <= 0x02ff) ++ { ++ // reserved P4 message ++ } ++ else if (msg_id >= 0x0300 && msg_id <= 0x03ff) ++ { ++ // reserved vendor extentions ++ } ++ ++ break; ++ } ++ }; ++ ++ ptvcursor_pop_subtree(ptvc); ++ ptvcursor_free(ptvc); ++ ++ return tvb_captured_length(tvb); ++} ++ ++static void nfapi_tag_vals_fn(gchar* s, guint32 v) ++{ ++ const tlv_t* tlv = look_up_tlv(v); ++ if (tlv != 0) ++ { ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%s (0x%x)", tlv->name, v); ++ } ++ else ++ { ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%s (0x%x)", "Unknown", v); ++ } ++} ++static void neg_pow_conversion_fn(gchar* s, guint8 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%d dB (%d)", ((gint16)v * (-1)), v); ++} ++static void power_offset_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", (((float)v * 0.001) - 6.0), v); ++} ++static void reference_signal_power_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", (((float)v * 0.25) - 63.75), v); ++} ++static void laa_threshold_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", (float)(v * -100.00), v); ++} ++static void max_transmit_power_2_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", ((float)v * 0.1) - 10.0, v); ++} ++static void max_transmit_power_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", ((float)v * 0.1), v); ++} ++static void sfn_sf_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%d/%d (%d)", v >> 0x4, v & 0x000F, v); ++} ++static void rssi_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", ((float)v * 0.1), v); ++} ++static void dl_rs_tx_pow_measment_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", ((float)v * 0.1), v); ++} ++ ++static void ul_cqi_conversion_fn(gchar* s, guint16 v) ++{ ++ g_snprintf(s, ITEM_LABEL_LENGTH, "%.2f dB (%d)", (((float)v / 2 ) - 64.0), v); ++} ++ ++// ----------------------------------------------------------------------------| ++ ++void proto_register_nfapi(void) ++{ ++ static hf_register_info hf[] = ++ { ++ { &hf_msg_fragments, ++ { "Message fragments", "nfapi.fragments", ++ FT_NONE, BASE_NONE, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment, ++ { "Message fragment", "nfapi.fragment", ++ FT_FRAMENUM, BASE_NONE, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_overlap, ++ { "Message fragment overlap", "nfapi.fragment.overlap", ++ FT_BOOLEAN, 0, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_overlap_conflicts, ++ { "Message fragment overlapping with conflicting data", "nfapi.fragment.overlap.conflicts", ++ FT_BOOLEAN, 0, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_multiple_tails, ++ { "Message has multiple tail fragments", "nfapi.fragment.multiple_tails", ++ FT_BOOLEAN, 0, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_too_long_fragment, ++ { "Message fragment too long", "nfapi.fragment.too_long_fragment", ++ FT_BOOLEAN, 0, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_error, ++ { "Message defragmentation error", "nfapi.fragment.error", ++ FT_FRAMENUM, BASE_NONE, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_fragment_count, ++ { "Message fragment count", "nfapi.fragment.count", ++ FT_UINT32, BASE_DEC, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_reassembled_in, ++ { "Reassembled in", "nfapi.reassembled.in", ++ FT_FRAMENUM, BASE_NONE, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_msg_reassembled_length, ++ { "Reassembled length", "nfapi.reassembled.length", ++ FT_UINT32, BASE_DEC, NULL, 0x00, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_p4_p5_message_header_phy_id, ++ { "PHY ID", "nfapi.p4_p5_message_header.phy_id", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Within the PNF Device, the unique identity of the PHY instance as assigned through the PNF_CONFIG.request", HFILL } ++ }, ++ { &hf_nfapi_p4_p5_message_header_message_id, ++ { "Message ID", "nfapi.p4_p5_message_header.message_id", ++ FT_UINT16, BASE_HEX_DEC, VALS(message_id_vals), 0x0, ++ "The nFAPI message identity", HFILL } ++ }, ++ { &hf_nfapi_p4_p5_message_header_message_length, ++ { "Message Length", "nfapi.p4_p5_message_header.message_length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The length in bytes of the message including the header", HFILL } ++ }, ++ { &hf_nfapi_p4_p5_message_header_spare, ++ { "Spare", "nfapi.p4_p5_message_header.spare", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Reserved field to be populated with zeros on transmission and ignored on reception", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_phy_id, ++ { "Phy ID", "nfapi.p7_message_header.phy_id", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Within the PNF Device, the unique identity of the PHY instance as assigned through the PNF_CONFIG.request", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_message_id, ++ { "Message ID", "nfapi.p7.message_header.message_id", ++ FT_UINT16, BASE_HEX_DEC, VALS(message_id_vals), 0x0, ++ "The nFAPI message identity", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_message_length, ++ { "Message Length", "nfapi.p7_message_header.message_length", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_byte_bytes, 0x0, ++ "The length in bytes of the message segment including the header", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_m, ++ { "M", "nfapi.p7_message_header.m_segment_sequence", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "A More flag indicating there are more segments to follow to complete the entire message", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_segment, ++ { "Segment Number", "nfapi.p7_message_header.m_segment_sequence", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The segment number starting at zero and incrementing by one between each segment", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_sequence_number, ++ { "Sequence Number", "nfapi.p7_message_header.m_segment_sequence", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The incrementing sequence number for all complete messages over the P7 nFAPI interface per PHY instance", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_checksum, ++ { "Checksum", "nfapi.p7_message_header.checksum", ++ FT_UINT32, BASE_HEX_DEC, NULL, 0x0, ++ "The checksum of the whole message segment (including header) as calculated using " ++ "the CRC32c algorithm following the same method as the SCTP protocol defined in IETF RFC 4960 " ++ "The Checksum is optional to populate and must be filled with zero's when not used", HFILL } ++ }, ++ { &hf_nfapi_p7_message_header_transmit_timestamp, ++ { "Transmit Timestamp", "nfapi.p7_message_header.timestamp", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The offset from VNF SFN/SF 0/0 time reference of the message transmission at the transport layer, in microseconds, with a range of 0 to 10239999", HFILL } ++ }, ++ { &hf_nfapi_tl_tag, ++ { "TLV Tag", "nfapi.tl_tag", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(nfapi_tag_vals_fn), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_tl_length, ++ { "TLV Length", "nfapi.tl_length", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_byte_bytes, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_error_code, ++ { "Error Code", "nfapi.error.code", ++ FT_UINT8, BASE_DEC, VALS(nfapi_error_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_p4_error_code, ++ { "Error Code", "nfapi.p4_error.code", ++ FT_UINT8, BASE_DEC, VALS(nfapi_p4_error_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_rat_type, ++ { "RAT Type", "nfapi.rat_type", ++ FT_UINT8, BASE_DEC, VALS(nfapi_rat_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_num_tlv, ++ { "Number of TLV", "nfapi.param.response.num_tlv", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_phy_state, ++ { "Phy state value", "nfapi.phy.state", ++ FT_UINT16, BASE_DEC, VALS(nfapi_phy_state_vals), 0x0, ++ "Indicates the current operational state of the PHY", HFILL } ++ }, ++ { &hf_nfapi_dl_ue_per_sf, ++ { "Downlink UEs per Subframe", "nfapi.dl.ue.per.sf", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The maximum number of downlink UEs per subframe supported." ++ "This is the maximum number of downlink UEs that can be scheduled per " ++ "subframe, non-inclusive of broadcast, paging and common channels.", HFILL } ++ }, ++ { &hf_nfapi_ul_ue_per_sf, ++ { "Uplink UEs per Subframe", "nfapi.ul.ue.per.sf", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The maximum number of uplink UEs per subframe supported." ++ "This is the maximum number of uplink UEs that can be scheduled per " ++ "subframe, non-inclusive of common channels.", HFILL } ++ }, ++ { &hf_nfapi_duplex_mode, ++ { "Duplex Mode", "nfapi.duplex.mode", ++ FT_UINT16, BASE_DEC, VALS(nfapi_duplex_mode_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support, ++ { "Downlink bandwidth support", "nfapi.dl.bandwidth.support", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PHY downlink channel bandwidth capability (in resource blocks)", HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_6, ++ { "6Mhz", "nfapi.dl.bandwidth.support.6", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_15, ++ { "15Mhz", "nfapi.dl.bandwidth.support.15", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_25, ++ { "25Mhz", "nfapi.dl.bandwidth.support.25", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_50, ++ { "50Mhz", "nfapi.dl.bandwidth.support.50", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_75, ++ { "75Mhz", "nfapi.dl.bandwidth.support.75", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_bandwidth_support_100, ++ { "100Mhz", "nfapi.dl.bandwidth.support.100", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support, ++ { "Uplink bandwidth support", "nfapi.ul.bandwidth.support", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PHY uplink channel bandwidth capability (in resource blocks)", HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_6, ++ { "6Mhz", "nfapi.ul.bandwidth.support.6", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_15, ++ { "15Mhz", "nfapi.ul.bandwidth.support.15", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_25, ++ { "25Mhz", "nfapi.ul.bandwidth.support.25", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_50, ++ { "50Mhz", "nfapi.ul.bandwidth.support.50", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_75, ++ { "75Mhz", "nfapi.ul.bandwidth.support.75", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_bandwidth_support_100, ++ { "100Mhz", "nfapi.ul.bandwidth.support.100", ++ FT_BOOLEAN, 1, TFS(&tfs_supported_not_supported), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_modulation_support, ++ { "Downlink modulation support", "nfapi.dl.modulation.support", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PHY downlink modulation capability", HFILL } ++ }, ++ { &hf_nfapi_dl_modulation_support_qpsk, ++ { "QPSK", "nfapi.dl.modulation.support.qpsk", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_modulation_support_16qam, ++ { "16QAM", "nfapi.dl.modulation.support.16qam", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_modulation_support_64qam, ++ { "64QAM", "nfapi.dl.modulation.support.64qam", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_modulation_support_256qam, ++ { "256QAM", "nfapi.dl.modulation.support.256qam", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_modulation_support, ++ { "Uplink modulation support", "nfapi.ul.modulation.support", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PHY uplink modulation capability", HFILL } ++ }, ++ { &hf_nfapi_ul_modulation_support_qpsk, ++ { "QPSK", "nfapi.ul.modulation.support.qpsk", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_modulation_support_16qam, ++ { "16QAM", "nfapi.ul.modulation.support.16qam", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_modulation_support_64qam, ++ { "64QAM", "nfapi.ul.modulation.support.64qam", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_phy_antenna_capability, ++ { "Phy Antenna capability", "nfapi.phy.antenna.capability", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of antennas supported", HFILL } ++ }, ++ { &hf_nfapi_release_capability, ++ { "Release capability", "nfapi.release.capability", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates which release the PHY supports", HFILL } ++ }, ++ { &hf_nfapi_mbsfn_capability, ++ { "MBSFN capability", "nfapi.mbsfn.capability", ++ FT_BOOLEAN, 8, TFS(&support_strname), 0x0, ++ "Indicates support for MBSFN features", HFILL } ++ }, ++ { &hf_nfapi_laa_capability, ++ { "LAA Support", "nfapi.laa.support", ++ FT_BOOLEAN, 8, TFS(&support_strname), 0x0, ++ "Indicates support for LAA features", HFILL } ++ }, ++ { &hf_nfapi_pd_sensing_lbt_support, ++ { "PD sensing LBT support", "nfapi.pd.sensing.lbt.support", ++ FT_BOOLEAN, 8, TFS(&support_strname), 0x0, ++ "Indicates support for PD sensing in L1", HFILL } ++ }, ++ { &hf_nfapi_multi_carrier_lbt_support, ++ { "Multi carrier LBT support", "nfapi.multi.carrier.lbt.support", ++ FT_UINT16, BASE_DEC, VALS(nfapi_mutli_carrier_lbt_support_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_partial_sf_support, ++ { "Partial SF support", "nfapi.partial.sf.support", ++ FT_BOOLEAN, 8, TFS(&partial_sf_support_strname), 0x0, ++ "Indicates support for Partial SF in L1", HFILL } ++ }, ++ { &hf_nfapi_reference_signal_power, ++ { "Reference signal power", "nfapi.ref_sig_power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(reference_signal_power_conversion_fn), 0x0, ++ "Normalized value levels (relative) to accommodate different absolute Tx Power used by eNb", HFILL } ++ }, ++ { &hf_nfapi_primary_synchronization_signal_epre_eprers, ++ { "Primary synchronization signal EPRE/EPRERS", "nfapi.primary.sync.signal", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "The power of synchronization signal with respect to the reference signal, (PSS for LTE cell, NPSS for NB-IOT cell)", HFILL } ++ }, ++ { &hf_nfapi_secondary_synchronization_signal_epre_eprers, ++ { "Secondary synchronization signal EPRE/EPRERS", "nfapi.secondary.sync.signal", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "The power of synchronization signal with respect to the reference signal, (SSS for LTE cell, NSSS for NB-IOT cell)", HFILL } ++ }, ++ { &hf_nfapi_physical_cell_id, ++ { "Physical Cell ID", "nfapi.physical.cell.id", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The Cell ID sent with the synchronization signal", HFILL } ++ }, ++ { &hf_nfapi_phich_resource, ++ { "PHICH Resource", "nfapi.phich.resource", ++ FT_UINT16, BASE_DEC, VALS(nfapi_phich_resource_vals), 0x0, ++ "The number of resource element groups used for PHICH", HFILL } ++ }, ++ { &hf_nfapi_phich_duration, ++ { "PHICH Duration", "nfapi.phich.duration", ++ FT_BOOLEAN, 8, TFS(&phich_duration_strname), 0x0, ++ "The PHICH duration for MBSFN and non-MBSFN sub-frames", HFILL } ++ }, ++ { &hf_nfapi_phich_power_offset, ++ { "PHICH Power Offset", "nfapi.phich.power.offset", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "The power per antenna of the PHICH with respect to the reference signal", HFILL } ++ }, ++ { &hf_nfapi_configuration_index, ++ { "Configuration Index", "nfapi.configuration.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Provides information about the location and format of the PRACH.", HFILL } ++ }, ++ { &hf_nfapi_root_sequence_index, ++ { "Root sequence Index", "nfapi.root.sequence.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "PRACH Root sequence index", HFILL } ++ }, ++ { &hf_nfapi_zero_correlation_zone_configuration, ++ { "Zero correlation zone configuration", "nfapi.zero.correlation.zone.configuration", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Equivalent to Ncs", HFILL } ++ }, ++ { &hf_nfapi_high_speed_flag, ++ { "High Speed Flag", "nfapi.high.speed.flag", ++ FT_BOOLEAN, 8, TFS(&high_speed_flag_strname), 0x0, ++ "Indicates if unrestricted, or restricted, set of preambles is used", HFILL } ++ }, ++ { &hf_nfapi_frequency_offset, ++ { "Frequency offset", "nfapi.frequency.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The first physical resource block available for PRACH", HFILL } ++ }, ++ { &hf_nfapi_hopping_mode, ++ { "Hopping Mode", "nfapi.hopping.mode", ++ FT_BOOLEAN, 8, TFS(&hopping_mode_strname), 0x0, ++ "If hopping is enabled indicates the type of hopping used", HFILL } ++ }, ++ { &hf_nfapi_hopping_offset, ++ { "Hopping offset", "nfapi.hopping.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The offset used if hopping is enabled", HFILL } ++ }, ++ { &hf_nfapi_delta_pucch_shift, ++ { "Delta PUCCH Shift", "nfapi.delta.pucch.shift", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The cyclic shift difference", HFILL } ++ }, ++ { &hf_nfapi_n_cqi_rb, ++ { "N CQI RB", "nfapi.n.cqi.rb", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The bandwidth, in units of resource blocks, that is available for use by PUCCH formats 2/2a/2b transmission in each slot", HFILL } ++ }, ++ { &hf_nfapi_n_an_cs, ++ { "N AN CS", "nfapi.n.an.cs", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of cyclic shifts used for PUCCH formats 1/1a/1b in a resource block with a mix of formats 1/a/1/ab and 2/2a/2b.", HFILL } ++ }, ++ { &hf_nfapi_n1_pucch_an, ++ { "N1 PUCCH AN", "nfapi.n1.pucch.an", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "N1 PUCCH", HFILL } ++ }, ++ { &hf_nfapi_bandwidth_configuration, ++ { "Bandwidth configuration", "nfapi.bw.configuration", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The available SRS bandwidth of the cell", HFILL } ++ }, ++ { &hf_nfapi_srs_subframe_configuration, ++ { "SRS subframe configuration", "nfapi.srs.subframe.configuration", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The subframe configuration. Needed if semi-static configuration is held in PHY", HFILL } ++ }, ++ { &hf_nfapi_uplink_rs_hopping, ++ { "Uplink RS hopping", "nfapi.uplink.rs.hopping", ++ FT_UINT16, BASE_DEC, VALS(nfapi_uplink_rs_hopping_vals), 0x0, ++ "Indicates the type of hopping to use", HFILL } ++ }, ++ { &hf_nfapi_group_assignment, ++ { "Group assignment", "nfapi.group.assignment", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The sequence shift pattern used if group hopping is enabled", HFILL } ++ }, ++ { &hf_nfapi_cyclic_shift_1_for_drms, ++ { "Cyclic Shift 1 for DRMS", "nfapi.cyclic.shift.1.for.drms", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Specifies the cyclic shift for the reference signal used in the cell.", HFILL } ++ }, ++ { &hf_nfapi_subframe_assignment, ++ { "Subframe_assignment", "nfapi.subframe.assignment", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "For TDD mode only, indicates the DL/UL subframe structure", HFILL } ++ }, ++ { &hf_nfapi_special_subframe_patterns, ++ { "Special Subframe patterns", "nfapi.special.subframe.patterns", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "For TDD mode only. Length of fields DwPTS, GP and UpPTS", HFILL } ++ }, ++ { &hf_nfapi_ed_threshold_for_lbt_for_pdsch, ++ { "ED Threshold for LBT for PDSCH", "nfapi.ed.threshold.for.lbt.pdsch", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(laa_threshold_conversion_fn), 0x0, ++ "Indicates the energy detection threshold in dBm for LBT for PDSCH", HFILL } ++ }, ++ { &hf_nfapi_ed_threshold_for_lbt_for_drs, ++ { "ED Threshold for LBT for DRS", "nfapi.ed.threshold.for.lbt.for.drs", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(laa_threshold_conversion_fn), 0x0, ++ "Indicates the energy detection threshold in dBm for LBT for DRS", HFILL } ++ }, ++ { &hf_nfapi_pd_threshold, ++ { "PD Threshold", "nfapi.pd.threshold", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(laa_threshold_conversion_fn), 0x0, ++ "Indicates the preamble detection threshold in dBm, if the L1 capabilities support PD", HFILL } ++ }, ++ { &hf_nfapi_multi_carrier_type, ++ { "Multi carrier type", "nfapi.multi.carrier.type", ++ FT_UINT16, BASE_DEC, VALS(nfapi_laa_carrier_type_vals), 0x0, ++ "Indicates multi carrier type configuration of L1 (according to L1 capabilities and L2 scheduler requirements", HFILL } ++ }, ++ { &hf_nfapi_multi_carrier_tx, ++ { "Multi carrier TX", "nfapi.multi.carrier.tx", ++ FT_BOOLEAN, 8, TFS(&nfapi_multi_carrier_tx_strname), 0x0, ++ "Indicates multi carrier transmission configuration of L1 (according to type if supporting multi carrier)", HFILL } ++ }, ++ { &hf_nfapi_multi_carrier_freeze, ++ { "Multi carrier freeze", "nfapi.multi.carrier.freeze", ++ FT_BOOLEAN, 8, TFS(&nfapi_multi_carrier_freeze_strname), 0x0, ++ "Indicates multi carrier freeze, configuration of L1 (applicable only to type A type if supporting multi carrier)", HFILL } ++ }, ++ { &hf_nfapi_tx_antenna_ports_for_drs, ++ { "Tx antenna ports for DRS", "nfapi.tx.antenna.ports.for.drs", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of cell specific transmit antenna ports within the DRS occasions", HFILL } ++ }, ++ { &hf_nfapi_transmission_power_for_drs, ++ { "Transmission power for DRS", "nfapi.transmission.power.for.drs.", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "Offset of cell specific Reference signals power within DRS occasions to the reference signal power", HFILL } ++ }, ++ { &hf_nfapi_pbch_repetitions_enabled_r13, ++ { "PBCH Repetitions enable R13", "nfapi.pbch.repetitions.enabled_r13", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable / Disable PBCH repetitions", HFILL } ++ }, ++ { &hf_nfapi_prach_cat_m_root_sequence_index, ++ { "PRACH CAT-M Root sequence index", "nfapi.prach.cat_m.root.squence.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "PRACH Root sequence index", HFILL } ++ }, ++ { &hf_nfapi_prach_cat_m_zero_correlation_zone_configuration, ++ { "PRACH CAT-M Zero correlation zone configuration", "nfapi.prach.cat_m.zero.correlation.zone.configuration", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Equivalent to Ncs", HFILL } ++ }, ++ { &hf_nfapi_prach_cat_m_high_speed_flag, ++ { "PRACH CAT-M High speed flag", "nfapi.prach.cat_m.high.speed.flag", ++ FT_BOOLEAN, 8, TFS(&high_speed_flag_strname), 0x0, ++ "Indicates if unrestricted, or restricted, set of preambles is used", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_enable, ++ { "PRACH CE level #0 Enable", "nfapi.prach.ce.level.0.enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable CE level #0.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_configuration_index, ++ { "PRACH CE level #0 Configuration index", "nfapi.prach.ce.level.0.configuration.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Provides information about the location and format of the PRACH", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_frequency_offset, ++ { "PRACH CE level #0 Frequency offset", "nfapi.prach.ce.level.0.frequency_offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The first physical resource block available for PRACH for each CE", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_number_of_repetitions_per_attempt, ++ { "PRACH CE level #0 Number of repetitions per attempt", "nfapi.prach.ce.level.0.number.of.repetitions.per_attempt", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of PRACH repetitions per attempt for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_starting_subframe_periodicity, ++ { "CE level #0 Starting subframe periodicity", "nfapi.prach.ce.level.0.starting.subframe_periodicity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Optional. PRACH starting subframe periodicity, expressed in number of slots available for preamble transmission(PRACH opportunities)", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_hopping_enabled, ++ { "PRACH CE level #0 Hopping Enable", "nfapi.prach.ce.level.0.hopping_enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable PRACH frequency hopping for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_0_hopping_offset, ++ { "PRACH CE level #0 Hopping Offset", "nfapi.prach.ce.level.0.hopping.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Valid in case 'PRACH Hopping Enable' is enabled", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_enable, ++ { "PRACH CE level #1 Enable", "nfapi.prach.ce.level.0.enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable CE level #1", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_configuration_index, ++ { "PRACH CE level #1 Configuration index", "nfapi.prach.ce.level.1.configuration.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Provides information about the location and format of the PRACH", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_frequency_offset, ++ { "PRACH CE level #1 Frequency offset", "nfapi.prach.ce.level.1.frequency_offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The first physical resource block available for PRACH for each CE", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_number_of_repetitions_per_attempt, ++ { "PRACH CE level #1 Number of repetitions per attempt", "nfapi.prach.ce.level.1.number.of.repetitions.per_attempt", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of PRACH repetitions per attempt for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_starting_subframe_periodicity, ++ { "CE level #1 Starting subframe periodicity", "nfapi.prach.ce.level.1.starting.subframe_periodicity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Optional.PRACH starting subframe periodicity, expressed in number of slots available for preamble transmission(PRACH opportunities),", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_hopping_enabled, ++ { "PRACH CE level #1 Hopping Enable", "nfapi.prach.ce.level.1.hopping_enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable PRACH frequency hopping for each CE level.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_1_hopping_offset, ++ { "PRACH CE level #1 Hopping Offset", "nfapi.prach.ce.level.1.hopping.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Valid in case 'PRACH Hopping Enable' is enabled.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_enable, ++ { "PRACH CE level #2 Enable", "nfapi.prach.ce.level.2.enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable CE level #2", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_configuration_index, ++ { "PRACH CE level #2 Configuration index", "nfapi.prach.ce.level.2.configuration.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Provides information about the location and format of the PRACH", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_frequency_offset, ++ { "PRACH CE level #2 Frequency offset", "nfapi.prach.ce.level.2.frequency_offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The first physical resource block available for PRACH for each CE", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_number_of_repetitions_per_attempt, ++ { "PRACH CE level #2 Number of repetitions per attempt", "nfapi.prach.ce.level.2.number.of.repetitions.per_attempt", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of PRACH repetitions per attempt for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_starting_subframe_periodicity, ++ { "CE level #2 Starting subframe periodicity", "nfapi.prach.ce.level.2.starting.subframe_periodicity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Optional. PRACH starting subframe periodicity, expressed in number of slots available for preamble transmission(PRACH opportunities)", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_hopping_enabled, ++ { "PRACH CE level #2 Hopping Enable", "nfapi.prach.ce.level.2.hopping_enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable PRACH frequency hopping for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_2_hopping_offset, ++ { "PRACH CE level #2 Hopping Offset", "nfapi.prach.ce.level.2.hopping.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Valid in case 'PRACH Hopping Enable' is enabled.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_enable, ++ { "PRACH CE level #3 Enable", "nfapi.prach.ce.level.3.enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable CE level #3.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_configuration_index, ++ { "PRACH CE level #3 Configuration index", "nfapi.prach.ce.level.3.configuration.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Provides information about the location and format of the PRACH.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_frequency_offset, ++ { "PRACH CE level #3 Frequency offset", "nfapi.prach.ce.level.3.frequency_offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The first physical resource block available for PRACH for each CE", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_number_of_repetitions_per_attempt, ++ { "PRACH CE level #3 Number of repetitions per attempt", "nfapi.prach.ce.level.3.number.of.repetitions.per_attempt", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of PRACH repetitions per attempt for each CE level", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_starting_subframe_periodicity, ++ { "CE level #3 Starting subframe periodicity", "nfapi.prach.ce.level.3.starting.subframe_periodicity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Optional. PRACH starting subframe periodicity, expressed in number of slots available for preamble transmission(PRACH opportunities)", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_hopping_enabled, ++ { "PRACH CE level #3 Hopping Enable", "nfapi.prach.ce.level.3.hopping_enable", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Enable \\ Disable PRACH frequency hopping for each CE level.", HFILL } ++ }, ++ { &hf_nfapi_prach_ce_level_3_hopping_offset, ++ { "PRACH CE level #3 Hopping Offset", "nfapi.prach.ce.level.3.hopping.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Valid in case 'PRACH Hopping Enable' is enabled.", HFILL } ++ }, ++ { &hf_nfapi_pucch_internal_ul_hopping_config_common_mode_a, ++ { "PUCCH Interval-ULHoppingConfigCommonModeA", "nfapi.pucch.interval.ulhopping.config.common.mode.a", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "NthULNB for UEModeA", HFILL } ++ }, ++ { &hf_nfapi_pucch_internal_ul_hopping_config_common_mode_b, ++ { "PUCCH Interval-ULHoppingConfigCommonModeB", "nfapi.pucch.interval.ulhopping.config.common.mode.b", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "NthULNB for UEModeB", HFILL } ++ }, ++ { &hf_nfapi_data_report_mode, ++ { "Data Report Mode", "nfapi.data.report.mode", ++ FT_BOOLEAN, 8, TFS(&data_report_mode_vals), 0x0, ++ "The data report mode for the uplink data", HFILL } ++ }, ++ { &hf_nfapi_sfnsf, ++ { "SFN/SF", "nfapi.sfn.sf", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(sfn_sf_conversion_fn), 0x0, ++ "The future SFN/SF subframe where the TLVs included in the message should be applied", HFILL } ++ }, ++ { &hf_nfapi_max_up_pts, ++ { "Max UpPTS frames", "nfapi.max.uppts.frame", ++ FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x0, ++ "Used for TDD only and indicates how SRS operates in UpPTS subframes", HFILL } ++ }, ++ { &hf_nfapi_srs_acknack_srs_simultaneous_transmission, ++ { "SRS AckNack Simultaneous transmission", "nfapi.srs.acknack.simult.tx", ++ FT_BOOLEAN, 8, TFS(&srs_simult_tx_strname), 0x0, ++ "Indicates if SRS and ACK/NACK can be received in the same subframe. Needed if semi-static configuration is held in PHY.", HFILL } ++ }, ++ { &hf_nfapi_pnf_address_ipv4, ++ { "PNF IPV4", "nfapi.pnf.address.ipv4", ++ FT_IPv4, BASE_NONE, NULL, 0x0, ++ "The IPv4 address of the PNF PHY instance to be used by the VNF for this PNF PHY instance", HFILL } ++ }, ++ { &hf_nfapi_pnf_address_ipv6, ++ { "PNF IPV6", "nfapi.pnf.address.ipv6", ++ FT_IPv6, BASE_NONE, NULL, 0x0, ++ "The IPv6 address of the PNF PHY instance to be used by the VNF for this PNF PHY instance", HFILL } ++ }, ++ { &hf_nfapi_vnf_address_ipv4, ++ { "VNF IPV4 Address", "nfapi.vnf.address.ipv4", ++ FT_IPv4, BASE_NONE, NULL, 0x0, ++ "The IPv4 address of the VNF to be used by the PNF for this P7 PHY instance", HFILL } ++ }, ++ { &hf_nfapi_vnf_address_ipv6, ++ { "VNF IPV6 Address", "nfapi.vnf.address.ipv6", ++ FT_IPv6, BASE_NONE, NULL, 0x0, ++ "The IPv6 address of the VNF to be used by the PNF for this P7 PHY instance", HFILL } ++ }, ++ { &hf_nfapi_pnf_port, ++ { "PNF PORT value", "nfapi.config.pnf.port.value", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The port of the PNF PHY instance to be used by the VNF for this PNF PHY instance", HFILL } ++ }, ++ { &hf_nfapi_vnf_port, ++ { "VNF PORT value", "nfapi.config.vnf.port.value", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The port of the VNF to be used by the PNF for this P7 PHY instance", HFILL } }, ++ { &hf_nfapi_sync_mode, ++ { "Sync Mode", "nfapi.sync.mode", ++ FT_UINT8, BASE_DEC, VALS(nfapi_sync_mode_vals), 0x0, ++ "The method of nFAPI Synchronization supported by the PNF", HFILL } ++ }, ++ { &hf_nfapi_location_mode, ++ { "Location Mode", "nfapi.location.mode", ++ FT_UINT8, BASE_DEC, VALS(location_mode_vals), 0x0, ++ "The method of location derivation supported by the PNF", HFILL } ++ }, ++ { &hf_nfapi_location_coordinates_length, ++ { "Location Coordinates Length", "nfapi.location.coordinates.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Length in bytes of the Location Coordinates Array field", HFILL } ++ }, ++ { &hf_nfapi_location_coordinates, ++ { "Location Coordinates", "nfapi.location.coordinates", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "The Location of the PNF. The value is formatted as the LocationCoordinates IE using BASIC-PER encoding as defined in " ++ "TS36.355 section 6.4.2. The first bit of the LocationCoordinates IE is in the LSB of the first byte of the array." ++ "The MSBs of the last element of the array may be padded with zeros if the ASN.1 element is not an integer number of bytes", HFILL } ++ }, ++ { &hf_nfapi_pdu, ++ { "PDU", "nfapi.pdu", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_config_timing, ++ { "DL config Timing", "nfapi.dl.config.timing", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The timing offset before the air interface subframe start that the DL_Config.request must be received at the PNF.", HFILL } ++ }, ++ { &hf_nfapi_tx_timing, ++ { "Tx Timing", "nfapi.general.tx.timing", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The timing offset before the air interface subframe start that the TX.request must be received at the PNF.", HFILL } ++ }, ++ { &hf_nfapi_ul_config_timing, ++ { "UL Config Timing", "nfapi.ul.config.timing", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The timing offset before the air interface subframe start that the UL_CONFIG.request must be received at the PNF.", HFILL } ++ }, ++ { &hf_nfapi_hi_dci0_timing, ++ { "HI DCi0 Timing", "nfapi.hi.dci0.timing", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The timing offset before the air interface subframe start that the HI_DCI0.request must be received at the PNF.", HFILL } ++ }, ++ { &hf_nfapi_maximum_number_phys, ++ { "Maximum number of Phys", "nfapi.maximum.number.phys", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The maximum number of operational PHYs supported by the PNF device.", HFILL } ++ }, ++ { &hf_nfapi_maximum_total_bandwidth, ++ { "Maximum Total Bandwidth", "nfapi.maximum.total.bandwidth", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &khz_100_units_db, 0x0, ++ "The total maximum bandwidth (in units of 100kHz) supported by the PNF device.", HFILL } ++ }, ++ { &hf_nfapi_maximum_total_number_dl_layers, ++ { "Maximum Total Number DL Layers", "nfapi.maximum.total.number.dl.layers", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The maximum total number of downlink layers supported.", HFILL } ++ }, ++ { &hf_nfapi_maximum_total_number_ul_layers, ++ { "Maximum Total Number UL Layers", "nfapi.maximum.total.number.ul.layers", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The maximum total number of uplink layers supported across all available PHYs.", HFILL } ++ }, ++ { &hf_nfapi_shared_bands, ++ { "Shared bands", "nfapi.shared.bands", ++ FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x0, ++ "Indication that the PNF device shares the list of RF band options available across all available PHYs, so each may only be used with a single PHY.", HFILL } ++ }, ++ { &hf_nfapi_shared_pa, ++ { "Shared pa", "nfapi.shared.pa", ++ FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x0, ++ "Indication that the PNF device shares a single RF PA across all available PHYs, so that the maximum Total Power is shared across all available PHYs.", HFILL } ++ }, ++ { &hf_nfapi_maximum_total_power, ++ { "Maximum total power", "nfapi.maximum.total.power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(dl_rs_tx_pow_measment_conversion_fn), 0x0, ++ "The maximum transmit power of the PNF device summed across all PHYs.", HFILL } ++ }, ++ { &hf_nfapi_oui, ++ { "OUI", "nfapi.oui", ++ FT_STRING, BASE_NONE, NULL, 0x0, ++ "The PNF OUI in the format as specified by IEEE", HFILL } ++ }, ++ { &hf_nfapi_pnf_phy_number_phy, ++ { "PNF Phy Number of Phy", "nfapi.pnf.phy.number.phy", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of PHY instances", HFILL } ++ }, ++ { &hf_nfapi_pnf_phy_config_index, ++ { "PNF Phy Config Index", "nfapi.pnf.phy.config.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The unique index number of the PHY to permit the PNF to identify the PHY in the PNF_CONFIG.Request", HFILL } ++ }, ++ { &hf_nfapi_number_of_rfs, ++ { "Number of RFs", "nfapi.pnf.rf.number.rf", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of RF configurations", HFILL } ++ }, ++ { &hf_nfapi_phy_rf_config_info_phy_id, ++ { "Phy ID", "nfapi.pnf.phy.rf.config.phy.id", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_rf_config_index, ++ { "RF Config Index", "nfapi.rf_config_index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The index number defined in the PNF RF struct that the PHY can support", ++ HFILL } ++ }, ++ { &hf_nfapi_number_of_rf_exclusions, ++ { "Number of RF exclusions", "nfapi.hf_nfapi_number_of_rf_exclusions", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of RF configurations excluded from use by this PHY", HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported, ++ { "Maximum 3gpp Release Supported", "nfapi.maximum_3gpp_release_supported", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The major 3GPP releases supported", HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel8, ++ { "Release 8", "nfapi.maximum_3gpp_release_supported.rel8", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel9, ++ { "Release 9", "nfapi.maximum_3gpp_release_supported.rel9", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel10, ++ { "Release 10", "nfapi.maximum_3gpp_release_supported.rel10", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel11, ++ { "Release 11", "nfapi.maximum_3gpp_release_supported.rel11", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel12, ++ { "Release 12", "nfapi.maximum_3gpp_release_supported.rel12", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_maximum_3gpp_release_supported_rel13, ++ { "Release 13", "nfapi.maximum_3gpp_release_supported.rel13", ++ FT_BOOLEAN, 1, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_downlink_channel_bandwidth_supported, ++ { "Maximum Channel Downlink Bandwidth Supported", "nfapi.downlink_channel_bandwidth_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The downlink channel bandwidth supported in resource blocks as specified in 3GPP TS 36.104", HFILL } ++ }, ++ { &hf_nfapi_uplink_channel_bandwidth_supported, ++ { "Maximum Channel Uplink Bandwidth Supported", "nfapi.uplink_channel_bandwidth_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The uplink channel bandwidth supported in resource blocks as specified in 3GPP TS 36.104.", HFILL } ++ }, ++ { &hf_nfapi_number_of_dl_layers_supported, ++ { "Number of DL Layers Supported", "nfapi.number_of_dl_layer_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The maximum number of downlink layers supported", HFILL } ++ }, ++ { &hf_nfapi_number_of_ul_layers_supported, ++ { "Number of UL Layers Supported", "nfapi.number_of_ul_layer_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The maximum number of uplink layers supported", HFILL } ++ }, ++ { &hf_nfapi_nmm_modes_supported, ++ { "NMM modes supported", "nfapi.nmm_modes_supported", ++ FT_UINT8, BASE_DEC, VALS(nmm_modes_supported_vals), 0x0, ++ "Network Monitor Modes Supported.", HFILL } ++ }, ++ { &hf_nfapi_band, ++ { "Band", "nfapi.band", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Band number as specified in 3GPP TS36.101", HFILL } ++ }, ++ { &hf_nfapi_maximum_transmit_power_2, ++ { "Maximum transmit power", "nfapi.maximum_transmit_power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(max_transmit_power_2_conversion_fn), 0x0, ++ "The maximum transmit power for the PHY and RF operating at the configured bandwidth as defined in 3GPP TS 36.104.", HFILL } ++ }, ++ { &hf_nfapi_maximum_transmit_power, ++ { "Maximum transmit power", "nfapi.maximum_transmit_power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(max_transmit_power_conversion_fn), 0x0, ++ "The maximum transmit power for the RF chain operating at the maximum supported bandwidth as defined in 3GPP TS 36.104.", HFILL } ++ }, ++ { &hf_nfapi_earfcn, ++ { "EARFCN", "nfapi.earfcn", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The EARFCN to be measured.", HFILL } ++ }, ++ { &hf_nfapi_number_of_rf_bands, ++ { "Number of RF Bands", "nfapi.num.rf_bands", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of RF Band instances", HFILL } ++ }, ++ { &hf_nfapi_nmm_uplink_rssi_supported, ++ { "NMM Uplink RSSI supported", "nfapi.nmm.uplink.rssi.supported", ++ FT_UINT8, BASE_DEC, VALS(ul_rssi_supported_vals), 0x0, ++ "Indicates if the uplink RSSI meausremnts are supported by NMM.", HFILL } ++ }, ++ { &hf_nfapi_minimum_transmit_power, ++ { "Minimum transmit power", "nfapi.minimum_transmit_power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(max_transmit_power_conversion_fn), 0x0, ++ "The minimum transmit power for the RF chain operating at the maximum supported bandwidth as defined in 3GPP TS 36.104.", HFILL } ++ }, ++ { &hf_nfapi_number_of_antennas_suppported, ++ { "Number of Supported Antennas", "nfapi.number_of_antennas_suppported", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The maximum number of antennas supported.", HFILL } ++ }, ++ { &hf_nfapi_minimum_downlink_frequency, ++ { "Minimum downlink frequency", "nfapi.minimum_downlink_frequency", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &khz_100_units_db, 0x0, ++ "The minimum supported downlink frequency in 100kHz units", HFILL } ++ }, ++ { &hf_nfapi_maximum_downlink_frequency, ++ { "Maximum downlink frequency", "nfapi.maximum_downlink_frequency", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &khz_100_units_db, 0x0, ++ "The maximum supported downlink frequency in 100kHz units", HFILL } ++ }, ++ { &hf_nfapi_minimum_uplink_frequency, ++ { "Minimum uplink frequency", "nfapi.minimum_downlink_frequency", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &khz_100_units_db, 0x0, ++ "The minimum supported uplink frequency in 100kHz units", HFILL } ++ }, ++ { &hf_nfapi_maximum_uplink_frequency, ++ { "Maximum uplink frequency", "nfapi.maximum_downlink_frequency", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &khz_100_units_db, 0x0, ++ "The maximum supported uplink frequency in 100kHz units", HFILL } ++ }, ++ { &hf_nfapi_transmission_mode7_supported, ++ { "Transmission Mode 7 Supported", "nfapi.pnf.phy_rel10.tx_mode7_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports TM7 for PDSCH", HFILL } ++ }, ++ { &hi_nfapi_transmission_mode8_supported, ++ { "Transmission Mode 8 Supported", "nfapi.pnf.phy_rel10.tx_mode8_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports TM8 for PDSCH", HFILL } ++ }, ++ { &hi_nfapi_two_antennas_ports_for_pucch, ++ { "Two antennas ports for PUCCH", "nfapi.pnf.phy_rel10.two_antennas_ports_for_pucch", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports PUCCH transmit diversity introduced in Release 10. Equivalent to two-AntennaPortsForPUCCH-r10 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_transmission_mode_9_supported, ++ { "Transmission Mode 9 Supported", "nfapi.pnf.phy_rel10.tx_mode9_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports TM9 for PDSCH with 8 antennas and 8 CSI. Equivalent to tm9-With-8Tx-FDD-r10 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_simultaneous_pucch_pusch, ++ { "Simultaneous PUCCH PUSCH", "nfapi.pnf.simultaneous_pucch_pusch", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports UE sending simultaneous PUCCH and PUSCH introduced in Release 10. Equivalent to simultaneousPUCCH-PUSCH-r10 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_four_layer_tx_with_tm3_and_tm4, ++ { "Four layer Tx with TM3 and TM4", "nfapi.pnf.phy_rel10.layer_tx_with_tm3_and_tm4", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports four layer transmission for TM3 and TM4. Equivalent to fourLayerTM3-TM4-r10 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_epdcch_supported, ++ { "ePDCCH supported", "nfapi.pnf.phy_rel11.epdcch_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports Enhanced PDCCH", HFILL } ++ }, ++ { &hi_nfapi_multi_ack_csi_reporting, ++ { "Multi ACK CSI reporting", "nfapi.pnf.phy_rel11.mutli_ack_csi_reporting", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports the multi ACK and CSI reporting required with CA and mixed FDD/TDD carriers. Equivalent to multiACK-CSI-Reporting-r11 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_pucch_tx_diversity_with_channel_selection, ++ { "PUCCH Tx diversity with channel selection", "nfapi.pnf.phy_rel11.tx_div_with_channel_selection", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports transmit diversity for PUCCH format 1b with channel selection. Equivalent to txDiv-PUCCH1b-ChSelect in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_ul_comp_supported, ++ { "UL CoMP supported", "nfapi.pnf.phy_rel11.ul_comp_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports UL CoMP", HFILL } ++ }, ++ { &hi_nfapi_transmission_mode_5_supported, ++ { "Transmission mode 5 supported", "nfapi.pnf.phy_rel11.tx_mode5_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports TM5 for PDSCH", HFILL } ++ }, ++ { &hf_nfapi_csi_subframe_set, ++ { "CSI subframe set", "nfapi.pnf.phy_rel12.csi_subframe_set", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Equivalent to csi-SubframeSet-r12 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_enhanced_4tx_codebook, ++ { "Enhanced 4TX codebook", "nfapi.pnf.phy_rel12.exhanced_t4x_codebook", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports the enhanced 4TX codebook. Equivalent to enhanced-4TxCodebook-r12 in TS36.306", HFILL } ++ }, ++ { &hi_nfapi_drs_supported, ++ { "DRS supported", "nfapi.pnf.phy_rel12.drs_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports the Discovery Reference Signal", HFILL } ++ }, ++ { &hi_nfapi_ul_64qam_supported, ++ { "UL 64QAM supported", "nfapi.pnf.phy_rel12.ul_64qam_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY support 64 QAM in the uplink", HFILL } ++ }, ++ { &hi_nfapi_transmission_mode_10_supported, ++ { "Transmission mode 10 supported", "nfapi.pnf.phy_rel12.tx_mode10_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports TM10 for PDSCH (DL CoMP)", HFILL } ++ }, ++ { &hi_nfapi_alternative_tbs_indices, ++ { "Alternative TBS indices", "nfapi.pnf.phy_rel12.alternative_tbs_indices", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports the alternate TBS indices (256 QAM). Equivalent to alternativeTBS-Indices-r12 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_pucch_format_4_supported, ++ { "PUCCH format 4 supported", "nfapi.pnf.phy_rel13.pucch_format4_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports PUCCH format 4", HFILL } ++ }, ++ { &hf_nfapi_pucch_format_5_supported, ++ { "PUCCH format 5 supported", "nfapi.pnf.phy_rel13.pucch_format5_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports PUCCH format 5", HFILL } ++ }, ++ { &hf_nfapi_more_than_5_ca_supported, ++ { "More than 5 CA support", "nfapi.pnf.phy_rel13.mode_than_5_ca_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports features required for more than 5 CA support on PUSCH. Equivalent to uci-PUSCH-Ext-r13 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_laa_supported, ++ { "LAA supported", "nfapi.pnf.phy_rel13.laa_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports DL LAA (subframe format 3)", HFILL } ++ }, ++ { &hf_nfapi_laa_ending_in_dwpts_supported, ++ { "LAA ending in DwPTS supported", "nfapi.pnf.phy_rel13.laa_ending_in_dwpts_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports DL LAA ending in a DwPTS subframe. Equivalent to endingDwPTS-r13i n TS36.306", HFILL } ++ }, ++ { &hf_nfapi_laa_starting_in_second_slot_supported, ++ { "LAA starting in second slot Supported", "nfapi.pnf.phy_rel13.laa_starting_in_second_slot_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports DL LAA starting in the second slot in a subframe. Equivalent to secondSlotStartingPosition-r13 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_beamforming_supported, ++ { "Beamforming Supported", "nfapi.pnf.phy_rel13.beamingforming_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports beamforming (FD-MIMO Class B). Equivalent to beamformed-r13 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_enhancements_supported, ++ { "CSI-RS enhancements supported", "nfapi.pnf.phy_rel13.csi_rs_enchancements_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports CSI-RS enhancements (FD-MIMO Class A). Equivalent to csi-RS-EnhancementsTDD-r13 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_drms_enhancements_supported, ++ { "DMRS enhancements supported", "nfapi.pnf.phy_rel13.drms_enhancements_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports DMRS enhancements added in Release 13. Equivalent to dmrs-Enhancements-r13 in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_srs_enhancements_supported, ++ { "SRS enhancements supported", "nfapi.pnf.phy_rel13.srs_enhancements_supported", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates if PHY supports SRS enhancements added in Release 13. Equivalent to srs-Enhancements-r13in TS36.306", HFILL } ++ }, ++ { &hf_nfapi_sfn_sf, ++ { "SFN_SF", "nfapi.sfn_sf", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(sfn_sf_conversion_fn), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_number_pdcch_ofdm_symbols, ++ { "Number of PDCCH OFDM Symbols", "nfapi.number_pdcch_ofdm_symbols", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of OFDM symbols for the PDCCH", HFILL } ++ }, ++ { &hf_nfapi_number_dci, ++ { "Number of DCI", "nfapi.number_dci", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of DCI PDUs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_pdus, ++ { "Number of PDUs", "nfapi.number_pdu", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of PDUs that are included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_harqs, ++ { "Number of HARQs", "nfapi.number_harqs", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of HARQs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_crcs, ++ { "Number of CRCs", "nfapi.number_crcs", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of CRCs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_srs, ++ { "Number of SRs", "nfapi.number_srs", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of SRs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_cqi, ++ { "Number of CQIs", "nfapi.number_cqi", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of CQIs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_preambles, ++ { "Number of Preambles", "nfapi.number_preambles", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of RACH preambles", HFILL } ++ }, ++ { &hf_nfapi_number_of_srss, ++ { "Number of SRSs", "nfapi.number_srss", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Number of UEs contributing to the uplink SRS", HFILL } ++ }, ++ { &hf_nfapi_lbt_dl_req_pdu_type, ++ { "LBT DL Request PDU Type", "nfapi.number_srss", ++ FT_UINT16, BASE_DEC, VALS(nfapi_lbt_dl_req_pdu_type), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_lbt_dl_ind_pdu_type, ++ { "LBT DL Indication PDU Type", "nfapi.number_srss", ++ FT_UINT16, BASE_DEC, VALS(nfapi_lbt_dl_ind_pdu_type), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_number_pdsch_rnti, ++ { "Number of PDSCH RNTI", "nfapi.number_pdsch_rnti", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of unique RNTIs sent on the PDSCH", HFILL } ++ }, ++ { &hf_nfapi_transmission_power_pcfich, ++ { "Transmission Power PCFICH", "nfapi.transmission_power_pcfich", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "Offset to the reference signal power.", HFILL } ++ }, ++ { &hf_nfapi_dl_config_pdu_type, ++ { "PDU Type", "nfapi.pdu.type", ++ FT_UINT8, BASE_DEC, VALS(nfapi_dl_config_pdu_type_vals), 0x0, ++ "DL_CONFIG.request PDU Type", HFILL } ++ }, ++ { &hf_nfapi_pdu_size, ++ { "PDU size", "nfapi.pdu.size", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Size of the PDU control information (in bytes). This length value includes the 2 bytes required for the PDU type and PDU size parameters", HFILL } ++ }, ++ { &hf_nfapi_instance_length, ++ { "Instance length", "nfapi.instance.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The Length in bytes of all TLVs within this instance", HFILL } ++ }, ++ { &hf_nfapi_length, ++ { "PDU length", "nfapi.pdu.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Length of PDU in bytes.", HFILL } ++ }, ++ { &hf_nfapi_pdu_index, ++ { "PDU Index", "nfapi.pdu.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PDU index parameter specified for each PDU", HFILL } ++ }, ++ { &hf_nfapi_rnti, ++ { "RNTI", "nfapi.rnti", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The RNTI used for identifying the UE when receiving the PDU", HFILL } ++ }, ++ { &hf_nfapi_resource_allocation_type, ++ { "Resource Allocation Type", "nfapi.resource.allocation.type", ++ FT_UINT8, BASE_DEC, VALS(resource_allocation_type_vals), 0x0, ++ "Resource allocation type/header Valid for DCI formats : 1, 2, 2A, 2B, 2C, 2D", HFILL } ++ }, ++ { &hf_nfapi_virtual_resource_block_assignment_flag, ++ { "Virtual resource block assignment flag", "nfapi.resource.block.assignment.flag", ++ FT_UINT8, BASE_DEC, VALS(local_distributed_vals), 0x0, ++ "Type of virtual resource block used Valid for DCI formats : 1A, 1B, 1D", HFILL } ++ }, ++ { &hf_nfapi_resource_block_coding, ++ { "Resource block coding", "nfapi.resource.block.coding", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The encoding for the resource blocks. The coding is dependent on whether resource allocation type 0, 1, 2 is in use", HFILL } ++ }, ++ { &hf_nfapi_modulation, ++ { "Modulation", "nfapi.modulation", ++ FT_UINT8, BASE_DEC, VALS(modulation_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_redundancy_version, ++ { "Redundancy version", "nfapi.redundancy.version", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ redundancy version", HFILL } ++ }, ++ { &hf_nfapi_transport_blocks, ++ { "Transport blocks", "nfapi.transport.blocks", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The transport block transmitted to this RNTI", HFILL } ++ }, ++ { &hf_nfapi_transport_block_to_codeword_swap_flag, ++ { "Transport block to codeword swap flag", "nfapi.transport.block.to.codeword.swap.flag", ++ FT_UINT8, BASE_DEC, VALS(transport_block_to_codeword_swap_flag_vals), 0x0, ++ "Indicates the mapping of transport block to codewords.", HFILL } ++ }, ++ { &hf_nfapi_transmission_scheme, ++ { "Transmission scheme", "nfapi.transmission.scheme", ++ FT_UINT8, BASE_DEC, VALS(transmission_scheme_vals), 0x0, ++ "The MIMO mode used in the PDU", HFILL } ++ }, ++ { &hf_nfapi_ul_transmission_scheme, ++ { "Transmission scheme", "nfapi.transmission.scheme", ++ FT_UINT8, BASE_DEC, VALS(ul_transmission_scheme_vals), 0x0, ++ "The MIMO mode used in the PDU", HFILL } ++ }, ++ { &hf_nfapi_number_of_layers, ++ { "Number of layers", "nfapi.number.of.layers", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of layers used in transmission", HFILL } ++ }, ++ { &hf_nfapi_number_of_subbands, ++ { "Number of subbands", "nfapi.number.of.subbands", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Only valid when transmission scheme = 3, 4, 5. Defines the number of subbands and " ++ "codebooks used for PMI.If value = 1 then a single PMI value is supplied which should be used over all RB", HFILL } ++ }, ++ { &hf_nfapi_codebook_index, ++ { "Codebook index", "nfapi.number.of.codebook.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Only valid when transmission scheme = 3, 4, 5. Defines the codebook used.", HFILL } ++ }, ++ { &hf_nfapi_ue_category_capacity, ++ { "UE category capacity", "nfapi.ue.category.capacity", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The UE capabilities category", HFILL } ++ }, ++ { &hf_nfapi_pa, ++ { "P-A", "nfapi.pa", ++ FT_UINT8, BASE_DEC, VALS(pa_vals), 0x0, ++ "The ratio of PDSCH EPRE to cell-specific RS EPRE among PDSCH REs in all the OFDM symbols not containing cell-specific RS in dB.", HFILL } ++ }, ++ { &hf_nfapi_delta_power_offset_index, ++ { "Delta Power offset index", "nfapi.delta.power.offset.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Delta power offset, value: 0..1", HFILL } ++ }, ++ { &hf_nfapi_nprb, ++ { "Nprb", "nfapi.nprb", ++ FT_UINT8, BASE_DEC, VALS(nprb_vals), 0x0, ++ "Used with DCI format 1A and RNTI=SI-RNTI or RA-RNTI. This should match the value sent in the TPC field of the DCI 1A PDU which allocated this grant.", HFILL } ++ }, ++ { &hf_nfapi_transmission_mode, ++ { "Transmission Mode", "nfapi.transmission_nprb", ++ FT_UINT8, BASE_DEC, VALS(transmission_mode_vals), 0x0, ++ "Transmission mode associated with the UE", HFILL } ++ }, ++ { &hf_nfapi_prnti, ++ { "P-RNTI", "nfapi.prnti", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The P-RNTI associated with the paging", HFILL } ++ }, ++ { &hf_nfapi_mcs, ++ { "MCS", "nfapi.mcs", ++ FT_UINT8, BASE_DEC, VALS(pch_modulation_vals), 0x0, ++ "The modulation and coding scheme for the transport block", HFILL } ++ }, ++ { &hf_nfapi_number_of_transport_blocks, ++ { "Number of transport blocks", "nfapi.number_of_transport_blocks", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of transport blocks transmitted to this RNTI", HFILL } ++ }, ++ { &hf_nfapi_ue_mode, ++ { "UE Mode", "nfapi.ue.mode", ++ FT_UINT8, BASE_DEC, VALS(ue_mode_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_prs_bandwidth, ++ { "PRS bandwidth", "nfapi.prs.bandwidth", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "PRS bandwidth in resource blocks.", HFILL } ++ }, ++ { &hf_prs_cyclic_prefix_type, ++ { "PRS cyclic prefix type", "nfapi.prs.cyclic.prefix.type", ++ FT_BOOLEAN, 8, TFS(&prs_cyclic_prefix_type_strname), 0x0, ++ "The cyclic prefix used for PRS transmission", HFILL } ++ }, ++ { &hf_prs_muting, ++ { "PRS muting", "nfapi.prs.muting", ++ FT_BOOLEAN, 8, TFS(&prs_muting_strname), 0x0, ++ "PRS muting dictates if PRS REs are vacant (prsMutingInfo-r9 indicates the SF occasions)", HFILL } ++ }, ++ { &hf_nfapi_num_bf_prb_per_subband, ++ { "Num of BF PRB per Subband", "nfapi.num.bf.prb.per.subband", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of PRBs that are treated as one subband", HFILL } ++ }, ++ { &hf_nfapi_num_bf_vector, ++ { "Num of BF Vector", "nfapi.num.bf.vector", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of beam forming vectors. One beam forming vector is specified for each subband", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_resource_config, ++ { "CSI-RS resource config", "nfapi.csi.rs.resource.config", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates reference signal configuration for CSI-RS", HFILL } ++ }, ++ { &hf_nfapi_bf_vector_subband_index, ++ { "BF Subband Index", "nfapi.num.bf.vector.subband.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Index of subband for which the following beam forming vector is applied", HFILL } ++ }, ++ { &hf_nfapi_bf_vector_num_antennas, ++ { "BF Num of Antennas", "nfapi.num.bf.vector.bf.value", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of physical antennas", HFILL } ++ }, ++ { &hf_nfapi_bf_vector_bf_value, ++ { "BF Value per Antenna", "nfapi.num.bf.vector.bf.value", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Beam forming vector element for physical antenna #i real 8 bits followed by imaginary 8 bits", HFILL } ++ }, ++ { &hf_nfapi_nscid, ++ { "NSC id", "nfapi.nscid", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Used with DCI format 2B and 2C.", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_flag, ++ { "CSI RS Flag", "nfapi.csi.rs.flag", ++ FT_BOOLEAN, 8, TFS(&csi_rs_flags_strname), 0x0, ++ "Indicates if parameters related to CSI-RS are valid or not.", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_resource_config_r10, ++ { "CSI RS resource config R10", "nfapi.csi.rs.resource_config_r10", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "This value is deprecated", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_zero_tx_power_resource_config_bitmap_r10, ++ { "CSI-RS Number of NZP configuration", "nfapi.csi.rs.num.of.nzp.configurations", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Bitmap of 16 bits. Encoding format of bitmap follows section 6.10.5.2 of 36.211", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_number_of_nzp_configurations, ++ { "CSI RS zero Tx Power Resource config bitmap R10", "nfapi.csi.rs.zero.tx.power.resource.config.bitmap.r10", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates the number of Non-Zero power CSI-RS configurations.", HFILL } ++ }, ++ { &hf_nfapi_pdsch_start, ++ { "PDSCH_start", "nfapi.pdsch.start", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Per UE starting OFDM symbol for the PDSCH, impacts the mapping of PDSCH to REs", HFILL } ++ }, ++ { &hf_nfapi_drms_config_flag, ++ { "DMRS Config flag", "nfapi.drms.config.flag", ++ FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, ++ "Indicates if the DMRS Config parameter is valid", HFILL } ++ }, ++ { &hf_nfapi_drms_scrambling, ++ { "DMRS Scrambling", "nfapi.drms.scrambling", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The scrambling identity for UE specific reference signals.", HFILL } ++ }, ++ { &hf_nfapi_csi_config_flag, ++ { "CSI Config flag", "nfapi.csi.config.flag", ++ FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, ++ "Indicates if the CSI Config parameter is valid", HFILL } ++ }, ++ { &hf_nfapi_csi_scrambling, ++ { "CSI Scrambling", "nfapi.csi.scrambling", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The scrambling identity for CSI.", HFILL } ++ }, ++ { &hf_nfapi_pdsch_re_mapping_flag, ++ { "PDSCH RE mapping flag", "nfapi.pdsch.remapping.flag", ++ FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, ++ "Indicates if the PDSCH RE parameters are valid.", HFILL } ++ }, ++ { &hf_nfapi_pdsch_re_mapping_antenna_ports, ++ { "PDSCH RE mapping antenna ports", "nfapi.pdsch.remapping.antenna.ports", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates number of antennas used for PDSCH RE mapping", HFILL } ++ }, ++ { &hf_nfapi_pdsch_re_mapping_freq_shift, ++ { "PDSCH RE mapping freq shift", "nfapi.pdsch.remapping.freq.shift", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the frequency shift used for PDSCH RE mapping.", HFILL } ++ }, ++ { &hf_nfapi_alt_cqi_table_r12, ++ { "altCQI-Table-r12", "nfapi.alt.cqi.table.r12", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "altCQI-Table-r12 is indicative of using an alternative MCS table for UEs supporting 256QAM." ++ "This is taken into account for calculation of soft buffer size for the transport block", HFILL } ++ }, ++ { &hf_nfapi_max_layers, ++ { "MaxLayers", "nfapi.max.layers", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Maximal number of negotiated / configured layers for a UE, used for the calculation of soft buffer size for the transport block", HFILL } ++ }, ++ { &hf_nfapi_n_dl_harq, ++ { "N_DL_HARQ", "nfapi.n.dl.harq", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dwpts_symbols, ++ { "DwPTS Symbols", "nfapi.dwpts.symbols", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid if DCI format 1C is being used to signal LAA end partial SF. Indicates the number of starting symbols according to 36.213 Table 13-A-1", HFILL } ++ }, ++ { &hf_nfapi_initial_lbt_sf, ++ { "Initial LBT SF", "nfapi.initial.lbt.sf", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if the DCI PDU is prepared for full SF (regular) or for initial partial SF (2nd slot) according to [11] section 6.2.4 (if PDCCH) or 6.2.4A (if ePDCCH)", HFILL } ++ }, ++ { &hf_nfapi_ue_type, ++ { "UE Type", "nfapi.ue.type", ++ FT_UINT8, BASE_DEC, VALS(dlsch_re13_ue_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_pdsch_payload_type, ++ { "PDSCH Payload Type", "nfapi.pdsch.payload.type", ++ FT_UINT8, BASE_DEC, VALS(dlsch_re13_pdsch_payload_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_initial_transmission_sf, ++ { "Initial transmission SF (io)", "nfapi.init.tx.sf.io", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Absolute Sub-Frame of the initial transmission", HFILL } ++ }, ++ { &hf_nfapi_req13_drms_table_flag, ++ { "Rel-13-DMRS-tabe flag", "nfapi.r13.drms.table.flag", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if Release 13 DMRS table is used.", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_resource_index, ++ { "CSI-RS resource index", "nfapi.csi.rs.resource.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Index of the CSI-RS resource. This is included to link bfValues to CSI-RS resources included in Release 10 parameters.", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_class, ++ { "Class", "nfapi.csi.rs.class", ++ FT_UINT8, BASE_DEC, VALS(csi_rs_class_vals), 0x0, ++ "Indicates CSI-RS class", HFILL } ++ }, ++ { &hf_nfapi_cdm_type, ++ { "CDM Type", "nfapi.cdm.type", ++ FT_UINT8, BASE_DEC, VALS(csi_rs_cdm_type_vals), 0x0, ++ "Indicates CDM type for CSI-RS. See [36.211] section 6.10.5.2. Valid for Class A", HFILL } ++ }, ++ { &hf_nfapi_edpcch_prb_index, ++ { "EPDCCH PRB index", "nfapi.edpcch.prb.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "PRB index", HFILL } ++ }, ++ { &hf_nfapi_epdcch_resource_assignment_flag, ++ { "EPDCCH Resource assignment flag", "nfapi.epdcch.resource.assignment.flag", ++ FT_UINT8, BASE_DEC, VALS(local_distributed_vals), 0x0, ++ "Type of virtual resource block used", HFILL } ++ }, ++ { &hf_nfapi_epdcch_id, ++ { "EPDCCH ID", "nfapi.epdcch.id", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "EPDCCH index- used for the scrambler initiation The DMRS scrambling sequence initialization parameter defined in[11] section 6.10.3A.1", HFILL } ++ }, ++ { &hf_nfapi_epdcch_start_symbol, ++ { "EPDCCH Start Symbol", "nfapi.epdcch.start.symbol", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the OFDM starting symbol for any EPDCCH and PDSCH", HFILL } ++ }, ++ { &hf_nfapi_epdcch_num_prb, ++ { "EPDCCH NumPRB", "nfapi.epdcch.num.prb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of PRBs allocated for EPDCCH", HFILL } ++ }, ++ { &hf_nfapi_precoding_value, ++ { "Precoding value", "nfapi.precoding.value", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Precoding element for physical antenna #i real 8 bits followed by imaginary 8 bits", HFILL } ++ }, ++ { &hf_nfapi_mpdcch_narrowband, ++ { "MPDCCH Narrowband", "nfapi.mpdcch.narrowband", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Narrowband for MPDCCH", HFILL } ++ }, ++ { &hf_nfapi_number_of_prb_pairs, ++ { "Number of PRB pairs", "nfapi.number.prb.pairs", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of PRB-pairs constituting the MPDCCH-PRB-pair set", HFILL } ++ }, ++ { &hf_nfapi_resource_block_assignment, ++ { "Resource Block Assignment", "nfapi.resource.block.assignement", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Combinational index r", HFILL } ++ }, ++ { &hf_nfapi_start_symbol, ++ { "Start symbol", "nfapi.start.symbol", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ecce_index, ++ { "ECCE index", "nfapi.ecce.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "CCE index used to send the DCI", HFILL } ++ }, ++ { &hf_nfapi_ce_mode, ++ { "CE Mode", "nfapi.ce.mode", ++ FT_UINT8, BASE_DEC, VALS(ce_mode_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_drms_scrabmling_init, ++ { "DMRS scrambling init", "nfapi.drms.scrambling.init", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The DMRS scrambling sequence initialization parameter defined in [11] section 6.10.3A.1", HFILL } ++ }, ++ { &hf_nfapi_pdsch_reception_levels, ++ { "PDSCH repetition levels", "nfapi.pdsch.repetition.levels", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid for DCI formats: 6-0A, 6-0B", HFILL } ++ }, ++ { &hf_nfapi_new_data_indicator, ++ { "New data indicator", "nfapi.new.data.indicator", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The new data indicator for the transport block", HFILL } ++ }, ++ { &hf_nfapi_tpmi_length, ++ { "TPMI length", "nfapi.tpmi.length", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Length of 'TPMI' field in units of bits", HFILL } ++ }, ++ { &hf_nfapi_pmi_flag, ++ { "PMI flag", "nfapi.pmi.flag", ++ FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x0, ++ "Indicates if 'PMI' field is present", HFILL } ++ }, ++ { &hf_nfapi_harq_resource_offset, ++ { "HARQ resource offset", "nfapi.harq.resource.offset", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ-ACK resource offset used", HFILL } ++ }, ++ { &hf_nfapi_dci_subframe_repetition_number, ++ { "DCI subframe repetition number", "nfapi.dci.subframe.repetition.number", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the number of MPDCCH repetitions", HFILL } ++ }, ++ { &hf_nfapi_downlink_assignment_index_length, ++ { "Downlink assignment index Length", "nfapi.dl.assignement.index.length", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Length of Downlink assignment index field in units of bits.", HFILL } ++ }, ++ { &hf_nfapi_starting_ce_level, ++ { "Starting CE Level", "nfapi.starting.ce.level", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "2 bits provide the PRACH starting CE level", HFILL } ++ }, ++ { &hf_nfapi_antenna_ports_and_scrambling_identity_flag, ++ { "Antenna ports and scrambling identity flag", "nfapi.antenna.ports.and.scrambling.identity.flag", ++ FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x0, ++ "Indicates if 'Antenna ports and scrambling identity' field is present.", HFILL } ++ }, ++ { &hf_nfapi_antenna_ports_and_scrambling_identity, ++ { "Antenna ports and scrambling identity", "nfapi.antenna.ports.and.scrambling.identit", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the Antenna port and, scrambling identity value", HFILL } ++ }, ++ { &hf_nfapi_paging_direct_indication_differentiation_flag, ++ { "Paging/Direct indication differentiation flag", "nfapi.paging.direct.indictation.differentiation.flag", ++ FT_UINT8, BASE_DEC, VALS(paging_direct_indication_differtiation_flag_vals), 0x0, ++ "Valid for DCI format 6-2", HFILL } ++ }, ++ { &hf_nfapi_direct_indication, ++ { "Direct indication", "nfapi.direct.indication", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid for DCI format 6-2", HFILL } ++ }, ++ { &hf_nfapi_number_of_tx_antenna_ports, ++ { "Number of TX Antenna ports", "nfapi.num.of.tx.antenna.ports.", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of TX physical antenna ports", HFILL } ++ }, ++ { &hf_nfapi_transmission_power, ++ { "Transmission Power", "nfapi.transmission_power", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "Offset to the reference signal power.", HFILL } ++ }, ++ { &hf_nfapi_mbsfn_area_id, ++ { "MBSFN Area id", "nfapi.mbsfn.area.id", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates MBSFN area ID", HFILL } ++ }, ++ { &hf_nfapi_dl_dci_format, ++ { "DL DCI format", "nfapi.dl.dci.format", ++ FT_UINT8, BASE_DEC, VALS(dl_dci_format_vals), 0x0, ++ "Format of the DL DCI", HFILL } ++ }, ++ { &hf_nfapi_ul_dci_format, ++ { "UL DCI format", "nfapi.ul_dci.format", ++ FT_UINT8, BASE_DEC, VALS(ul_dci_format_vals), 0x0, ++ "Format of the UL DCI", HFILL } ++ }, ++ { &hf_nfapi_mpdcch_ul_dci_format, ++ { "UL DCI format", "nfapi.mpdcch.ul_dci.format", ++ FT_UINT8, BASE_DEC, VALS(mpdcch_ul_dci_format_vals), 0x0, ++ "Format of the UL DCI", HFILL } ++ }, ++ { &hf_nfapi_cce_idx, ++ { "CCE index", "nfapi.cce.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "CCE index used to send the DCI", HFILL } ++ }, ++ { &hf_nfapi_aggregation_level, ++ { "Aggregation level", "nfapi.aggregation.level", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The aggregation level used", HFILL } ++ }, ++ { &hf_nfapi_mcs_1, ++ { "MCS_1", "nfapi.mcs_1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The modulation and coding scheme for 1st transport block", HFILL } ++ }, ++ { &hf_nfapi_mcs_2, ++ { "MCS_2", "nfapi.mcs_2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The modulation and coding scheme for 2nd transport block", HFILL } ++ }, ++ { &hf_nfapi_redundancy_version_1, ++ { "Redundancy version_1", "nfapi.redundancy.version.1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The redundancy version for 1st transport block.", HFILL } ++ }, ++ { &hf_nfapi_redundancy_version_2, ++ { "Redundancy version_2", "nfapi.redundancy.version.2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The redundancy version for 2nd transport block", HFILL } ++ }, ++ { &hf_nfapi_new_data_indicator_1, ++ { "New data indicator_1", "nfapi.new.data.indicator.1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The new data indicator for 1st transport block.", HFILL } ++ }, ++ { &hf_nfapi_new_data_indicator_2, ++ { "New data indicator_2", "nfapi.new.data.indicator.2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The new data indicator for 2nd transport block.", HFILL } ++ }, ++ { &hf_nfapi_harq_process, ++ { "HARQ process", "nfapi.harq.process", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ process number", HFILL } ++ }, ++ { &hf_nfapi_tpmi, ++ { "TPMI", "nfapi.tpmi", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The codebook index to be used for precoding", HFILL } ++ }, ++ { &hf_nfapi_pmi, ++ { "PMI", "nfapi.pmi", ++ FT_UINT8, BASE_DEC, VALS(pmi_vals), 0x0, ++ "Confirmation for precoding", HFILL } ++ }, ++ { &hf_nfapi_precoding_information, ++ { "Precoding information", "nfapi.precoding.information", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_tpc, ++ { "TPC", "nfapi.tpc", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Tx power control command for PUCCH", HFILL } ++ }, ++ { &hf_nfapi_downlink_assignment_index, ++ { "Downlink assignment index", "nfapi.downlink.assignment.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The downlink assignment index. In release 8-11 this is only used in TDD mode, " ++ "value ignored for FDD. In release 12 or later a field indicating the structure " ++ "type of the primary cell is used to determine if this is valid with size 2 bits." ++ "In release 13 or later a field indicating codebooksizeDetermination - r13 = 0 is " ++ "used to determine is this field is valid with size 4 bits", HFILL } ++ }, ++ { &hf_nfapi_ngap, ++ { "Ngap", "nfapi.ngap", ++ FT_UINT8, BASE_DEC, VALS(ngap_vals), 0x0, ++ "Used in virtual resource block distribution", HFILL } ++ }, ++ { &hf_nfapi_transport_block_size_index, ++ { "Transport block size index", "nfapi.transport.block.size.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The transport block size", HFILL } ++ }, ++ { &hf_nfapi_downlink_power_offset, ++ { "Downlink power offset", "nfapi.downlink.power.offset", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the DL power offset type for multi-user MIMO transmission", HFILL } ++ }, ++ { &hf_nfapi_allocate_prach_flag, ++ { "Allocation PRACH flag", "nfapi.allocation.prach.flag", ++ FT_UINT8, BASE_DEC, VALS(true_false_vals), 0x0, ++ "Indicates that PRACH procedure is initiated", HFILL } ++ }, ++ { &hf_nfapi_preamble_index, ++ { "Preamble index", "nfapi.preamable.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The preamble index to be used on the PRACH", HFILL } ++ }, ++ { &hf_nfapi_prach_mask_index, ++ { "PRACH mask index", "nfapi.prach.mask.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The mask index to be used on the PRACH", HFILL } ++ }, ++ { &hf_nfapi_rnti_type, ++ { "RNTI type", "nfapi.rnti.type", ++ FT_UINT8, BASE_DEC, VALS(rnti_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_mpdcch_rnti_type, ++ { "RNTI type", "nfapi.mpdcch.rnti.type", ++ FT_UINT8, BASE_DEC, VALS(mpdcch_rnti_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_mcch_flag, ++ { "MCCH flag", "nfapi.mcch.flag", ++ FT_BOOLEAN, BASE_NONE, TFS(&mcch_flag_string_name), 0x0, ++ "Indicates if format 1C is being used to signal a MCCH or SC-MCCH change notification", HFILL } ++ }, ++ { &hf_nfapi_mcch_change_notification, ++ { "MCCH change notification", "nfapi.mcch.change.notification", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "MCCH or SC-MCCH Change Notification", HFILL } ++ }, ++ { &hf_nfapi_scrambling_identity, ++ { "Scrambling identity", "nfapi.scrambling.identity", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the scrambling identity value NSCID", HFILL } ++ }, ++ { &hf_nfapi_cross_carrier_scheduling_flag, ++ { "Cross Carrier scheduling flag", "nfapi.cross.carrier.scheduling.flag", ++ FT_BOOLEAN, 8, TFS(&cross_carrier_scheduling_flag_strname), 0x0, ++ "Indicates if cross carrier scheduling has been enabled for the UE receiving this DCI", HFILL } ++ }, ++ { &hf_nfapi_carrier_indicator, ++ { "Carrier Indicator", "nfapi.carrier.indicator", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Serving Cell Index", HFILL } ++ }, ++ { &hf_nfapi_srs_flag, ++ { "SRS flag", "nfapi.srs.flag", ++ FT_BOOLEAN, 8, TFS(&srs_flag_strname), 0x0, ++ "Indicates if the SRS request parameter is valid", HFILL } ++ }, ++ { &hf_nfapi_srs_request, ++ { "SRS request", "nfapi.srs.request", ++ FT_BOOLEAN, 8, TFS(&srs_request_strname), 0x0, ++ "SRS request flag", HFILL } ++ }, ++ { &hf_nfapi_antenna_ports_scrambling_and_layers, ++ { "Antenna ports scrambling and layers", "nfapi.antenna.ports.scrambling.and.layers", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the Antenna port, scrambling identity value NSCID and number of layers", HFILL } ++ }, ++ { &hf_nfapi_total_dci_length_including_padding, ++ { "Total DCI length including padding", "nfapi.total.dci.length.including.padding", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The total DCI length including padding bits", HFILL } ++ }, ++ { &hf_nfapi_n_ul_rb, ++ { "N_UL_RB", "nfapi.n.dl.rb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "BW of serving cell for which the DCI was scheduled for. This is valid for " ++ "the case of cross carrier scheduling, for the case of a self - " ++ "scheduling(cross carrier scheduling is not valid or Carrier indicator has value '0', " ++ "the BW is the 'DL BW support' as configured in configuration phase(params) " ++ "Uplink channel bandwidth in resource blocks", HFILL } ++ }, ++ { &hf_nfapi_harq_ack_resource_offset, ++ { "HARQ-ACK resource offset", "nfapi.harq.ack.resource.offset", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ-ACK resource offset field is present only when this format is carried by EPDCCH.", HFILL } ++ }, ++ { &hf_nfapi_pdsch_re_mapping_and_quasi_co_location_indicator, ++ { "PDSCH RE Mapping and Quasi-Co-Location Indicator", "nfapi.pdsch.re.mapping", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the parameter set configured by the higher layers which the UE should use.", HFILL } ++ }, ++ { &hf_nfapi_primary_cell_type, ++ { "Primary cell type", "nfapi.primary.cell.type", ++ FT_UINT8, BASE_DEC, VALS(primary_cells_type_vals), 0x0, ++ "Indicates the type of the primary cell.", HFILL } ++ }, ++ { &hf_nfapi_ul_dl_configuration_flag, ++ { "UL/DL configuration flag", "nfapi.ul.dl.configuration.flag", ++ FT_BOOLEAN, 8, TFS(&ul_dl_configuration_flag_strname), 0x0, ++ "Indicates if format 1C is being used to signal UL/DL configuration", HFILL } ++ }, ++ { &hf_nfapi_number_of_ul_dl_configurations, ++ { "Number of UL/DL configurations", "nfapi.number.ul.dl.configurations", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_dl_configuration_index, ++ { "UL/DL configuration indication", "nfapi.ul.dl.configuration.indication", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "UL/DL configuration index", HFILL } ++ }, ++ { &hf_nfapi_laa_end_partial_sf_flag, ++ { "LAA end partial SF flag", "nfapi.laa.end.partial.sf.flag", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if DCI format 1C is being used to signal LAA end partial SF (valid if end partial SF support configuraton is set)", HFILL } ++ }, ++ { &hf_nfapi_laa_end_partial_sf_configuration, ++ { "LAA end partial SF configuration", "nfapi.laa.end.partial.sf.configuration", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "If DCI format 1C scrambled by CC - RNTI is used to signal end partial SF, this field " ++ "contains LAA common information (4 bits used in [9] Table 13A-1 for configuration of " ++ "occupied OFDM symbols for current and next SF)", HFILL } ++ }, ++ { &hf_nfapi_codebooksize_determination_r13, ++ { "Codebook Size Determination R13", "nfapi.codebook.size.determination.r13", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if the downlink assignment index parameter (DAI) is 4 bits", HFILL } ++ }, ++ { &hf_nfapi_rel13_drms_table_flag, ++ { "Rel-13-DMRS-tabe flag", "nfapi.drms.table.flag.r13", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if Release 13 DMRS table for be used", HFILL } ++ }, ++ { &hf_nfapi_pscch_resource, ++ { "PSCCH Resource", "nfapi.pscch.resource", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "6-bits describing the resource blocks for transmitting PSCCH", HFILL } ++ }, ++ { &hf_nfapi_time_resource_pattern, ++ { "Time resource pattern", "nfapi.time.resource.pattern", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "7-bits describing the time resource pattern index", HFILL } ++ }, ++ { &hf_nfapi_mpdcch_transmission_type, ++ { "MPDCCH transmission type", "nfapi.mpdcch.transmission.type", ++ FT_UINT8, BASE_DEC, VALS(local_distributed_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_drms_scrambling_init, ++ { "DMRS scrambling init", "nfapi.drms.scrambling.init", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The DMRS scrambling sequence initialization", HFILL } ++ }, ++ { &hf_nfapi_pusch_repetition_levels, ++ { "PUSCH repetition levels", "nfapi.pusch.repetition.levels", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid for DCI formats: 6-0A, 6-0B", HFILL } ++ }, ++ { &hf_nfapi_frequency_hopping_flag, ++ { "Frequency hopping flag", "nfapi.frequency.hopping.flag", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if hopping is being used.", HFILL } ++ }, ++ { &hf_nfapi_csi_request, ++ { "CSI request", "nfapi.csi.request", ++ FT_UINT8, BASE_DEC, VALS(csi_request_vals), 0x0, ++ "Aperiodic CSI request flag", HFILL } ++ }, ++ { &hf_nfapi_dai_presence_flag, ++ { "DAI presence flag", "nfapi.dia.presence.flag", ++ FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x0, ++ "Indicates if DL assignment index field is present in the DCI", HFILL } ++ }, ++ { &hf_nfapi_total_dci_length_include_padding, ++ { "Total DCI length including padding", "nfapi.total.dci.length.including.padding", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The total DCI length including padding bits", HFILL } ++ }, ++ { &hf_nfapi_csi_rs_antenna_port_count_r10, ++ { "CSI-RS antenna port count r10", "nfapi.csi.rs.antenna.port.count.r10", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates number of antennas used for transmission of CSI reference signal.", HFILL } ++ }, ++ { &hf_nfapi_ul_config_pdu_type, ++ { "UL Config PDU Type", "nfapi.ul.config.pdu.type", ++ FT_UINT8, BASE_DEC, VALS(nfapi_ul_config_pdu_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_rach_prach_frequency_resources, ++ { "RACH PRACH Frequency resources", "nfapi.rach.prach.frequency.resources", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "If semi-static information is held in the MAC", HFILL } ++ }, ++ { &hf_nfapi_srs_present, ++ { "SRS present", "nfapi.srs.present", ++ FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x0, ++ "If semi-static information is held in the MAC", HFILL } ++ }, ++ { &hf_nfapi_handle, ++ { "Handle", "nfapi.handle", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "An opaque handle", HFILL } ++ }, ++ { &hf_nfapi_pucch_index, ++ { "PUCCH Index", "nfapi.pucch.index", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PUCCH index value", HFILL } ++ }, ++ { &hf_nfapi_size, ++ { "Size", "nfapi.size", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The size of the ULSCH PDU in bytes as defined by the relevant UL grant", HFILL } ++ }, ++ { &hf_nfapi_resource_block_start, ++ { "Resource block start", "nfapi.resource.block.start", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The starting resource block for this ULSCH allocation", HFILL } ++ }, ++ { &hf_nfapi_number_of_resource_blocks, ++ { "Number of resource blocks", "nfapi.resource.blocks", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of resource blocks allocated to this ULSCH grant", HFILL } ++ }, ++ { &hf_nfapi_cyclic_shift_2_for_drms, ++ { "Cyclic Shift 2 for DRMS", "nfapi.cyclic.shift.2.for.drms", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The 2nd cyclic shift for DMRS assigned to the UE in the ULSCH grant", HFILL } ++ }, ++ { &hf_nfapi_frequency_hopping_enabled_flag, ++ { "Frequency hopping enabled flag", "nfapi.frequency.hopping.enabled.flag", ++ FT_UINT8, BASE_DEC, VALS(hopping_vals), 0x0, ++ "Indicates if hopping is being used", HFILL } ++ }, ++ { &hf_nfapi_frequency_hopping_bits, ++ { "Frequency hopping bits", "nfapi.frequency.hopping.bits", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_new_data_indication, ++ { "New Data inidication", "nfapi.new.data.indication", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Specify whether this received transport block is a new transmission from UE", HFILL } ++ }, ++ { &hf_nfapi_harq_process_number, ++ { "HARQ Process number", "nfapi.harq.process.number", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_ul_tx_mode, ++ { "UL Tx Mode", "nfapi.ul.tx.mode", ++ FT_UINT8, BASE_DEC, VALS(ul_tx_mode_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_current_tx_nb, ++ { "Current Tx nb", "nfapi.current.tx.nb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The current HARQ transmission count of this transport block. Valid if frequency hopping enabled.", HFILL } ++ }, ++ { &hf_nfapi_n_srs, ++ { "N SRS", "nfapi.n.srs", ++ FT_UINT8, BASE_DEC, VALS(n_srs_vals), 0x0, ++ "Indicates if the resource blocks allocated for this grant overlap with the SRS configuration.", HFILL } ++ }, ++ { &hf_nfapi_disable_sequence_hopping_flag, ++ { "Disable seqeunce hopping flag", "nfapi.disable.sequence.hopping.flag", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if any configured group hopping should be disabled for this UE.", HFILL } ++ }, ++ { &hf_nfapi_virtual_cell_id_enabled_flag, ++ { "Virtual cell ID enabled flag", "nfapi.virtual.cell.id.enabled.flag", ++ FT_UINT8, BASE_DEC, VALS(not_used_enabled_vals), 0x0, ++ "Indicates if virtual cell is being used and nPUSCH identity is valid.", HFILL } ++ }, ++ { &hf_nfapi_npusch_identity, ++ { "nPUSCH Identity", "nfapi.npusch.identity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Virtual cell ID for initialization of group hopping, sequence hopping and sequence shift pattern of PUSCH DMRS.", HFILL } ++ }, ++ { &hf_nfapi_ndrms_csh_identity, ++ { "nDMRS-CSH Identity", "nfapi.ndrms.csh.identity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Virtual cell ID for initialization of cyclic shift hopping of PUSCH DMRS.", HFILL } ++ }, ++ { &hf_nfapi_total_number_of_repetitions, ++ { "Total Number of repetitions", "nfapi.total.number.of.repetitions", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_repetition_number, ++ { "Repetition Number", "nfapi.repetition.number", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Current transmission number", HFILL } ++ }, ++ { &hf_nfapi_initial_sf_io, ++ { "Initial transmission SF (io)", "nfapi.initial.sf.io", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Absolute Sub-Frame of the initial transmission", HFILL } ++ }, ++ { &hf_nfapi_empty_symbols_due_to_retunning, ++ { "Empy symbols due to re-tunning", "nfapi.empty.symbols.due.to.retunning", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the symbols that are left empty due to eMTC retuning.", HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_ri_pmi_size_2, ++ { "DL CQI/PMI/RI size 2", "nfapi.dl.cqi.ri.pmi.size.2", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI/RI in bits. If the CQI/PMI/RI size exceeds 255 (8-bits) then the Release 9 size value = 0, and this field is used instead.", HFILL } ++ }, ++ { &hf_nfapi_harq_size_2, ++ { "HARQ Size 2", "nfapi.harq.size2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the ACK/NACK in bits.", HFILL } ++ }, ++ { &hf_nfapi_delta_offset_harq_2, ++ { "Delta Offset HARQ 2", "nfapi.delta.offset.harq.2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Delta offset 2 for HARQ. This value is fixed for a UE, allocated in RRC connection setup and used for ACK_NACK mode = 4 or 5", HFILL } ++ }, ++ { &hf_nfapi_starting_prb, ++ { "Starting PRB", "nfapi.starting.prb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The starting PRB for the PUCCH", HFILL } ++ }, ++ { &hf_nfapi_antenna_port, ++ { "Antenna Port", "nfapi.antenna.port", ++ FT_UINT8, BASE_DEC, VALS(antenna_ports_vals), 0x0, ++ "Defines the number of antenna ports used by the UE for the SRS. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_number_of_combs, ++ { "Number of Combs", "nfapi.num.of.combs", ++ FT_UINT8, BASE_DEC, VALS(combs_vals), 0x0, ++ "Defines the maximum number of transmission combs (TC).", HFILL } ++ }, ++ { &hf_nfapi_npucch_identity, ++ { "nPUCCH Identity", "nfapi.npucch.identity", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Virtual cell ID for initialization of base sequence and cyclic shift hopping of PUCCH.", HFILL } ++ }, ++ { &hf_nfapi_empty_symbols, ++ { "Empty symbols", "nfapi.empty.symbols", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates the symbols that are left empty due to eMTC retuning.", HFILL } ++ }, ++ { &hf_nfapi_csi_mode, ++ { "CSI_mode", "nfapi.csi.mode", ++ FT_UINT8, BASE_DEC, VALS(csi_mode_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_pmi_size_2, ++ { "DL CQI/PMI Size 2", "nfapi.dl.cqi.pmi.size.2", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI in bits", HFILL } ++ }, ++ { &hf_nfapi_statring_prb, ++ { "Starting PRB", "nfapi.starting.prb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The starting PRB for the PUCCH", HFILL } ++ }, ++ { &hf_nfapi_cdm_index, ++ { "cdm_Index", "nfapi.cdm.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Selected CDM option", HFILL } ++ }, ++ { &hf_nfapi_nsrs, ++ { "N srs", "nfapi.n.srs", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if the resource blocks allocated for this grant overlap with the SRS configuration.", HFILL } ++ }, ++ { &hf_nfapi_num_ant_ports, ++ { "Num_ant_ports", "nfapi.num.ant.port", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of antenna ports used by the UE transmit", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_2_0, ++ { "n_PUCCH_2_0", "nfapi.n.pucch.2.0", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PUCCH Index value for ACK/NACK HARQ resource 4 on antenna port", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_2_1, ++ { "n_PUCCH_2_1", "nfapi.n.pucch.2.1", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "HARQ resource 5", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_2_2, ++ { "n_PUCCH_2_2", "nfapi.n.pucch.2.2", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "HARQ resource 6", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_2_3, ++ { "n_PUCCH_2_3", "nfapi.n.pucch.2.3", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "HARQ resource 7", HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_pmi_size_rank_1, ++ { "DL CQI PMI size rank 1", "nfapi.dl.cqi.pmi.size.rank.1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI in bits in case of rank 1 report.", HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_pmi_size_rank_greater_1, ++ { "DL CQI PMI size rank greater 1", "nfapi.dl.cqi.pmi.size.rank.1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI in bits in case of rank>1 report.", HFILL } ++ }, ++ { &hf_nfapi_ri_size, ++ { "RI size", "nfapi.ri.size", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of RI in bits", HFILL } ++ }, ++ { &hf_nfapi_delta_offset_cqi, ++ { "Delta offset cqi", "nfapi.delta.offset.cqi", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Delta offset for CQI. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_delta_offset_ri, ++ { "Delta offset ri", "nfapi.delta.offset.ri", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Delta offset for RI. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_harq_size, ++ { "HARQ size", "nfapi.harq_size", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the ACK/NACK in bits", HFILL } ++ }, ++ { &hf_nfapi_delta_offset_harq, ++ { "Delta offset HARQ", "nfapi.delta.offset.harq", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Delta offset for HARQ. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_tdd_ack_nack_mode, ++ { "ACK NACK mode", "nfapi.tdd.ack.nack.mode", ++ FT_UINT8, BASE_DEC, VALS(nfapi_tdd_ack_nack_mode_vals), 0x0, ++ "The format of the ACK/NACK response expected. For TDD only.", HFILL } ++ }, ++ { &hf_nfapi_fdd_ack_nack_mode, ++ { "ACK NACK mode", "nfapi.fdd.ack.nack.mode", ++ FT_UINT8, BASE_DEC, VALS(nfapi_fdd_ack_nack_mode_vals), 0x0, ++ "The format of the ACK/NACK response expected. For TDD only.", HFILL } ++ }, ++ { &hf_nfapi_n_srs_initial, ++ { "N srs initial", "nfapi.n.srs.initial", ++ FT_UINT8, BASE_DEC, VALS(n_srs_initial_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_initial_number_of_resource_blocks, ++ { "Initial number of resource blocks", "nfapi.initial.number.of.resource.blocks", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of resource blocks used in the initial transmission of this transport block.", HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_pmi_size, ++ { "DL cqi pmi size", "nfapi.dl.cqi.pmi.size", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI in bits in case of this RI value. The size of the DL CQI / PMI / RI in bits in case of this CRI value", HFILL } ++ }, ++ { &hf_nfapi_report_type, ++ { "Report type", "nfapi.report.type", ++ FT_BOOLEAN, 8, TFS(&nfapi_csi_report_type_strname), 0x0, ++ "Type of CSI report", HFILL } ++ }, ++ { &hf_nfapi_dl_cqi_ri_pmi_size, ++ { "DL CQI/PMI/RI size", "nfapi.dl.cqi.ri.pmi.size", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The size of the DL CQI/PMI/RI/CRI in bits", HFILL } ++ }, ++ { &hf_nfapi_control_type, ++ { "Control type", "nfapi.control.type", ++ FT_BOOLEAN, 8, TFS(&nfapi_control_type_string_name), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_number_of_cc, ++ { "Number of cc", "nfapi.number.of.cc", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of CC in the aperiodic report", HFILL } ++ }, ++ { &hf_nfapi_number_of_pucch_resource, ++ { "Number of PUCCH Resource", "nfapi.number.of.pucch.resource", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "A value of 2 indicates that the UE is configured to transmit on two antenna ports", HFILL } ++ }, ++ { &hf_nfapi_pucch_index_p1, ++ { "PUCCH Index P1", "nfapi.pucch.index.p1", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PUCCH index value for antenna port P1", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_1_0, ++ { "N PUCCH 1 0", "nfapi.n.pucch.1.0", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ resource 0", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_1_1, ++ { "N PUCCH 1 1", "nfapi.n.pucch.1.1", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ resource 1", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_1_2, ++ { "N PUCCH 1 2", "nfapi.n.pucch.1.2", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ resource 2", HFILL } ++ }, ++ { &hf_nfapi_n_pucch_1_3, ++ { "N PUCCH 1 3", "nfapi.n.pucch.1.3", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "HARQ resource 3", HFILL } ++ }, ++ { &hf_nfapi_srs_bandwidth, ++ { "SRS Bandwidth", "nfapi.srs.bandwidth", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "SRS Bandwidth. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_frequency_domain_position, ++ { "Frequency Domain position", "nfapi.frequency.domain.position", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Frequency-domain position, NRRC This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_srs_hopping_bandwidth, ++ { "SRS hopping bandwidth", "nfapi.srs.hopping.bandwidth", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Configures the frequency hopping on the SRS. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_transmission_comb, ++ { "Transmission comb", "nfapi.transmission.comb", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Configures the frequency location of the SRS. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_i_srs, ++ { "I SRS", "nfapi.i.srs", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Defines the periodicity and subframe location of the SRS. SRS Configuration Index. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_sounding_reference_cyclic_shift, ++ { "Sounding reference cyclic shift", "nfapi.sounding.reference.cyclic.shift", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Configures the SRS sequence generation. This value is fixed for a UE and allocated in RRC connection setup.", HFILL } ++ }, ++ { &hf_nfapi_pdu_length, ++ { "PDU length", "nfapi.pdu.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The total length (in bytes) of the PDU description and PDU data, without the padding bytes", HFILL } ++ }, ++ { &hf_nfapi_crc_flag, ++ { "CRC flag", "nfapi.crc.flag", ++ FT_BOOLEAN, 8, TFS(&crc_flag_strname), 0x0, ++ "A flag indicating if a CRC error was detected", HFILL } ++ }, ++ { &hf_nfapi_number_of_hi_pdus, ++ { "Number of HI Pdu's", "nfapi.number_of_hi_pdus", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of HI PDUs included in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_dci_pdus, ++ { "Number of DCI Pdu's", "nfapi.number_of_dci_pdus", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of DCI PDUs included in this message", HFILL } ++ }, ++ { &hf_nfapi_hi_dci0_pdu_type, ++ { "PDU Type", "nfapi.pdu_type", ++ FT_UINT8, BASE_DEC, VALS(hi_dci0_pdu_type_vals), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_hi_value, ++ { "HI Value", "nfapi.hi_value", ++ FT_BOOLEAN, 8, TFS(&hi_value_strname), 0x0, ++ "The PHICH value which is sent on the resource", HFILL } ++ }, ++ { &hf_nfapi_i_phich, ++ { "i phich", "nfapi.i_phich", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Is used in the calculation of the PHICH location. For TDD only", HFILL } ++ }, ++ { &hf_nfapi_flag_tb2, ++ { "Flag TB2", "nfapi.flag_tb2", ++ FT_BOOLEAN, BASE_NONE, TFS(&flag_tb2_strname), 0x0, ++ "Indicates is HI is present for a second transport block", HFILL } ++ }, ++ { &hf_nfapi_hi_value_2, ++ { "HI Value 2", "nfapi.hi_value_2", ++ FT_BOOLEAN, BASE_NONE, TFS(&hi_value_strname), 0x0, ++ "The PHICH value for a second transport block.", HFILL } ++ }, ++ { &hf_nfapi_ue_tx_antenna_selection, ++ { "UE Tx Antenna selection", "nfapi.ue_tx_antenna_selection", ++ FT_UINT8, BASE_DEC, VALS(ue_tx_antenna_selection_vals), 0x0, ++ "Indicates how the CRC is calculated on the PDCCH.", HFILL } ++ }, ++ { &hf_nfapi_cqi_csi_request, ++ { "cqi csi request", "nfapi.cqi_csi_request", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Aperiodic CQI request flag", HFILL } ++ }, ++ { &hf_nfapi_ul_index, ++ { "UL index", "nfapi.ul_index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid for TDD mode only", HFILL } ++ }, ++ { &hf_nfapi_dl_assignment_index, ++ { "DL Assignment index", "nfapi.dl_assignment_index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Valid for TDD mode only.", HFILL } ++ }, ++ { &hf_nfapi_tpc_bitmap, ++ { "TPC bitmap", "nfapi.tpc_bitmap", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "TPC commands for PUCCH and PUSCH", HFILL } ++ }, ++ { &hf_nfapi_number_of_antenna_ports, ++ { "Number of antenna ports", "nfapi.number.of.antenna.ports", ++ FT_UINT8, BASE_DEC, VALS(number_of_antenna_port_vals), 0x0, ++ "Defines number of antenna ports for this ULSCH allocation", HFILL } ++ }, ++ { &hf_nfapi_size_of_cqi_csi_feild, ++ { "Size of cqi csi feild", "nfapi.size.of.cqi.csi.feild", ++ FT_UINT8, BASE_DEC, VALS(size_of_cqi_csi_feild_vals), 0x0, ++ "Indicates the size of the CQI/CSI request field", HFILL } ++ }, ++ { &hf_nfapi_new_data_indication_two, ++ { "New data indication 2", "nfapi.new.data.indication.two", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The new data indicator for the second transport block", HFILL } ++ }, ++ { &hf_nfapi_resource_allocation_flag, ++ { "Resource allocation flag", "nfapi.resource.allocation.flag", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Indicates if the Resource Allocation Type parameter is valid.", HFILL } ++ }, ++ { &hf_nfapi_dl_node_sync_t1, ++ { "DL Node Sync t1", "nfapi.dl.node.sync.t1", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "Offset from VNF SFN/SF 0/0 time reference of the DL Node Sync message transmission at the transport layer, in microseconds.", HFILL } ++ }, ++ { &hf_nfapi_dl_node_sync_delta_sfn_sf, ++ { "DL Node Sync Delta SFN SF", "nfapi.dl.node.sync.delta_sfn_sf", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The delta shift in subframes that the PNF PHY instance must update to on the next subframe boundary", HFILL } ++ }, ++ { &hf_nfapi_dl_cyclic_prefix_type, ++ { "DL Cyclic Prefix type", "nfapi.dl.cyclic.prefix.type", ++ FT_BOOLEAN, 8, TFS(&cyclic_prefix_type_strname), 0x0, ++ "Cyclic prefix type, used for DL", HFILL } ++ }, ++ { &hf_nfapi_ul_cyclic_prefix_type, ++ { "UL Cyclic Prefix type", "nfapi.ul.cyclic.prefix.type", ++ FT_BOOLEAN, 8, TFS(&cyclic_prefix_type_strname), 0x0, ++ "Cyclic prefix type, used for UL", HFILL } ++ }, ++ { &hf_nfapi_downlink_channel_bandwidth, ++ { "Downlink Channel Bandwidth", "nfapi.dl.channel.bandwidth", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Downlink channel bandwidth in resource blocks.", HFILL } ++ }, ++ { &hf_nfapi_uplink_channel_bandwidth, ++ { "Uplink Channel Bandwidth", "nfapi.ul.channel_bandwidth", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Uplink channel bandwidth in resource blocks.", HFILL } ++ }, ++ { &hf_nfapi_tx_antenna_ports, ++ { "Tx Antenna Ports", "nfapi.tx.antenna.ports", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of cell specific or NB transmit antenna ports.", HFILL } ++ }, ++ { &hf_nfapi_rx_antenna_ports, ++ { "Tx Antenna Ports", "nfapi.rx.antenna.ports", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of cell specific or NB receive antenna ports.", HFILL } ++ }, ++ { &hf_nfapi_ul_node_sync_t1, ++ { "UL Node Sync t1", "nfapi.ul.node.sync.t1", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The supplied t1 field in the DL Node Sync", HFILL } ++ }, ++ { &hf_nfapi_ul_node_sync_t2, ++ { "UL Node Sync t2", "nfapi.ul.node.sync.t2", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "Offset from PNF SFN/SF 0/0 time reference of the DL Node Sync message reception at the transport layer, in microseconds.", HFILL } ++ }, ++ { &hf_nfapi_ul_node_sync_t3, ++ { "UL Node Sync t3", "nfapi.ul.node.sync.t3", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "Offset from PNF SFN/SF 0/0 time reference of the UL Node Sync message transmission at the transport layer, in microseconds.", HFILL } ++ }, ++ { &hf_nfapi_pb, ++ { "P-B", "nfapi.pb.allocation", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Refers to downlink power allocation. Value is an index into the referenced table.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_last_sfn_sf, ++ { "Last SFN/SF", "nfapi.timing.info.last.sfn.sf", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The completed SFN/SF at the PNF PHY instance that triggered the Timing Info message", HFILL } ++ }, ++ { &hf_nfapi_timing_info_time_since_last_timing_info, ++ { "Time since last Timing Info", "nfapi.timing.info.time.since.last.timing.info", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The number of ms since the last Timing Info was sent from this PNF PHY instance.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_dl_config_jitter, ++ { "DL Config Jitter", "nfapi.timing.info.dl.config.jitter", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The inter message jitter of the DL Config message reception in microseconds", HFILL } ++ }, ++ { &hf_nfapi_timing_info_tx_request_jitter, ++ { "Tx Request Jitter", "nfapi.timing.info.tx.req.jitter", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The inter message jitter of the Tx Request message reception in microseconds", HFILL } ++ }, ++ { &hf_nfapi_timing_info_ul_config_jitter, ++ { "UL Config Jitter", "nfapi.timing.info.ul.config.jitter", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The inter message jitter of the UL Config message reception in microseconds", HFILL } ++ }, ++ { &hf_nfapi_timing_info_hi_dci0_jitter, ++ { "HI_DCI0 Jitter", "nfapi.timing.info.hi.dci0.jitter", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The inter message jitter of the HI_DCI0 message reception in microseconds", HFILL } ++ }, ++ { &hf_nfapi_timing_info_dl_config_latest_delay, ++ { "DL Config Latest Delay", "nfapi.timing.info.dl.config.latest.delay", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The latest delay offset in microseconds from the latest acceptable time for the DL Config as defined in the DL Config Timing in the PNF_PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_tx_request_latest_delay, ++ { "Tx Request Latest Delay", "nfapi.timing.info.tx.request.latest.delay", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The latest delay offset in microseconds from the latest acceptable time for the Tx Request as defined in the Tx Config Timing in the PNF_PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_ul_config_latest_delay, ++ { "UL Config Latest Delay", "nfapi.timing.info.ul.config.latest.delay", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The latest delay offset in microseconds from the latest acceptable time for the UL Config as defined in the UL Config Timing in the PNF_PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_hi_dci0_latest_delay, ++ { "HI_DCI0 Latest Delay", "nfapi.timing.info.hi.dci0.latest.delay", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The latest delay offset in microseconds from the latest acceptable time for the HI_DCI0 as defined in the HI_DCI0 Timing in the PNF_PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_dl_config_earliest_arrival, ++ { "DL Config Earliest Arrival", "nfapi.timing.info.dl.config.earliest.arrival", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The earlierst arrival offset in microseconds from the latest time acceptable for the DL Config as defined in the Timing Window in the PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_tx_request_earliest_arrival, ++ { "Tx Request Earliest Arrival", "nfapi.timing.info.tx.request.earliest.arrival", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The earlierst arrival offset in microseconds from the latest time acceptable for the Tx Request as defined in the Timing Window in the PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_ul_config_earliest_arrival, ++ { "UL Config Earliest Arrival", "nfapi.timing.info.ul.config.earliest.arrival", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The earlierst arrival offset in microseconds from the latest time acceptable for the UL Config as defined in the Timing Window in the PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_hi_dci0_earliest_arrival, ++ { "HI_DCI0 Earliest Arrival", "nfapi.timing.info.hi.dci0.earliest.arrival", ++ FT_INT32, BASE_DEC, NULL, 0x0, ++ "The earlierst arrival offset in microseconds from the latest time acceptable for the HI_DCI0 as defined in the Timing Window in the PARAM.Response since the last transmission of the Timing Info Message.", HFILL } ++ }, ++ { &hf_nfapi_pcfich_power_offset, ++ { "PCFICH Power Offset", "nfapi.pcfich.power.offset", ++ FT_UINT16, BASE_CUSTOM, CF_FUNC(power_offset_conversion_fn), 0x0, ++ "The power per antenna of the PCFICH with respect to the reference signal.", HFILL } ++ }, ++ { &hf_nfapi_timing_window, ++ { "NFAPI Timing window", "nfapi.timing.window", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The window in milliseconds that the PHY must receive and queue the P7 messages.", HFILL } ++ }, ++ { &hf_nfapi_timing_info_mode, ++ { "Timing Info mode", "nfapi.timing.info.mode", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The configured mode of operation for the timing info message to be sent to the VNF from the PHY", HFILL } ++ }, ++ { &hf_nfapi_timing_info_period, ++ { "Timing info period", "nfapi.timing.info.period", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "If Periodic timing mode is enabled, this defines the periodicity in subframes. This field is ignored if periodic timing mode is disabled.", HFILL } ++ }, ++ { &hf_nfapi_tdd_harq_mode, ++ { "Mode", "nfapi.tdd.harq.mode", ++ FT_UINT8, BASE_DEC, VALS(tdd_harq_mode_vals), 0x0, ++ "The format of the ACK/NACK response expected", HFILL } ++ }, ++ { &hf_nfapi_fdd_harq_mode, ++ { "Mode", "nfapi.fdd.harq.mode", ++ FT_UINT8, BASE_DEC, VALS(fdd_harq_mode_vals), 0x0, ++ "The format of the ACK/NACK response expected", HFILL } ++ }, ++ { &hf_nfapi_number_of_ack_nack, ++ { "Number of ACK/NACK", "nfapi.uint16.tag", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of ACK/NACK results reported for this UE", HFILL } ++ }, ++ { &hf_nfapi_harq_data_value_0, ++ { "Value 0", "nfapi.harq.value.0", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "Indicates HARQ results", HFILL } ++ }, ++ { &hf_nfapi_harq_data_value_0_special, ++ { "Value 0", "nfapi.harq.value.0.special", ++ FT_UINT8, BASE_DEC, VALS(harq_special_value_vals), 0x0, ++ "Indicates HARQ results", HFILL } ++ }, ++ { &hf_nfapi_harq_data_value_1, ++ { "Value 1", "nfapi.harq.value.1", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "Indicates HARQ results", HFILL } ++ }, ++ { &hf_nfapi_harq_data_value_2, ++ { "Value 2", "nfapi.harq.value.2", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "Indicates HARQ results", HFILL } ++ }, ++ { &hf_nfapi_harq_data_value_3, ++ { "Value 3", "nfapi.harq.value.3", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "Indicates HARQ results", HFILL } ++ }, ++ { &hf_nfapi_harq_tb_1, ++ { "HARQ TB1", "nfapi.harq.tb.", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "HARQ feedback of 1st TB.", HFILL } ++ }, ++ { &hf_nfapi_harq_tb_2, ++ { "HARQ TB2", "nfapi.harq.tb.2", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "HARQ feedback of 2nd TB.", HFILL } ++ }, ++ { &hf_nfapi_harq_tb_n, ++ { "HARQ TB_N", "nfapi.harq.tb.n", ++ FT_UINT8, BASE_DEC, VALS(harq_value_vals), 0x0, ++ "HARQ feedback of Nth TB.", HFILL } ++ }, ++ { &hf_nfapi_ul_cqi, ++ { "UL_CQI", "nfapi.ul.cqi", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(ul_cqi_conversion_fn), 0x0, ++ "SNR", HFILL } ++ }, ++ { &hf_nfapi_channel, ++ { "Channel", "nfapi.channel", ++ FT_UINT8, BASE_DEC, VALS(channel_vals), 0x0, ++ "The channel to which this measurement refers", HFILL } ++ }, ++ { &hf_nfapi_data_offset, ++ { "Data Offset", "nfapi.data.offset", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Gives the PDU#i data address offset from the beginning of the 'Number of PDUs' field. An offset of 0 indicates a CRC or decoding error", HFILL } ++ }, ++ { &hf_nfapi_ri, ++ { "RI", "nfapi.ri", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The rank indication reported by the UE on PUSCH for aperiodic CSI.", HFILL } ++ }, ++ { &hf_nfapi_timing_advance, ++ { "Timing Advance", "nfapi.timing.advance", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The timing advance measured for this PDU and UE.", HFILL } ++ }, ++ { &hf_nfapi_timing_advance_r9, ++ { "Timing Advance R9", "nfapi.timing.advance.r9", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Timing advance used for positioning", HFILL } ++ }, ++ { &hf_nfapi_number_of_cc_reported, ++ { "Number of CC reported", "nfapi.number.of.cc.reported", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_preamble, ++ { "Preamble", "nfapi.preamble", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The detected preamble", HFILL } ++ }, ++ { &hf_nfapi_rach_resource_type, ++ { "RACH resource type", "nfapi.rach.resource.type", ++ FT_UINT8, BASE_DEC, VALS(rach_resource_type_vals), 0x0, ++ "Indicates if this indication is related to Cat-M UE and in which CE level", HFILL } ++ }, ++ { &hf_nfapi_doppler_estimation, ++ { "Doppler estimation", "nfapi.doppler.estimation", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "FFS", HFILL } ++ }, ++ { &hf_nfapi_rb_start, ++ { "RB Start", "nfapi.rb.start", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The starting point of the RBs to be reported", HFILL } ++ }, ++ { &hf_nfapi_snr, ++ { "SNR", "nfapi.snr", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(ul_cqi_conversion_fn), 0x0, ++ "Field size dependent on configured bandwidth SNR for RBs, each RBs report one SNR.", HFILL } ++ }, ++ { &hf_nfapi_up_pts_symbol, ++ { "UpPTS Symbol", "nfapi.uppts.symbol", ++ FT_UINT8, BASE_DEC, VALS(up_pts_symbol_vals), 0x0, ++ "Indicates symbol where SRS was received. Only valid if the SRS was received in subframe 1 or 6.", HFILL } ++ }, ++ { &hf_nfapi_number_prb_per_subband, ++ { "numPRBperSubband", "nfapi.num.prb.per.subband", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of PRBs that are treated as one subband", HFILL } ++ }, ++ { &hf_nfapi_number_antennas, ++ { "numAntennas", "nfapi.num.antennas", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Number of physical antennas", HFILL } ++ }, ++ { &hf_nfapi_subband_index, ++ { "subbandIndex", "nfapi.subband.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "Index of subband for which the following channel coefficient is applied", HFILL } ++ }, ++ { &hf_nfapi_channel_coefficient, ++ { "Channel", "nfapi.channel.coefficient", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Averaged channel coefficient in a subband for physical antenna #i, real 8 bits followed by imaginary 8 bits", HFILL } ++ }, ++ { &hf_nfapi_ul_rtoa, ++ { "UL_RTOA", "nfapi.ul.rtoa", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "UL relative time of arrival used for network based positioning", HFILL } ++ }, ++ { &hf_nfapi_frequency_band_indicator, ++ { "Frequency Band Indicator", "nfapi.frequency.band.indicator", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The E-UTRA band for which the carrierList applies.", HFILL } ++ }, ++ { &hf_nfapi_measurement_period, ++ { "Measurement Period", "nfapi.measurement.period", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The length of time to measure RSSI over, in units of 1ms.", HFILL } ++ }, ++ { &hf_nfapi_bandwidth, ++ { "Bandwidth", "nfapi.bandwidth", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The bandwidth (in resource blocks) over which the RSSI is measured.", HFILL } ++ }, ++ { &hf_nfapi_timeout, ++ { "Timeout", "nfapi.timeout", ++ FT_UINT32, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The timeout value after which the PNF should abort the procedure in units of 1ms. The value of 0 indicates that the PNF should attempt to complete the procedure without any VNF-imposed timeout.", HFILL } ++ }, ++ { &hf_nfapi_number_of_earfcns, ++ { "Number of EARFCNs", "nfapi.number.of.earfcns", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of EARFCNs which should be measured. In the case that no EARFCN (value 0) is specified, all valid EARFCNs for the specified bandwidth in the band shall be measured, in order of ascending EARCFN.", HFILL } ++ }, ++ { &hf_nfapi_uarfcn, ++ { "UARFCN", "nfapi.uarfcn", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "UARFCN to be measured.", HFILL } ++ }, ++ { &hf_nfapi_number_of_uarfcns, ++ { "Number of UARFCNs", "nfapi.number.of.uarfcn", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of UARFCNs which should be measured. In the case that no UARFCN (value 0) is specified, all UARFCNs in the band shall be measured, in order of ascending UARCFN.", HFILL } ++ }, ++ { &hf_nfapi_arfcn, ++ { "ARFCN", "nfapi.arfcn", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The ARFCN to be measured", HFILL } ++ }, ++ { &hf_nfapi_arfcn_direction, ++ { "Direction", "nfapi.arfcn.direction", ++ FT_UINT8, BASE_DEC, VALS(arfcn_direction_vals), 0x0, ++ "The link direction to be measured", HFILL } ++ }, ++ { &hf_nfapi_number_of_arfcns, ++ { "Number of ARFCNs", "nfapi.number.of.arfcn", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of ARFCNs which should be measured. In the case that no ARFCN (value 0) is specified, all ARFCNs in the band shall be measured, in order of ascending ARCFN.", HFILL } ++ }, ++ { &hf_nfapi_rssi, ++ { "RSSI", "nfapi.rssi", ++ FT_INT16, BASE_CUSTOM, CF_FUNC(rssi_conversion_fn), 0x0, ++ "The list of RSSI values of the carriers measured, in the order of the list of the original request.", HFILL } ++ }, ++ { &hf_nfapi_number_of_rssi, ++ { "Number of RSSI", "nfapi.number.of.rssi", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of RSSI results returned in the following array.", HFILL } ++ }, ++ { &hf_nfapi_pci, ++ { "PCI", "nfapi.pci", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PCI for cell which should be searched", HFILL } ++ }, ++ { &hf_nfapi_measurement_bandwidth, ++ { "Measurement Bandwidth", "nfapi.measurement.bandwidth", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of resource blocks which should be used for measuring RSRP", HFILL } ++ }, ++ { &hf_nfapi_exhaustive_search, ++ { "Exhaustive Search", "nfapi.exhaustive.search", ++ FT_UINT8, BASE_DEC, VALS(exhustive_search_vals), 0x0, ++ "NMM should try to find all cells on the carrier", HFILL } ++ }, ++ { &hf_nfapi_number_of_pci, ++ { "Number of PCI", "nfapi.number.of.pci", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of cells in the PCI list. If 0 all cells on the carrier should be found. Otherwise, depending on exhaustiveSearch flag, only the given pciList is searched or the pciList is used for indicating a priority list. Range: 0 to MAX_PCI_LIST.", HFILL } ++ }, ++ { &hf_nfapi_psc, ++ { "PSC", "nfapi.psc", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The PSC for cells which should be searched.", HFILL } ++ }, ++ { &hf_nfapi_number_of_psc, ++ { "Number of PSC", "nfapi.number.of.psc", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of cells in the PSC list. If 0 all cells on the carrier should be found. Otherwise, depending on Exhaustive Search flag, only the given PSC list is searched or the PSC list is used for indicating a priority list. Range: 0 to MAX_PSC_LIST.", HFILL } ++ }, ++ { &hf_nfapi_rsrp, ++ { "RSRP", "nfapi.rsrp", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(neg_pow_conversion_fn), 0x0, ++ "The measured RSRP value in units of -1dB", HFILL } ++ }, ++ { &hf_nfapi_rsrq, ++ { "RSRQ", "nfapi.rsrq", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(neg_pow_conversion_fn), 0x0, ++ "The measured RSRQ value in units of -1dB", HFILL } ++ }, ++ { &hf_nfapi_number_of_lte_cells_found, ++ { "Number of LTE Cells Found", "nfapi.number.of.lte.cells.found", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of LTE cells indicated in this message.", HFILL } ++ }, ++ { &hf_nfapi_rscp, ++ { "RSCP", "nfapi.rscp", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(neg_pow_conversion_fn), 0x0, ++ "The measured RSCP value in units of -1dB", HFILL } ++ }, ++ { &hf_nfapi_enco, ++ { "EcNo", "nfapi.ecno", ++ FT_UINT8, BASE_CUSTOM, CF_FUNC(neg_pow_conversion_fn), 0x0, ++ "The measured RSCP value in units of -1dB", HFILL } ++ }, ++ { &hf_nfapi_number_of_utran_cells_found, ++ { "Number of UTRAN Cells Found", "nfapi.number.of.utran.cells.found", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of LTE cells indicated in this message", HFILL } ++ }, ++ { &hf_nfapi_bsic, ++ { "BSIC", "nfapi.bsic", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The BSIC of the cell which the NMM synchronized to", HFILL } ++ }, ++ { &hf_nfapi_rxlev, ++ { "RxLev", "nfapi.rxlev", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The measured RxLev value", HFILL } ++ }, ++ { &hf_nfapi_rxqual, ++ { "RxQual", "nfapi.rxqual", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The measured RxQual value", HFILL } ++ }, ++ { &hf_nfapi_sfn_offset, ++ { "SFN Offset", "nfapi.sfn.offset", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "The offset in us of the start of the current GSM Radio HyperFrame (i.e. FN=0) from the start of the preceding LTE Radio Frame of the PNF for SFN=0", HFILL } ++ }, ++ { &hf_nfapi_number_of_geran_cells_found, ++ { "Number of GSM Cells Found", "nfapi.number.of.geran.cells.found", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The number of GSM cells indicated in this message", HFILL } ++ }, ++ { &hf_nfapi_number_of_tx_antenna, ++ { "Number of Tx Antenna", "nfapi.number.of.tx.antenna", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of Tx Antenna detected for the cell", HFILL } ++ }, ++ { &hf_nfapi_mib_length, ++ { "MIB Length", "nfapi.mib.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Length in bytes of the following MIB array", HFILL } ++ }, ++ { &hf_nfapi_mib, ++ { "MIB", "nfapi.mib", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "The MIB read from the specified cell.", HFILL } ++ }, ++ { &hf_nfapi_phich_configuration, ++ { "PHICH Configuration", "nfapi.phich.configuration", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The PHICH-Config of the cell", HFILL } ++ }, ++ { &hf_nfapi_retry_count, ++ { "retryCount", "nfapi.retry.count", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of SIB1 repetition periods for which decoding of SIB1 should be retried.", HFILL } ++ }, ++ { &hf_nfapi_sib1, ++ { "SIB1", "nfapi.sib1", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_si_periodicity, ++ { "SI Periodicity", "nfapi.si.periodicity", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The SI Periodicity of the requested SIBs, with the first element being for SIB2, the next for SIB3, etc, encoded as follows", HFILL } ++ }, ++ { &hf_nfapi_si_index, ++ { "SI Index", "nfapi.si.index", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The index of this SIB in the SIB1 SchedulingInfoList:", HFILL } ++ }, ++ { &hf_nfapi_number_of_si_periodicity, ++ { "Number of SI Periodicity", "nfapi.number.of.si.periodicity", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The number of System Information periodicity values in the following array", HFILL } ++ }, ++ { &hf_nfapi_si_window_length, ++ { "SI Window Length", "nfapi.si.window.length", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The SI window in units of 1ms", HFILL } ++ }, ++ { &hf_nfapi_sib_type, ++ { "SIB Type", "nfapi.sib.type", ++ FT_UINT8, BASE_DEC, NULL, 0x0, ++ "The SIB type", HFILL } ++ }, ++ { &hf_nfapi_sib_len, ++ { "SIB Length", "nfapi.sib.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The length in bytes of the following SIB array", HFILL } ++ }, ++ { &hf_nfapi_sib, ++ { "SIB", "nfapi.sib", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "The SIB element read from the specified cell.", HFILL } ++ }, ++ { &hf_nfapi_si_len, ++ { "SI Length", "nfapi.si.length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The length in bytes of the following SI array", HFILL } ++ }, ++ { &hf_nfapi_si, ++ { "SI", "nfapi.si", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "The SI element read from the specified cell.", HFILL } ++ }, ++ { &hf_nfapi_pnf_search_state, ++ { "State", "nfapi.state", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "A structure of opaque data optionally sent by the PNF to the VNF", HFILL } ++ }, ++ { &hf_nfapi_pnf_broadcast_state, ++ { "State", "nfapi.state", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "A structure of opaque data optionally sent by the PNF to the VNF", HFILL } ++ }, ++ { &hf_nfapi_dl_rs_tx_power, ++ { "DL RS Tx power", "nfapi.dl.rs.tx.power", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "The DL RS Tx power measurement", HFILL } ++ }, ++ { &hf_nfapi_received_interference_power, ++ { "Received interference power", "nfapi.received.interference.power", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The Received interference power measurement", HFILL } ++ }, ++ { &hf_nfapi_thermal_noise_power, ++ { "Thermal noise power", "nfapi.thermal.noise.power", ++ FT_UINT16, BASE_DEC | BASE_UNIT_STRING, &units_milliseconds, 0x0, ++ "The Thermal noise power measurement", HFILL } ++ }, ++ { &hf_nfapi_dl_rs_tx_power_measurement, ++ { "DL RS TX Power measurement", "nfapi.dl.rs.tx.power.measurement", ++ FT_INT16, BASE_CUSTOM, CF_FUNC(dl_rs_tx_pow_measment_conversion_fn), 0x0, ++ "The DL RS Tx power measurement defined", HFILL } ++ }, ++ { &hf_nfapi_received_interference_power_measurement, ++ { "Received interference power measurement", "nfapi.received.interference.power.measurement", ++ FT_INT16, BASE_CUSTOM, CF_FUNC(dl_rs_tx_pow_measment_conversion_fn), 0x0, ++ NULL, HFILL } ++ }, ++ { &hf_nfapi_thermal_noise_power_measurement, ++ { "Thermal noise power measurement", "nfapi.thermal.noise.power.measurement", ++ FT_INT16, BASE_CUSTOM, CF_FUNC(dl_rs_tx_pow_measment_conversion_fn), 0x0, ++ "The Thermal noise power measurement", HFILL } ++ }, ++ { &hf_nfapi_initial_partial_sf, ++ { "Initial Partial SF", "nfapi.initial.partial.sf", ++ FT_BOOLEAN, 32, TFS(&initial_partial_sf_strname), 0x0, ++ "Indicates whether the initial SF in the LBT process is full or partial", HFILL } ++ }, ++ { &hf_nfapi_lbt_mode, ++ { "LBT Mode", "nfapi.lbt.mode", ++ FT_BOOLEAN, 32, TFS(&lbt_mode_strname), 0x0, ++ "Part of multi-carrier support. Indicates whether full LBT process is carried or partial LBT process is carried (multi carrier mode B according to [9] section 15.1.5.2)", HFILL } ++ }, ++ { &hf_nfapi_lte_txop_sf, ++ { "LTE TXOP SF", "nfapi.txop.sf", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "Indicates the LTE TXOP (TMCOT,P in [9] section 15.1.1) duration in subframes.", HFILL } ++ }, ++ { &hf_nfapi_mp_cca, ++ { "mp cca", "nfapi.mp.cca", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "Indicates the value of the defer factor", HFILL } ++ }, ++ { &hf_nfapi_n_cca, ++ { "n cca", "nfapi.n.cca", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "Indicates the value of LBT backoff counter", HFILL } ++ }, ++ { &hf_nfapi_offset, ++ { "offset", "nfapi.offset", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "Indicates the LBT start time in microseconds from the beginning of the subframe scheduled by this message.", HFILL } ++ }, ++ { &hf_nfapi_result, ++ { "result", "nfapi.result", ++ FT_BOOLEAN, 32, TFS(&tfs_fail_success), 0x0, ++ "Indicates the LBT procedure result of SFN/SF:", HFILL } ++ }, ++ { &hf_nfapi_sfn_sf_end, ++ { "SFN/SF End", "nfapi.sfn.sf.end", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates the SFN/SF by which the DRS window (Discovery signal occasion as described in [9] section 6.11A) must end. In worst case, this would be the last TXOP subframe.", HFILL } ++ }, ++ { &hf_nfapi_txop_sfn_sf_end, ++ { "TXOP SFN/SF End", "nfapi.txop.sfn.sf.end", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Indicates the SFN/SF by which the TXOP must end. In worst case, this would be the last TXOP subframe.", HFILL } ++ }, ++ { &hf_nfapi_txop_symbols, ++ { "LTE TXOP symbols", "nfapi.lte.txop.symbols", ++ FT_UINT32, BASE_DEC, NULL, 0x0, ++ "Actual LTE TXOP in symbols", HFILL } ++ }, ++ }; ++ ++ /* Setup protocol subtree array */ ++ static gint *ett[] = ++ { ++ &ett_nfapi_message_tree, ++ &ett_nfapi_p4_p5_message_header, ++ &ett_nfapi_p7_message_header, ++ &ett_nfapi_tlv_tree, ++ &ett_nfapi_tl, ++ &ett_nfapi_pnf_phy_rf_config, ++ &ett_nfapi_pnf_phy, ++ &ett_nfapi_pnf_phy_rel10, ++ &ett_nfapi_pnf_phy_rel11, ++ &ett_nfapi_pnf_phy_rel12, ++ &ett_nfapi_pnf_phy_rel13, ++ &ett_nfapi_rf_bands, ++ &ett_nfapi_bf_vectors, ++ &ett_nfapi_csi_rs_bf_vector, ++ &ett_nfapi_csi_rs_resource_configs, ++ &ett_nfapi_tx_antenna_ports, ++ &ett_nfapi_harq_ack_nack_data, ++ &ett_nfapi_harq_data, ++ &ett_nfapi_cqi_pmi_size, ++ &ett_nfapi_cc, ++ &ett_nfapi_rbs, ++ &ett_nfapi_antennas, ++ &ett_nfapi_epdcch_prbs, ++ &ett_nfapi_dl_config_request_pdu_list, ++ &ett_nfapi_ul_config_request_pdu_list, ++ &ett_nfapi_hi_dci0_request_pdu_list, ++ &ett_nfapi_tx_request_pdu_list, ++ &ett_nfapi_rx_indication_pdu_list, ++ &ett_nfapi_harq_indication_pdu_list, ++ &ett_nfapi_crc_indication_pdu_list, ++ &ett_nfapi_sr_indication_pdu_list, ++ &ett_nfapi_cqi_indication_pdu_list, ++ &ett_nfapi_preamble_indication_pdu_list, ++ &ett_nfapi_srs_indication_pdu_list, ++ &ett_nfapi_lbt_dl_config_pdu_list, ++ &ett_nfapi_lbt_dl_indication_pdu_list, ++ &ett_nfapi_subbands, ++ &ett_nfapi_precoding, ++ &ett_nfapi_bf_vector_antennas, ++ &ett_nfapi_received_interference_power_mesurement_results, ++ &ett_nfapi_downlink_bandwidth_support, ++ &ett_nfapi_uplink_bandwidth_support, ++ &ett_nfapi_release_support, ++ &ett_nfapi_downlink_modulation_support, ++ &ett_nfapi_uplink_modulation_support, ++ ++ &ett_nfapi_earfcn_list, ++ &ett_nfapi_uarfcn_list, ++ &ett_nfapi_arfcn_list, ++ &ett_nfapi_rssi_list, ++ &ett_nfapi_pci_list, ++ &ett_nfapi_psc_list, ++ &ett_nfapi_lte_cells_found_list, ++ &ett_nfapi_utran_cells_found_list, ++ &ett_nfapi_geran_cells_found_list, ++ &ett_nfapi_si_periodicity_list, ++ ++ /* for fragmentation support*/ ++ &ett_msg_fragment, ++ &ett_msg_fragments ++ }; ++ ++ static ei_register_info ei[] = ++ { ++ { &ei_invalid_range, { "nfapi.invalid.range", PI_PROTOCOL, PI_WARN, NULL, EXPFILL } }, ++ { &ei_invalid_tlv_length, { "nfapi.invalid.tlv.length", PI_PROTOCOL, PI_ERROR, NULL, EXPFILL } }, ++ }; ++ ++ expert_module_t* expert_nfapi; ++ /* Register protocol */ ++ proto_nfapi = proto_register_protocol("Nfapi", "NFAPI", "nfapi"); ++ ++ expert_nfapi = expert_register_protocol(proto_nfapi); ++ expert_register_field_array(expert_nfapi, ei, array_length(ei)); ++ ++ ++ proto_register_field_array(proto_nfapi, hf, array_length(hf)); ++ proto_register_subtree_array(ett, array_length(ett)); ++ ++ reassembly_table_register(&ul_p7_reassemble_table, &addresses_ports_reassembly_table_functions); ++ reassembly_table_register(&dl_p7_reassemble_table, &addresses_ports_reassembly_table_functions); ++ ++ register_dissector("nfapi", dissect_nfapi, proto_nfapi); ++ ++} ++ ++// ----------------------------------------------------------------------------| ++ ++void proto_reg_handoff_nfapi(void) ++{ ++ static dissector_handle_t nfapi_handle; ++ ++ nfapi_handle = create_dissector_handle(dissect_nfapi, proto_nfapi); ++ ++ dissector_add_for_decode_as("sctp.port", nfapi_handle); ++ ++ dissector_add_uint("udp.port", 41700, nfapi_handle); ++ ++} ++ ++ ++/* ++* Editor modelines - http://www.wireshark.org/tools/modelines.html ++* ++* Local variables: ++* c-basic-offset: 8 ++* tab-width: 8 ++* indent-tabs-mode: t ++* End: ++* ++* vi: set shiftwidth=8 tabstop=8 noexpandtab: ++* :indentSize=8:tabSize=8:noTabs=false: ++*/ +diff --git a/xml/pnf_phy_1_A.xml b/xml/pnf_phy_1_A.xml +index da6cc26..45f8f46 100644 +--- a/xml/pnf_phy_1_A.xml ++++ b/xml/pnf_phy_1_A.xml +@@ -26,7 +26,7 @@ + + 88 + 2500 +-
127.0.0.1
++
192.168.1.74
+ + 1 + +@@ -54,9 +54,9 @@ + + + +- 7722 +- 127.0.0.1 +- 7733 ++ 5201 ++ 192.168.1.28 ++ 5200 + + +
+diff --git a/xml/vnf_A.xml b/xml/vnf_A.xml +index e609c93..3791239 100644 +--- a/xml/vnf_A.xml ++++ b/xml/vnf_A.xml +@@ -2,8 +2,8 @@ + + + +- 5200 +-
127.0.0.1
++ 5201 ++
192.168.1.28
+ 10 + 0 + 0 +@@ -12,7 +12,7 @@ + + + 8891 +- 127.0.0.1 ++ 192.168.1.28 + 8892 + + diff --git a/open-nfapi.oai.patch b/open-nfapi.oai.patch deleted file mode 100644 index 95aeb2e64a..0000000000 --- a/open-nfapi.oai.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/nfapi/public_inc/nfapi_interface.h b/nfapi/public_inc/nfapi_interface.h -index 2d58c2a..45af99a 100644 ---- a/nfapi/public_inc/nfapi_interface.h -+++ b/nfapi/public_inc/nfapi_interface.h -@@ -34,7 +34,7 @@ - #define NFAPI_MAX_NUM_ANTENNAS 8 - #define NFAPI_MAX_NUM_SUBBANDS 13 - #define NFAPI_MAX_BF_VECTORS 8 --#define NFAPI_MAX_CC 1 -+#define NFAPI_MAX_CC 2 - #define NFAPI_MAX_NUM_PHYSICAL_ANTENNAS 8 - #define NFAPI_MAX_RSSI 8 - #define NFAPI_MAX_PSC_LIST 32 -@@ -1689,7 +1689,7 @@ typedef struct { - uint16_t number_pdu; - uint8_t number_pdsch_rnti; - uint16_t transmission_power_pcfich; -- nfapi_dl_config_request_pdu_t* dl_config_pdu_list; -+ nfapi_dl_config_request_pdu_t* dl_config_pdu_list; - } nfapi_dl_config_request_body_t; - #define NFAPI_DL_CONFIG_REQUEST_BODY_TAG 0x2000 - -@@ -1772,7 +1772,7 @@ typedef struct { - uint8_t number_of_cc; - struct { - uint8_t ri_size; -- uint8_t dl_cqi_pmi_size; -+ uint8_t dl_cqi_pmi_size[8]; - } cc[NFAPI_MAX_CC]; - } nfapi_ul_config_aperiodic_cqi_pmi_ri_report_t; - -@@ -1962,7 +1962,7 @@ typedef struct { - } nfapi_ul_config_harq_information_rel8_fdd_t; - #define NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG 0x2019 - --typedef struct { -+typedef struct { - nfapi_tl_t tl; - uint8_t harq_size; - uint8_t ack_nack_mode; diff --git a/openair1/Makefile b/openair1/Makefile deleted file mode 100644 index 04be9ff8b0..0000000000 --- a/openair1/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -# command line flags are automatically exported and thus passed down to any sub-make. -# here we set the default flags in case on command line flags are provided -# these flags have to be explicitely exported so that the sub-make is aware of them - - -include $(OPENAIR_DIR)/common/utils/Makefile.inc -ifndef OPENAIR_LTE -export OPENAIR_LTE=1 -endif - -ifndef OPENAIR1 -export OPENAIR1=1 -endif - -ifndef OPENAIR2 -export OPENAIR2=0 -endif - -ifndef EMOS -export EMOS=0 -endif - -ifndef FIRMWARE2010 -export FIRMWARE2010=0 -endif - -all: openair_rf_cbmimo1_softmodem.ko asn1_msg_kern.ko - -openair_rf_cbmimo1_softmodem.ko: - (cd ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 && mv openair_rf.ko openair_rf_softmodem.ko) - -oai_user_cbmimo1.ko: - (cd ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 BIT8_TX=1 OPENAIR1=0 OPENAIR2=0 && mv openair_rf.ko openair_rf_softmodem.ko) - -oai_user_exmimo.ko: - (cd ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 OPENAIR1=0 OPENAIR2=0 && mv openair_rf.ko openair_rf_softmodem.ko) - -asn1_msg_kern.ko: - (cd ../openair2/RRC/LITE/MESSAGES && $(MAKE) -C $(KERNEL_DIR) V=0 M=`pwd` RTAI=1 -j2) - -#Remove all but source files -cleanall: - find -name '*.o' -delete -print; \ - find -name '*.ko' -delete -print; \ - find -name '*.bak' -delete -print; \ - find -name '*.cmd' -delete -print; \ - find -name '*~' -delete -print; \ - find -name octave-core -delete -print; \ - -#Remove files created by SVN, dangerous!!! DO NOT RUN ON YOUR WORKING REPOSITORY! -#FK: Don't do this! Use svn export instead. -#cleansvn: -# rm -rf `find -name *.svn* -print`; \ -# find -name *.svn* -delete -print - -tgz: - mkdir /tmp/openair1_tmp; \ - $(MAKE) cleanall; \ - cp -r . /tmp/openair1_tmp; \ - (cd /tmp/openair1_tmp && $(MAKE) cleansvn && cd .. && tar czfv openair1.tgz openair1_tmp) ; \ - cp /tmp/openair1.tgz . ;\ - rm -rf /tmp/openair1_tmp - -fifos: - @for i in `seq 0 64`;\ - do \ - have_rtfX=`ls /dev/ |grep -c rtf$$i`;\ - if [ "$$have_rtfX" -eq 0 ] ;then \ - mknod -m 666 /dev/rtf$$i c 150 $$i; \ - fi;\ - done - -openair0: - mknod /dev/openair0 c 127 0 - chmod a+rw /dev/openair0 - -install_oai_user: - make fifos - insmod ARCH/CBMIMO1/DEVICE_DRIVER/openair_rf_softmodem.ko - -updatefw: - USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr_exmimo2/main -s 0x43fffff0 - -boot_exmimo: - sudo make install_oai_user - USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 - sudo rmmod openair_rf - sudo make install_oai_user - -reboot_exmimo: - USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 -b - rmmod openair_rf - make install_oai_user - USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 - rmmod openair_rf - make install_oai_user - -install_softmodem: - make fifos -ifeq ($(OPENAIR2),1) - insmod ../openair2/RRC/LITE/MESSAGES/asn1_msg_kern.ko -endif - insmod ARCH/CBMIMO1/DEVICE_DRIVER/openair_rf_softmodem.ko ; \ - -remove: - rmmod openair_rf -ifeq ($(OPENAIR2),1) - rmmod asn1_msg_kern -endif - -test: - (cd ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) test RTAI=1 CBMIMO1=1) - (cd ../openair2/RRC/LITE/MESSAGES && $(MAKE) test) - -clean: clean_l1 - -clean_l1: - (cd ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) clean RTAI=1 CBMIMO1=1) - -clean_asn1: - (cd ../openair2/RRC/LITE/MESSAGES && $(MAKE) clean) diff --git a/openair1/PHY/CODING/Makefile.arm b/openair1/PHY/CODING/Makefile.arm index 07dbf55909..04598075e3 100644 --- a/openair1/PHY/CODING/Makefile.arm +++ b/openair1/PHY/CODING/Makefile.arm @@ -5,7 +5,7 @@ RATE12CC_SRC = ccoding_byte.c viterbi.c crc_byte.c all: 3gpplte_sse 3gpplte_sse: $(TURBO_SRC) - gcc -O3 -gdwarf-2 -mfloat-abi=hard -mfpu=neon -lm -lgcc -lrt ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DTC_MAIN -DNB_ANTENNAS_RX=1 -o 3gpplte_sse 3gpplte_sse.c -Wall -g -ggdb -DTC_MAIN + gcc -O3 -gdwarf-2 -mfloat-abi=hard -mfpu=neon -lm -lgcc -lrt ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DTC_MAIN -DNB_ANTENNAS_RX=1 -o 3gpplte_sse 3gpplte_sse.c -Wall -g -ggdb -DTC_MAIN diff --git a/openair1/PHY/CODING/TESTBENCH/Makefile b/openair1/PHY/CODING/TESTBENCH/Makefile index a8ddd1fcb5..030f19b47b 100644 --- a/openair1/PHY/CODING/TESTBENCH/Makefile +++ b/openair1/PHY/CODING/TESTBENCH/Makefile @@ -7,7 +7,7 @@ OPENAIR2_TOP = $(OPENAIR2_DIR) OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -DNODE_RG -DUSER_MODE -DPC_TARGET -DNO_UL_REF -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DOPENAIR_LTE -DMAX_NUM_CCs=1 +CFLAGS += -DNODE_RG -DNO_UL_REF -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DOPENAIR_LTE -DMAX_NUM_CCs=1 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 4f0dcf2196..5ec4fcaaa4 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -31,13 +31,6 @@ */ -#ifndef USER_MODE -#define __NO_VERSION__ - -#endif - -//#include "PHY/types.h" - #include "defs.h" diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/defs.h index 06311a188b..80e28b1586 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/defs.h @@ -29,11 +29,7 @@ #include -#ifndef NO_OPENAIR1 #include "PHY/defs.h" -#else -#include "PHY/TOOLS/time_meas.h" -#endif #define CRC24_A 0 #define CRC24_B 1 diff --git a/openair1/PHY/CODING/viterbi_lte.c b/openair1/PHY/CODING/viterbi_lte.c index d112e7c109..5e11cb3453 100644 --- a/openair1/PHY/CODING/viterbi_lte.c +++ b/openair1/PHY/CODING/viterbi_lte.c @@ -28,10 +28,6 @@ date: 21.10.2009 */ -#ifdef USER_MODE -#include -#endif - #ifndef TEST_DEBUG #include "PHY/defs.h" #include "PHY/extern.h" @@ -126,7 +122,7 @@ void print_shorts(__m128i x,char *s) { } */ -#endif // USER_MODE +#endif // DEBUG_VITERBI diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index c4d5850501..218beb4faf 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -20,10 +20,6 @@ */ /*!\brief Initilization and reconfiguration routines for LTE PHY */ -#ifndef USER_MODE -#define __NO_VERSION__ -#endif - #include "defs.h" #include "PHY/extern.h" #include "MAC_INTERFACE/extern.h" diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 45f703f674..d662cf19de 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -32,6 +32,9 @@ #include "assertions.h" #include +extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn); +extern int32_t get_uldl_offset(int eutra_bandP); + extern uint16_t prach_root_sequence_map0_3[838]; extern uint16_t prach_root_sequence_map4[138]; uint8_t dmrs1_tab[8] = {0,2,3,4,6,8,9,10}; @@ -42,24 +45,41 @@ int N_RB_DL_array[6] = {6,15,25,50,75,100}; int l1_north_init_eNB() { int i,j; - AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst); - AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n"); - AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n"); - for (i=0;i0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]); - for (j=0;jif_inst = IF_Module_init(i))<0) return(-1); - RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request; - RC.eNB[i][j]->if_inst->schedule_response = schedule_response; + + if (RC.nb_L1_inst > 0 && RC.nb_L1_CC != NULL && RC.eNB != NULL) + { + AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst); + AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n"); + AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n"); + + LOG_I(PHY,"%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst); + + for (i=0;i0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]); + + LOG_I(PHY,"%s() RC.nb_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_L1_CC[i]); + + for (j=0;jif_inst = IF_Module_init(i))<0) return(-1); + + LOG_I(PHY,"%s() RC.eNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j); + + RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request; + RC.eNB[i][j]->if_inst->schedule_response = schedule_response; + } } } + else + { + LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_L1_inst:%d RC.nb_L1_CC:%p RC.eNB:%p\n", __FUNCTION__, RC.nb_L1_inst, RC.nb_L1_CC, RC.eNB); + } return(0); } - void phy_config_request(PHY_Config_t *phy_config) { uint8_t Mod_id = phy_config->Mod_id; @@ -71,13 +91,14 @@ void phy_config_request(PHY_Config_t *phy_config) { PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two}; int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0]; int dl_Bandwidth = cfg->rf_config.dl_channel_bandwidth.value; + int ul_Bandwidth = cfg->rf_config.ul_channel_bandwidth.value; int Nid_cell = cfg->sch_config.physical_cell_id.value; int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value; int p_eNB = cfg->rf_config.tx_antenna_ports.value; uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; - LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", - Mod_id, CC_id, eutra_band, N_RB_DL_array[dl_Bandwidth], Nid_cell, p_eNB,Ncp,dl_CarrierFreq, + LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,eNB_tx_antenna_ports %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", + Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq, cfg->phich_config.phich_resource.value, cfg->phich_config.phich_duration.value); @@ -86,13 +107,18 @@ void phy_config_request(PHY_Config_t *phy_config) { AssertFatal(RC.eNB[Mod_id][CC_id] != NULL, "PHY instance %d, CCid %d doesn't exist\n",Mod_id,CC_id); + if (RC.eNB[Mod_id][CC_id]->configured == 1) + { + LOG_E(PHY,"Already eNB already configured, do nothing\n"); + return; + } RC.eNB[Mod_id][CC_id]->mac_enabled = 1; fp = &RC.eNB[Mod_id][CC_id]->frame_parms; - fp->N_RB_DL = N_RB_DL_array[dl_Bandwidth]; - fp->N_RB_UL = N_RB_DL_array[dl_Bandwidth]; + fp->N_RB_DL = dl_Bandwidth; + fp->N_RB_UL = ul_Bandwidth; fp->Nid_cell = Nid_cell; fp->nushift = fp->Nid_cell%6; fp->eutra_band = eutra_band; @@ -154,93 +180,95 @@ void phy_config_request(PHY_Config_t *phy_config) { RC.eNB[Mod_id][CC_id]->X_u); #ifdef Rel14 - if (cfg->emtc_config.prach_ce_level_0_enable.value == 1) { - fp->prach_emtc_config_common.prach_Config_enabled=1; + fp->prach_emtc_config_common.prach_Config_enabled=1; - fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; + fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; - // CE Level 3 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], - "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); + // CE Level 3 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], + "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[3]); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[3]); - // CE Level 2 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], - "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[2]); + // CE Level 2 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], + "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[2]); - // CE Level 1 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], - "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); + // CE Level 1 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], + "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[1]); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[1]); - // CE Level 0 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], - "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, - "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[0]); - } + // CE Level 0 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], + "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); +#if 0 + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, + "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); +#else + LOG_E(PHY,"***DJP*** removed assert on preamble fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]:%d expecting >0 %s:%d\n\n\n", fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], __FILE__, __LINE__); +#endif + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[0]); #endif @@ -267,9 +295,9 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 1) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 2) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = cfg->uplink_reference_signal_config.group_assignment.value; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); @@ -316,14 +344,14 @@ void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, } /* - void phy_config_sib2_eNB(uint8_t Mod_id, - int CC_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) - { +void phy_config_sib2_eNB(uint8_t Mod_id, + int CC_id, + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + ARFCN_ValueEUTRA_t *ul_CArrierFreq, + long *ul_Bandwidth, + AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) +{ LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; //LTE_eNB_UE_stats *eNB_UE_stats = RC.eNB[Mod_id][CC_id].eNB_UE_stats; @@ -350,7 +378,7 @@ void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, init_prach_tables(839); compute_prach_seq(&fp->prach_config_common,fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u); + RC.eNB[Mod_id][CC_id]->X_u); fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; @@ -392,15 +420,15 @@ void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, fp->soundingrs_ul_config_common.enabled_flag = 0; if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + fp->soundingrs_ul_config_common.enabled_flag = 1; + fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; } @@ -428,34 +456,34 @@ void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, // MBSFN if (mbsfn_SubframeConfigList != NULL) { - fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; + fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; - for (i=0; ilist.count; i++) { - fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; - fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; + for (i=0; ilist.count; i++) { + fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; + fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { - fp->MBSFN_config[i].fourFrames_flag = 0; - fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration - fp->MBSFN_config[i].fourFrames_flag = 1; - fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + fp->MBSFN_config[i].fourFrames_flag = 0; + fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + fp->MBSFN_config[i].fourFrames_flag = 1; + fp->MBSFN_config[i].mbsfn_SubframeConfig = + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } - } + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + } } else - fp->num_MBSFN_config = 0; + fp->num_MBSFN_config = 0; // - } +} */ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, @@ -670,9 +698,9 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index); + LOG_E(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index); + LOG_E(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index); + LOG_E(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d\n",eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index); LOG_D(PHY,"\n"); @@ -858,7 +886,7 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobi PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); } if(ho_failed) { @@ -887,67 +915,67 @@ void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8 } /* - void phy_config_dedicated_eNB(uint8_t Mod_id, - int CC_id, - uint16_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated) - { +void phy_config_dedicated_eNB(uint8_t Mod_id, + int CC_id, + uint16_t rnti, + struct PhysicalConfigDedicated *physicalConfigDedicated) +{ PHY_VARS_eNB *eNB = RC.eNB[Mod_id][CC_id]; int8_t UE_id = find_ue(rnti,eNB); int i; if (UE_id == -1) { - LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); - return; + LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); + return; } if (physicalConfigDedicated) { - eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; - LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); + eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; + LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); - if (physicalConfigDedicated->antennaInfo) { - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - eNB->transmission_mode[UE_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - eNB->transmission_mode[UE_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - eNB->transmission_mode[UE_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - eNB->transmission_mode[UE_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - eNB->transmission_mode[UE_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - eNB->transmission_mode[UE_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); + if (physicalConfigDedicated->antennaInfo) { + switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { + case AntennaInfoDedicated__transmissionMode_tm1: + eNB->transmission_mode[UE_id] = 1; + break; + case AntennaInfoDedicated__transmissionMode_tm2: + eNB->transmission_mode[UE_id] = 2; + break; + case AntennaInfoDedicated__transmissionMode_tm3: + eNB->transmission_mode[UE_id] = 3; + break; + case AntennaInfoDedicated__transmissionMode_tm4: + eNB->transmission_mode[UE_id] = 4; + break; + case AntennaInfoDedicated__transmissionMode_tm5: + eNB->transmission_mode[UE_id] = 5; + break; + case AntennaInfoDedicated__transmissionMode_tm6: + eNB->transmission_mode[UE_id] = 6; + break; + case AntennaInfoDedicated__transmissionMode_tm7: + lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); - for (i=0;inum_RU;i++) eNB->RU_list[i]->do_precoding=1; - eNB->transmission_mode[UE_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); + for (i=0;inum_RU;i++) eNB->RU_list[i]->do_precoding=1; + eNB->transmission_mode[UE_id] = 7; + break; + default: + LOG_E(PHY,"Unknown transmission mode!\n"); + break; + } + LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); + } else { + LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); + } } else { - LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); - } - } else { - LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); - return; + LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); + return; } - } +} */ #if defined(Rel10) || defined(Rel14) @@ -959,11 +987,11 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, } /* - void phy_config_dedicated_scell_eNB(uint8_t Mod_id, - uint16_t rnti, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) - { +void phy_config_dedicated_scell_eNB(uint8_t Mod_id, + uint16_t rnti, + SCellToAddMod_r10_t *sCellToAddMod_r10, + int CC_id) +{ uint8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][0]); @@ -974,37 +1002,37 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint32_t carrier_freq_local; if ((dl_CarrierFreq_r10>=36000) && (dl_CarrierFreq_r10<=36199)) { - carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0, - CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0, + CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else if ((dl_CarrierFreq_r10>=6150) && (dl_CarrierFreq_r10<=6449)) { - carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, - //eNB->frame - 0,dl_CarrierFreq_r10,CC_id,UE_id); + LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, + //eNB->frame + 0,dl_CarrierFreq_r10,CC_id,UE_id); } if (physicalConfigDedicatedSCell_r10) { - //#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" - // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; - LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); +//#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" + // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; + LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); - return; + LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); + return; } - } +} */ #endif @@ -1181,7 +1209,7 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, } if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting + // configure PUCCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) @@ -1224,12 +1252,12 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, } //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); } @@ -1693,7 +1721,7 @@ int phy_init_RU(RU_t *ru) { ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], - fp->samples_per_tti*10*sizeof(int32_t)); + fp->samples_per_tti*10*sizeof(int32_t)); } for (i=0;inb_rx;i++) { @@ -1751,9 +1779,13 @@ int phy_init_RU(RU_t *ru) { AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n", RC.nb_L1_inst,NUMBER_OF_eNB_MAX); + LOG_E(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst); + for (i=0; ieNB_list[i]->frame_parms.nb_antenna_ports_eNB); if (peNB_list[i]->frame_parms.nb_antenna_ports_eNB || p==5) { + LOG_D(PHY,"[INIT] %s() DO BEAM WEIGHTS nb_antenna_ports_eNB:%d nb_tx:%d\n", __FUNCTION__, ru->eNB_list[i]->frame_parms.nb_antenna_ports_eNB, ru->nb_tx); ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); for (j=0; jnb_tx; j++) { ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); @@ -1762,15 +1794,20 @@ int phy_init_RU(RU_t *ru) { // antenna ports 5-14 are mapped on all antennas if (((p<4) && (p==j)) || ((p==4) && (j==0))) { for (re=0; reofdm_symbol_size; re++) + { ru->beam_weights[i][p][j][re] = 0x00007fff; + + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } } else if (p>4) { for (re=0; reofdm_symbol_size; re++) + { ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); + } } - LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", - i,j,ru->beam_weights[i][p][j], - fp->ofdm_symbol_size*sizeof(int32_t)); + //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); } } } @@ -1797,6 +1834,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif int i, UE_id; + LOG_I(PHY,"[eNB %d] %s() About to wait for eNB to be configured", eNB->Mod_id, __FUNCTION__); eNB->total_dlsch_bitrate = 0; eNB->total_transmitted_bits = 0; @@ -1805,10 +1843,18 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, while(eNB->configured == 0) usleep(10000); - LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d\n", + LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u nb_antenna_ports_eNB:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n", eNB->Mod_id, fp->N_RB_DL,fp->phich_config_common.phich_resource, - fp->phich_config_common.phich_duration); + fp->phich_config_common.phich_duration, + fp->nb_antennas_tx, fp->nb_antennas_rx, fp->nb_antenna_ports_eNB, + fp->prach_config_common.rootSequenceIndex, + fp->prach_config_common.prach_Config_enabled, + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset + ); LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02"PRIu8"][]\n", eNB->Mod_id); @@ -1835,6 +1881,8 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*)); + LOG_D(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB); + for (i=0; inb_antenna_ports_eNB || i==5) { common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); @@ -1889,12 +1937,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) - AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), - "nb_antennas_rx too large"); - for (i=0; inb_antennas_rx; i++) { - prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]); - }*/ + AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), + "nb_antennas_rx too large"); + for (i=0; inb_antennas_rx; i++) { + prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]); + }*/ for (UE_id=0; UE_idrxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); - } + } pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); } //UE_id @@ -1937,3 +1985,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, return (0); } + +void install_schedule_handlers(IF_Module_t *if_inst) +{ + if_inst->PHY_config_req = phy_config_request; + if_inst->schedule_response = schedule_response; +} diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h index aae97ecd9e..a7b5d14701 100644 --- a/openair1/PHY/LTE_ESTIMATION/defs.h +++ b/openair1/PHY/LTE_ESTIMATION/defs.h @@ -23,12 +23,6 @@ #define __LTE_ESTIMATION_DEFS__H__ #include "PHY/defs.h" -/* -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif - */ - /** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ * @{ */ @@ -136,18 +130,6 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *phy_vars_ue, int subframe, unsigned char l); -/* -#ifdef EMOS -int lte_dl_channel_estimation_emos(int dl_ch_estimates_emos[NB_ANTENNAS_RX*NB_ANTENNAS_TX][N_RB_DL_EMOS*N_PILOTS_PER_RB*N_SLOTS_EMOS], - int **rxdataF, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned char Ns, - unsigned char p, - unsigned char l, - unsigned char sector); -#endif - */ - /*! \brief Frequency offset estimation for LTE We estimate the frequency offset by calculating the phase difference between channel estimates for symbols carrying pilots (l==0 or l==3/4). We take a moving average of the phase difference. diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c index fee9fd1492..afa7985962 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c @@ -149,10 +149,8 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, int temp, i, aa, max_pos = 0,ind; int max_val=0; short Re,Im,ncoef; -#ifdef USER_MODE #ifdef DEBUG_PHY char fname[100],vname[100]; -#endif #endif ncoef = 32768 - coef; @@ -187,12 +185,10 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms, 1); break; } -#ifdef USER_MODE #ifdef DEBUG_PHY sprintf(fname,"srs_ch_estimates_time_%d%d.m",ind,aa); sprintf(vname,"srs_time_%d%d",ind,aa); write_output(fname,vname,lte_eNB_srs->srs_ch_estimates_time[aa],frame_parms->ofdm_symbol_size*2,2,1); -#endif #endif } 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 f3d28488af..f697bd5308 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -19,9 +19,7 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include -#endif #include "defs.h" #include "PHY/defs.h" #include "filt16_32.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index 8139112892..55f1a8e17c 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -19,9 +19,7 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include -#endif #include "defs.h" #include "SCHED/defs.h" #include "PHY/defs.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation_emos.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation_emos.c deleted file mode 100644 index a64aa797af..0000000000 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation_emos.c +++ /dev/null @@ -1,151 +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 - */ - -#ifdef USER_MODE -#include -#endif -#include "defs.h" -#include "PHY/defs.h" -#include "SCHED/phy_procedures_emos.h" - -// TODO: make channel estimation possible for multiple sectors (Gold sequences for pilots) - -//#define DEBUG_CH -int lte_dl_channel_estimation_emos(int dl_ch_estimates_emos[NB_ANTENNAS_RX*NB_ANTENNAS_TX][N_RB_DL_EMOS*N_PILOTS_PER_RB*N_SLOTS_EMOS], - int **rxdataF, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned char Ns, - unsigned char p, - unsigned char l, - unsigned char sector) -{ - - int pilot[2][200] __attribute__((aligned(16))); - unsigned char nu,aarx; - unsigned short k; - unsigned int rb,pilot_cnt; - short ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev; //*f,*f2,*fl,*f2l2,*fr,*f2r2; - int ch_offset,symbol_offset; - unsigned int n; - int i; - - unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame - - if ((p==0) && (l==0) ) - nu = 0; - else if ((p==0) && (l>0)) - nu = 3; - else if ((p==1) && (l==0)) - nu = 3; - else if ((p==1) && (l>0)) - nu = 0; - else { - msg("lte_dl_channel_estimation_emos: p %d, l %d -> ERROR\n",p,l); - return(-1); - } - - if (sector > 2) { - msg("lte_dl_channel_estimation_emos: sector must be 0,1, or 2\n"); - return(-1); - } - - switch (Ns) { - case 0: - ch_offset = ((l==0)?0:1)*2*frame_parms->N_RB_DL; - break; - - case 1: - ch_offset = ((l==0)?2:3)*2*frame_parms->N_RB_DL; - break; - - case 12: - ch_offset = ((l==0)?4:5)*2*frame_parms->N_RB_DL; - break; - - case 13: - ch_offset = ((l==0)?6:7)*2*frame_parms->N_RB_DL; - break; - - default: - msg("lte_dl_channel_estimation_emos: Ns must be 0, 1, 12, or 13\n"); - return(-1); - break; - - } - - symbol_offset = symbol*frame_parms->ofdm_symbol_size; // offset within rxdataF - - k = nu + sector; - - if (k > 6) - k -=6; - -#ifdef DEBUG_CH - printf("Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d, symbol=%d\n",ch_offset,frame_parms->ofdm_symbol_size,frame_parms->Ncp,l,Ns,k,symbol); -#endif - - // generate pilot - lte_dl_cell_spec_rx(&pilot[p][0], - frame_parms, - Ns, - (l==0)?0:1, - p); - - - for (aarx=0; aarxnb_antennas_rx; aarx++) { - - pil = (short *)&pilot[p][0]; - rxF = (short *)&rxdataF[aarx][((symbol_offset+k+frame_parms->first_carrier_offset)<<1)]; - dl_ch = (short *)&dl_ch_estimates_emos[(p<<1)+aarx][ch_offset]; - memset(dl_ch,0,frame_parms->N_RB_DL); - - for (pilot_cnt=0; pilot_cntN_RB_DL; pilot_cnt++) { - - dl_ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - dl_ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - - pil+=2; // Re Im - rxF+=24; // remember replicated format (Re0 Im0 Re0 Im0) !!! - dl_ch+=2; - - } - - // printf("Second half\n"); - // Second half of RBs - rxF = (short *)&rxdataF[aarx][((symbol_offset+1+k)<<1)]; - - for (pilot_cnt=0; pilot_cntN_RB_DL; pilot_cnt++) { - - - dl_ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); - dl_ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); - - pil+=2; - rxF+=24; - dl_ch+=2; - - } - - } - - return(0); -} - 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 834f7e6fc6..75f87a6549 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c @@ -19,9 +19,7 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include -#endif #include "defs.h" #include "PHY/defs.h" diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index c7625ba083..2525f19b0d 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -578,30 +578,3 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } -#ifdef PHY_ABSTRACTION -#include "SIMULATION/TOOLS/defs.h" -#include "SIMULATION/RF/defs.h" -//extern channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; - -int lte_sync_time_eNB_emul(PHY_VARS_eNB *phy_vars_eNB, - uint8_t sect_id, - int32_t *sync_val) -{ - - uint8_t UE_id; - uint8_t CC_id = phy_vars_eNB->CC_id; - - LOG_E(PHY,"[PHY] EMUL lte_sync_time_eNB_emul eNB %d, sect_id %d\n",phy_vars_eNB->Mod_id,sect_id); - *sync_val = 0; - - for (UE_id=0; UE_idMod_id,UE_id,PHY_vars_UE_g[UE_id]->generate_prach,UE2eNB[UE_id][phy_vars_eNB->Mod_id]->path_loss_dB); - if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach == 1) && (phy_vars_eNB->Mod_id == (UE_id % NB_eNB_INST))) { - *sync_val = 1; - return(0); - } - } - - return(-1); -} -#endif diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index bbbbc2ffff..1049232bd8 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -38,7 +38,6 @@ int16_t cond_num_threshold = 0; -#ifdef USER_MODE void print_shorts(char *s,short *x) { @@ -57,8 +56,6 @@ void print_ints(char *s,int *x) ); } -#endif - int16_t get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 234e30d829..44eebb0df4 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -91,7 +91,6 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); eNB->ulsch[UE_id]->harq_processes[harq_pid]->n_DMRS2 + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+Ns]) % 12; -#if defined(USER_MODE) Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints); if (Msc_idx_ptr) @@ -101,26 +100,14 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); return(-1); } -#else - uint8_t b; - - for (b=0; b<33; b++) - if (Msc_RS==dftsizes[b]) - Msc_RS_idx = b; - -#endif - // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); #ifdef DEBUG_CH -#ifdef USER_MODE - if (Ns==0) write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1); else write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1); -#endif #endif @@ -489,12 +476,10 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, 15, 0); -#ifdef USER_MODE #ifdef DEBUG_SRS sprintf(fname,"srs_ch_est%d.m",aa); sprintf(vname,"srs_est%d",aa); write_output(fname,vname,srs_vars->srs_ch_estimates[aa],frame_parms->ofdm_symbol_size,1,1); -#endif #endif } diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c index b715b3ffa2..5bf69578d1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_cell_spec.c @@ -19,10 +19,8 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include #include -#endif #include "defs.h" #include "PHY/defs.h" diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c index 445c84623c..35e5fe6aff 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c @@ -21,10 +21,8 @@ // 6.10.2.2 MBSFN reference signals Mapping to resource elements -#ifdef USER_MODE #include #include -#endif #include "defs.h" #include "PHY/defs.h" diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c index ed9ff1f5cd..a7db8fd5aa 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c @@ -30,10 +30,8 @@ * \warning */ -#ifdef USER_MODE #include #include -#endif #include "defs.h" #include "PHY/defs.h" diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 1bea8db59a..39e61c601d 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -29,11 +29,9 @@ * \note * \warning */ -#ifdef USER_MODE #include #include #include -#endif #include "PHY/defs.h" #include "PHY/extern.h" #include "SCHED/defs.h" @@ -43,6 +41,7 @@ #include "assertions.h" #include "T.h" #include "UTIL/LOG/log.h" +#include "UTIL/LOG/vcd_signal_dumper.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 @@ -2065,6 +2064,8 @@ void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t reset; uint32_t x1, x2, s=0; + //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length); + reset = 1; // x1 is set in lte_gold_generic @@ -2247,11 +2248,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,1); generate_pcfich(num_pdcch_symbols, amp, frame_parms, txdataF, subframe); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,0); wbar[0] = &wbar0[0]; wbar[1] = &wbar1[0]; y[0] = &yseq0[0]; @@ -2272,6 +2275,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, e_ptr = e; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,1); // generate DCIs in order of decreasing aggregation level, then common/ue spec // MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization @@ -2298,18 +2302,26 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0); // Scrambling - // printf("pdcch scrambling\n"); +#ifdef DEBUG_DCI_ENCODING + printf("pdcch scrambling\n"); +#endif + //LOG_D(PHY, "num_pdcch_symbols:%d mi:%d nquad:%d\n", num_pdcch_symbols, mi, get_nquad(num_pdcch_symbols, frame_parms, mi)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,1); pdcch_scrambling(frame_parms, subframe, e, 8*get_nquad(num_pdcch_symbols, frame_parms, mi)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,0); //72*get_nCCE(num_pdcch_symbols,frame_parms,mi)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,1); // Now do modulation if (frame_parms->nb_antenna_ports_eNB==1) gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); @@ -2322,6 +2334,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK); #endif + //LOG_D(PHY,"%s() Msymb2:%d\n", __FUNCTION__, Msymb2); if (frame_parms->nb_antenna_ports_eNB==1) { //SISO @@ -2368,22 +2381,38 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0); #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Interleaving\n"); #endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,1); // printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]); // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5 pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,1); mprime=0; nsymb = (frame_parms->Ncp==0) ? 14:12; re_offset = frame_parms->first_carrier_offset; // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 // printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]); +#ifdef DEBUG_DCI_ENCODING + printf("kprime loop - N_RB_DL:%d lprime:num_pdcch_symbols:%d Ncp:%d pcfich:%02x,%02x,%02x,%02x ofdm_symbol_size:%d first_carrier_offset:%d nb_antenna_ports_eNB:%d\n", + frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp, + frame_parms->pcfich_reg[0], + frame_parms->pcfich_reg[1], + frame_parms->pcfich_reg[2], + frame_parms->pcfich_reg[3], + frame_parms->ofdm_symbol_size, + frame_parms->first_carrier_offset, + frame_parms->nb_antenna_ports_eNB + ); +#endif for (kprime=0; kprimeN_RB_DL*12; kprime++) { for (lprime=0; lprimeofdm_symbol_size)) re_offset = 1; } // kprime loop + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0); return(num_pdcch_symbols); } @@ -4208,33 +4238,3 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); } - -#ifdef PHY_ABSTRACTION -uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **pdcch_vars, - uint8_t num_ue_spec_dci, - uint8_t num_common_dci, - DCI_ALLOC_t *dci_alloc_tx, - DCI_ALLOC_t *dci_alloc_rx, - int16_t eNB_id) -{ - - uint8_t dci_cnt=0,i; - - memcpy(dci_alloc_rx,dci_alloc_tx,num_common_dci*sizeof(DCI_ALLOC_t)); - dci_cnt = num_common_dci; - LOG_D(PHY,"[DCI][EMUL] : num_common_dci %d\n",num_common_dci); - - for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) { - LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format, - dci_alloc_tx[i].dci_pdu[0]&0x80); - - if (dci_alloc_tx[i].rnti == pdcch_vars[eNB_id]->crnti) { - memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t)); - dci_cnt++; - } - } - - - return(dci_cnt); -} -#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index 0e74324b2c..9381dd63fd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -482,8 +482,8 @@ typedef struct DCI1A_20MHz_FDD DCI1A_20MHz_FDD_t; /// DCI Format Type 1 (1.5 MHz, TDD, 23 bits) struct DCI1_1_5MHz_TDD { - /// Dummy bits to align to 32-bits - uint32_t dummy:9; + /// padding bits to align to 32-bits + uint32_t padding:9; /// DAI (TDD) uint32_t dai:2; /// Power Control @@ -507,8 +507,8 @@ typedef struct DCI1_1_5MHz_TDD DCI1_1_5MHz_TDD_t; /// DCI Format Type 1 (5 MHz, TDD, 30 bits) struct DCI1_5MHz_TDD { - /// Dummy bits to align to 32-bits - uint32_t dummy:2; + /// padding bits to align to 32-bits + uint32_t padding:2; /// DAI (TDD) uint32_t dai:2; /// Power Control @@ -532,8 +532,8 @@ typedef struct DCI1_5MHz_TDD DCI1_5MHz_TDD_t; /// DCI Format Type 1 (10 MHz, TDD, 34 bits) struct DCI1_10MHz_TDD { - /// Dummy bits to align to 64-bits - uint64_t dummy:30; + /// padding bits to align to 64-bits + uint64_t padding:30; /// DAI (TDD) uint64_t dai:2; /// Power Control @@ -557,8 +557,8 @@ typedef struct DCI1_10MHz_TDD DCI1_10MHz_TDD_t; /// DCI Format Type 1 (20 MHz, TDD, 42 bits) struct DCI1_20MHz_TDD { - /// Dummy bits to align to 64-bits - uint64_t dummy:22; + /// padding bits to align to 64-bits + uint64_t padding:22; /// DAI (TDD) uint64_t dai:2; /// Power Control @@ -582,8 +582,8 @@ typedef struct DCI1_20MHz_TDD DCI1_20MHz_TDD_t; /// DCI Format Type 1 (1.5 MHz, FDD, 21 bits) struct DCI1_1_5MHz_FDD { - /// Dummy bits to align to 32-bits - uint32_t dummy:11; + /// padding bits to align to 32-bits + uint32_t padding:11; /// Power Control uint32_t TPC:2; /// Redundancy version @@ -605,8 +605,8 @@ typedef struct DCI1_1_5MHz_FDD DCI1_1_5MHz_FDD_t; /// DCI Format Type 1 (5 MHz, FDD, 27 bits) struct DCI1_5MHz_FDD { - /// dummy bits (not transmitted) - uint32_t dummy:5; + /// padding its (not transmitted) + uint32_t padding:5; /// Power Control uint32_t TPC:2; /// Redundancy version @@ -628,8 +628,8 @@ typedef struct DCI1_5MHz_FDD DCI1_5MHz_FDD_t; /// DCI Format Type 1 (10 MHz, FDD, 31 bits) struct DCI1_10MHz_FDD { - /// dummy bits (not transmitted) - uint32_t dummy:1; + /// padding bits (not transmitted) + uint32_t padding:1; /// Power Control uint32_t TPC:2; /// Redundancy version @@ -651,8 +651,8 @@ typedef struct DCI1_10MHz_FDD DCI1_10MHz_FDD_t; /// DCI Format Type 1 (20 MHz, FDD, 39 bits) struct DCI1_20MHz_FDD { - /// dummy bits (not transmitted) - uint64_t dummy:25; + /// padding bits (not transmitted) + uint64_t padding:25; /// Power Control uint64_t TPC:2; /// Redundancy version @@ -674,10 +674,8 @@ typedef struct DCI1_20MHz_FDD DCI1_20MHz_FDD_t; /// DCI Format Type 1A (5 MHz, TDD, frame 1-6, 27 bits) struct DCI1A_RA_5MHz_TDD_1_6 { - /// Dummy bits to align to 32-bits - uint32_t dummy:5; - /// Padding - uint32_t padding:6; + /// padding bits to align to 32-bits + uint32_t padding:11; /// PRACH mask index uint32_t prach_mask_index:4; /// Preamble Index @@ -822,7 +820,7 @@ typedef struct DCI1B_5MHz_4A_TDD DCI1B_5MHz_4A_TDD_t; struct DCI1C_1_5MHz { /// padding to 32bits - uint32_t padding32:24; + uint32_t padding:24; uint32_t mcs:5; uint32_t rballoc:3; // N_RB_step = 2, Ngap=Ngap1=3, NDLVRBGap = 6, ceil(log2((3*4)/2)) = 3 } __attribute__ ((__packed__)); @@ -836,7 +834,7 @@ typedef struct DCI1C_1_5MHz DCI1C_1_5MHz_t; struct DCI1C_5MHz { /// padding to 32bits - uint32_t padding32:20; + uint32_t padding:20; uint32_t mcs:5; uint32_t rballoc:7; // N_RB_step = 2, Ngap1=Ngap2=12, NDLVRBGap = 24, ceil(log2((12*13)/2)) = 7 } __attribute__ ((__packed__)); @@ -848,7 +846,7 @@ typedef struct DCI1C_5MHz DCI1C_5MHz_t; struct DCI1C_10MHz { /// padding to 32bits - uint32_t padding32:19; + uint32_t padding:19; uint32_t mcs:5; uint32_t rballoc:7; // N_RB_step = 4, Ngap1=27, NDLVRBGap = 46, ceil(log2(((11*12)/2)) = 7 uint32_t Ngap:1; @@ -861,7 +859,7 @@ typedef struct DCI1C_10MHz DCI1C_10MHz_t; struct DCI1C_15MHz { /// padding to 32bits - uint32_t padding32:18; + uint32_t padding:18; uint32_t mcs:5; uint32_t rballoc:8; // N_RB_step = 4, Ngap1=64, ceil(log2((16*17)/2)) = 8 uint32_t Ngap:1; @@ -874,7 +872,7 @@ typedef struct DCI1C_15MHz DCI1C_15MHz_t; struct DCI1C_20MHz { /// padding to 32bits - uint32_t padding32:17; + uint32_t padding:17; uint32_t mcs:5; uint32_t rballoc:9; // N_RB_step = 4, Ngap1=48, ceil(log2((24*25)/2)) = 9 uint32_t Ngap:1; @@ -1006,7 +1004,7 @@ typedef struct DCI1D_5MHz_4A_TDD DCI1D_5MHz_4A_TDD_t; /// DCI Format Type 1E (5 MHz, TDD, 2 Antenna Ports, more than 10 PRBs, 34 bits) struct DCI1E_5MHz_2A_M10PRB_TDD { /// padding to 64bits - uint64_t padding64:30; + uint64_t padding:30; /// Redundancy version 2 ///uint64_t rv2:2; /// New Data Indicator 2 @@ -1045,7 +1043,7 @@ typedef struct DCI1E_5MHz_2A_M10PRB_TDD DCI1E_5MHz_2A_M10PRB_TDD_t; /// DCI Format Type 2 (1.5 MHz, TDD, 2 Antenna Ports, 34 bits) struct DCI2_1_5MHz_2A_TDD { /// padding to 64bits - uint64_t padding64:30; + uint64_t padding:30; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1078,7 +1076,7 @@ typedef struct DCI2_1_5MHz_2A_TDD DCI2_1_5MHz_2A_TDD_t; /// DCI Format Type 2 (1.5 MHz, TDD, 4 Antenna Ports, 37 bits) struct DCI2_1_5MHz_4A_TDD { /// padding for 64-bit - uint64_t padding64:27; + uint64_t padding:27; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1111,7 +1109,7 @@ typedef struct DCI2_1_5MHz_4A_TDD DCI2_1_5MHz_4A_TDD_t; /// DCI Format Type 2 (5 MHz, TDD, 2 Antenna Ports, 42 bits) struct DCI2_5MHz_2A_TDD { /// padding to 64bits - uint64_t padding64:22; + uint64_t padding:22; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1146,7 +1144,7 @@ typedef struct DCI2_5MHz_2A_TDD DCI2_5MHz_2A_TDD_t; /// DCI Format Type 2 (5 MHz, TDD, 4 Antenna Ports, 45 bits) struct DCI2_5MHz_4A_TDD { /// padding for 64-bit - uint64_t padding64:19; + uint64_t padding:19; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1181,7 +1179,7 @@ typedef struct DCI2_5MHz_4A_TDD DCI2_5MHz_4A_TDD_t; /// DCI Format Type 2 (10 MHz, TDD, 2 Antenna Ports, 46 bits) struct DCI2_10MHz_2A_TDD { /// padding to 64bits - uint64_t padding64:18; + uint64_t padding:18; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1216,7 +1214,7 @@ typedef struct DCI2_10MHz_2A_TDD DCI2_10MHz_2A_TDD_t; /// DCI Format Type 2 (10 MHz, TDD, 4 Antenna Ports, 49 bits) struct DCI2_10MHz_4A_TDD { /// padding for 64-bit - uint64_t padding64:15; + uint64_t padding:15; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1251,7 +1249,7 @@ typedef struct DCI2_10MHz_4A_TDD DCI2_10MHz_4A_TDD_t; /// DCI Format Type 2 (20 MHz, TDD, 2 Antenna Ports, 54 bits) struct DCI2_20MHz_2A_TDD { /// padding to 64bits - uint64_t padding64:10; + uint64_t padding:10; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1286,7 +1284,7 @@ typedef struct DCI2_20MHz_2A_TDD DCI2_20MHz_2A_TDD_t; /// DCI Format Type 2 (20 MHz, TDD, 4 Antenna Ports, 57 bits) struct DCI2_20MHz_4A_TDD { /// padding for 64-bit - uint64_t padding64:7; + uint64_t padding:7; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1321,7 +1319,7 @@ typedef struct DCI2_20MHz_4A_TDD DCI2_20MHz_4A_TDD_t; /// DCI Format Type 2 (1.5 MHz, FDD, 2 Antenna Ports, 31 bits) struct DCI2_1_5MHz_2A_FDD { //padding for 32 bits - uint32_t padding32:1; + uint32_t padding:1; /// precoding bits uint32_t tpmi:3; /// Redundancy version 2 @@ -1352,7 +1350,7 @@ typedef struct DCI2_1_5MHz_2A_FDD DCI2_1_5MHz_2A_FDD_t; /// DCI Format Type 2 (1.5 MHz, FDD, 4 Antenna Ports, 34 bits) struct DCI2_1_5MHz_4A_FDD { /// padding for 32 bits - uint64_t padding64:30; + uint64_t padding:30; /// precoding bits uint64_t tpmi:6; /// Redundancy version 2 @@ -1383,7 +1381,7 @@ typedef struct DCI2_1_5MHz_4A_FDD DCI2_1_5MHz_4A_FDD_t; /// DCI Format Type 2 (5 MHz, FDD, 2 Antenna Ports, 39 bits) struct DCI2_5MHz_2A_FDD { /// padding for 64-bit - uint64_t padding64:25; + uint64_t padding:25; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1416,7 +1414,7 @@ typedef struct DCI2_5MHz_2A_FDD DCI2_5MHz_2A_FDD_t; /// DCI Format Type 2 (5 MHz, TDD, 4 Antenna Ports, 42 bits) struct DCI2_5MHz_4A_FDD { /// padding for 64-bit - uint64_t padding64:21; + uint64_t padding:21; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1448,7 +1446,7 @@ typedef struct DCI2_5MHz_4A_FDD DCI2_5MHz_4A_FDD_t; /// DCI Format Type 2 (10 MHz, FDD, 2 Antenna Ports, 43 bits) struct DCI2_10MHz_2A_FDD { /// padding for 64-bit - uint64_t padding64:21; + uint64_t padding:21; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1481,7 +1479,7 @@ typedef struct DCI2_10MHz_2A_FDD DCI2_10MHz_2A_FDD_t; /// DCI Format Type 2 (5 MHz, TDD, 4 Antenna Ports, 46 bits) struct DCI2_10MHz_4A_FDD { /// padding for 64-bit - uint64_t padding64:18; + uint64_t padding:18; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -1513,7 +1511,7 @@ typedef struct DCI2_10MHz_4A_FDD DCI2_10MHz_4A_FDD_t; /// DCI Format Type 2 (20 MHz, FDD, 2 Antenna Ports, 51 bits) struct DCI2_20MHz_2A_FDD { /// padding for 64-bit - uint64_t padding64:13; + uint64_t padding:13; /// TPMI information for precoding uint64_t tpmi:3; /// Redundancy version 2 @@ -1546,7 +1544,7 @@ typedef struct DCI2_20MHz_2A_FDD DCI2_20MHz_2A_FDD_t; /// DCI Format Type 2 (20 MHz, FDD, 4 Antenna Ports, 54 bits) struct DCI2_20MHz_4A_FDD { /// padding for 64-bit - uint64_t padding64:10; + uint64_t padding:10; /// TPMI information for precoding uint64_t tpmi:6; /// Redundancy version 2 @@ -2083,7 +2081,7 @@ typedef struct DCI2A_20MHz_4A_FDD DCI2A_20MHz_4A_FDD_t; // ******************************************************************* /// DCI Format Type 2B (1.5 MHz, TDD, 33 bits) struct DCI2B_1_5MHz_TDD { - uint64_t padding64:31; + uint64_t padding:31; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2109,7 +2107,7 @@ struct DCI2B_1_5MHz_TDD { /// RB Assignment (ceil(log2(N_RB_DL/P)) bits) uint64_t rballoc:6; /// Padding for ambiguity - uint64_t padding:1; + uint64_t padding0:1; } __attribute__ ((__packed__)); typedef struct DCI2B_1_5MHz_TDD DCI2B_1_5MHz_TDD_t; @@ -2118,7 +2116,7 @@ typedef struct DCI2B_1_5MHz_TDD DCI2B_1_5MHz_TDD_t; /// DCI Format Type 2B (5 MHz, TDD, 39 bits) struct DCI2B_5MHz_TDD { /// padding to 64bits - uint64_t padding64:25; + uint64_t padding:25; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2153,7 +2151,7 @@ typedef struct DCI2B_5MHz_TDD DCI2B_5MHz_TDD_t; /// DCI Format Type 2B (10 MHz, TDD, 43 bits) struct DCI2B_10MHz_TDD { /// padding to 64bits - uint64_t padding64:21; + uint64_t padding:21; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2188,7 +2186,7 @@ typedef struct DCI2B_10MHz_TDD DCI2B_10MHz_TDD_t; /// DCI Format Type 2B (20 MHz, TDD, 51 bits) struct DCI2B_20MHz_TDD { /// padding to 64bits - uint64_t padding64:13; + uint64_t padding:13; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2223,7 +2221,7 @@ typedef struct DCI2B_20MHz_TDD DCI2B_20MHz_TDD_t; /// DCI Format Type 2B (1.5 MHz, FDD, 28 bits) struct DCI2B_1_5MHz_FDD { //padding for 32 bits - uint32_t padding32:4; + uint32_t padding:4; /// Redundancy version 2 uint32_t rv2:2; /// New Data Indicator 2 @@ -2252,7 +2250,7 @@ typedef struct DCI2B_1_5MHz_FDD DCI2B_1_5MHz_FDD_t; /// DCI Format Type 2B (5 MHz, FDD, 36 bits) struct DCI2B_5MHz_FDD { /// padding for 64-bit - uint64_t padding64:28; + uint64_t padding:28; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2283,7 +2281,7 @@ typedef struct DCI2B_5MHz_FDD DCI2B_5MHz_FDD_t; /// DCI Format Type 2B (10 MHz, FDD, 41 bits) struct DCI2B_10MHz_FDD { /// padding for 64-bit - uint64_t padding64:23; + uint64_t padding:23; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2307,7 +2305,7 @@ struct DCI2B_10MHz_FDD { /// Resource Allocation Header uint64_t rah:1; /// Padding for ambiguity - uint64_t padding:1; + uint64_t padding0:1; } __attribute__ ((__packed__)); #define sizeof_DCI2B_10MHz_FDD_t 41 @@ -2316,7 +2314,7 @@ typedef struct DCI2B_10MHz_FDD DCI2B_10MHz_FDD_t; /// DCI Format Type 2B (20 MHz, FDD, 48 bits) struct DCI2B_20MHz_FDD { /// padding for 64-bit - uint64_t padding64:16; + uint64_t padding:16; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2350,7 +2348,7 @@ typedef struct DCI2B_20MHz_FDD DCI2B_20MHz_FDD_t; /// DCI Format Type 2C (1.5 MHz, TDD, 34 bits) struct DCI2C_1_5MHz_TDD { - uint64_t padding64:30; + uint64_t padding:30; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2383,7 +2381,7 @@ typedef struct DCI2C_1_5MHz_TDD DCI2C_1_5MHz_TDD_t; /// DCI Format Type 2C (5 MHz, TDD, 41 bits) struct DCI2C_5MHz_TDD { /// padding to 64bits - uint64_t padding64:23; + uint64_t padding:23; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2418,7 +2416,7 @@ typedef struct DCI2C_5MHz_TDD DCI2C_5MHz_TDD_t; /// DCI Format Type 2C (10 MHz, TDD, 45 bits) struct DCI2C_10MHz_TDD { /// padding to 64bits - uint64_t padding64:19; + uint64_t padding:19; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2453,7 +2451,7 @@ typedef struct DCI2C_10MHz_TDD DCI2C_10MHz_TDD_t; /// DCI Format Type 2C (20 MHz, TDD, 53 bits) struct DCI2C_20MHz_TDD { /// padding to 64bits - uint64_t padding64:11; + uint64_t padding:11; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2488,7 +2486,7 @@ typedef struct DCI2C_20MHz_TDD DCI2C_20MHz_TDD_t; /// DCI Format Type 2C (1.5 MHz, FDD, 30 bits) struct DCI2C_1_5MHz_FDD { //padding for 32 bits - uint32_t padding32:2; + uint32_t padding:2; /// Redundancy version 2 uint32_t rv2:2; /// New Data Indicator 2 @@ -2517,7 +2515,7 @@ typedef struct DCI2C_1_5MHz_FDD DCI2C_1_5MHz_FDD_t; /// DCI Format Type 2C (5 MHz, FDD, 38 bits) struct DCI2C_5MHz_FDD { /// padding for 64-bit - uint64_t padding64:26; + uint64_t padding:26; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2548,7 +2546,7 @@ typedef struct DCI2C_5MHz_FDD DCI2C_5MHz_FDD_t; /// DCI Format Type 2C (10 MHz, FDD, 42 bits) struct DCI2C_10MHz_FDD { /// padding for 64-bit - uint64_t padding64:22; + uint64_t padding:22; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2579,7 +2577,7 @@ typedef struct DCI2C_10MHz_FDD DCI2C_10MHz_FDD_t; /// DCI Format Type 2C (20 MHz, FDD, 50 bits) struct DCI2C_20MHz_FDD { /// padding for 64-bit - uint64_t padding64:14; + uint64_t padding:14; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -2613,7 +2611,7 @@ typedef struct DCI2C_20MHz_FDD DCI2C_20MHz_FDD_t; /// DCI Format Type 2D (1.5 MHz, TDD, 36 bits) struct DCI2D_1_5MHz_TDD { - uint64_t padding64:28; + uint64_t padding:28; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2648,7 +2646,7 @@ typedef struct DCI2D_1_5MHz_TDD DCI2D_1_5MHz_TDD_t; /// DCI Format Type 2D (5 MHz, TDD, 43 bits) struct DCI2D_5MHz_TDD { /// padding to 64bits - uint64_t padding64:21; + uint64_t padding:21; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2685,7 +2683,7 @@ typedef struct DCI2D_5MHz_TDD DCI2D_5MHz_TDD_t; /// DCI Format Type 2D (10 MHz, TDD, 47 bits) struct DCI2D_10MHz_TDD { /// padding to 64bits - uint64_t padding64:17; + uint64_t padding:17; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2722,7 +2720,7 @@ typedef struct DCI2D_10MHz_TDD DCI2D_10MHz_TDD_t; /// DCI Format Type 2D (20 MHz, TDD, 55 bits) struct DCI2D_20MHz_TDD { /// padding to 64bits - uint64_t padding64:9; + uint64_t padding:9; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2759,7 +2757,7 @@ typedef struct DCI2D_20MHz_TDD DCI2D_20MHz_TDD_t; /// DCI Format Type 2D (1.5 MHz, FDD, 33 bits) struct DCI2D_1_5MHz_FDD { //padding for 33 bits - uint64_t padding64:31; + uint64_t padding:31; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2783,7 +2781,7 @@ struct DCI2D_1_5MHz_FDD { /// RB Assignment (ceil(log2(N_RB_DL/P)) bits) uint64_t rballoc:6; /// padding for ambiguity - uint64_t padding; + uint64_t padding0; } __attribute__ ((__packed__)); typedef struct DCI2D_1_5MHz_FDD DCI2D_1_5MHz_FDD_t; @@ -2792,7 +2790,7 @@ typedef struct DCI2D_1_5MHz_FDD DCI2D_1_5MHz_FDD_t; /// DCI Format Type 2D (5 MHz, FDD, 41 bits) struct DCI2D_5MHz_FDD { /// padding for 64-bit - uint64_t padding64:23; + uint64_t padding:23; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2818,7 +2816,7 @@ struct DCI2D_5MHz_FDD { /// Resource Allocation Header uint64_t rah:1; /// padding for ambiguity - uint64_t padding:1; + uint64_t padding0:1; } __attribute__ ((__packed__)); #define sizeof_DCI2D_5MHz_FDD_t 41 @@ -2827,7 +2825,7 @@ typedef struct DCI2D_5MHz_FDD DCI2D_5MHz_FDD_t; /// DCI Format Type 2D (10 MHz, FDD, 45 bits) struct DCI2D_10MHz_FDD { /// padding for 64-bit - uint64_t padding64:19; + uint64_t padding:19; /// PDSCH REsource Mapping and Quasi-Co-Location Indicator uint64_t REMQCL:2; /// Redundancy version 2 @@ -2853,7 +2851,7 @@ struct DCI2D_10MHz_FDD { /// Resource Allocation Header uint64_t rah:1; /// padding for ambiguity - uint64_t padding:1; + uint64_t padding0:1; } __attribute__ ((__packed__)); #define sizeof_DCI2D_10MHz_FDD_t 45 @@ -2862,7 +2860,7 @@ typedef struct DCI2D_10MHz_FDD DCI2D_10MHz_FDD_t; /// DCI Format Type 2D (20 MHz, FDD, 52 bits) struct DCI2D_20MHz_FDD { /// padding for 64-bit - uint64_t padding64:12; + uint64_t padding:12; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 3c6a5ded2c..e0c9c043c5 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -818,8 +818,7 @@ int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) for (i=0; idlsch[i]!=NULL,"eNB->dlsch[%d] is null\n",i); AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d][0] is null\n",i); - LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n", - rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index); + LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index); if ((eNB->dlsch[i][0]->harq_mask >0) && (eNB->dlsch[i][0]->rnti==rnti)) return i; else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; @@ -907,6 +906,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; } else { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_FDD_t; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->type = 1; @@ -917,6 +917,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -931,7 +932,8 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_5MHz_FDD_t; @@ -943,6 +945,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -958,6 +961,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_10MHz_FDD_t; @@ -969,6 +973,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_10MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -984,6 +989,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_20MHz_FDD_t; @@ -995,6 +1001,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_20MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1004,7 +1011,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a proc->frame_tx, proc->subframe_tx, rel8->rnti); } -void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) +void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; @@ -1028,7 +1035,6 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; int beamforming_mode = 0; int UE_id=-1; - int subframe = proc->subframe_tx; int NPRB; int TB0_active; int TB1_active; @@ -1041,8 +1047,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci dci_alloc->harq_pid = rel8->harq_process; dci_alloc->ra_flag = 0; - LOG_D(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n", - rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process); + LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[SFN/SF:%04d%d] DCI format %d, nCCE %d, L %d, rnti %x, harq_pid %d\n", + frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process); if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1; UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); @@ -1058,6 +1064,14 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch1_harq->codeword = 1; dlsch0->subframe_tx[subframe] = 1; + + LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d dlsch0[rnti:%x harq_mask:%04x] dci_pdu[rnti:%x rnti_type:%d harq_process:%d ndi1:%d] dlsch0_harq[round:%d harq_mask:%x ndi:%d]\n", + frame,subframe, + proc->frame_tx,proc->subframe_tx, + dlsch0->rnti,dlsch0->harq_mask, + rel8->rnti, rel8->rnti_type, rel8->harq_process, rel8->new_data_indicator_1, + dlsch0_harq->round, dlsch0->harq_mask, dlsch0_harq->ndi); + if (dlsch0->rnti != rel8->rnti) { // if rnti of dlsch is not the same as in the config, this is a new entry dlsch0_harq->round=0; dlsch0->harq_mask=0; @@ -1078,15 +1092,19 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci #endif if (rel8->rnti_type == 2) dlsch0_harq->round = 0; -LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round, - dlsch0_harq->ndi,rel8->new_data_indicator_1, rel8->rnti_type); + + LOG_D(PHY,"NFAPI: rel8[rnti %x dci_format %d harq_process %d ndi1 %d rnti type %d] dlsch0[rnti %x harq_mask %x] dlsch0_harq[round %d ndi %d]\n", + rel8->rnti,rel8->dci_format,rel8->harq_process, rel8->new_data_indicator_1, rel8->rnti_type, + dlsch0->rnti,dlsch0->harq_mask, + dlsch0_harq->round,dlsch0_harq->ndi + ); switch (rel8->dci_format) { case NFAPI_DL_DCI_FORMAT_1A: - AssertFatal(rel8->resource_block_coding < 8192, "Frame %d, Subframe %d: rel8->resource_block_coding (%p) %u >= 8192 (rnti %x, rnti_type %d, format %d, harq_id %d\n", - proc->frame_tx,subframe, + AssertFatal(rel8->resource_block_coding < 8192, "SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: rel8->resource_block_coding (%p) %u >= 8192 (rnti %x, rnti_type %d, format %d, harq_id %d\n", + frame,subframe,proc->frame_tx,subframe, &rel8->resource_block_coding,rel8->resource_block_coding,rel8->rnti,rel8->rnti_type,rel8->dci_format,rel8->harq_process); @@ -1105,6 +1123,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; } else { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_FDD_t; @@ -1116,6 +1135,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); @@ -1134,7 +1154,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_5MHz_FDD_t; @@ -1146,6 +1167,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); @@ -1164,7 +1186,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_10MHz_FDD_t; @@ -1176,6 +1199,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_10MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); @@ -1195,7 +1219,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_20MHz_FDD_t; @@ -1207,6 +1232,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1A_20MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); @@ -1229,7 +1255,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" NPRB = dlsch0_harq->nb_rb; I_mcs = get_I_TBS(rel8->mcs_1); } - AssertFatal(NPRB>0,"DCI 1A: NPRB = 0 (rnti %x, rnti type %d, tpc %d, round %d, resource_block_coding %d)\n",rel8->rnti,rel8->rnti_type,rel8->tpc,dlsch0_harq->round,rel8->resource_block_coding); + AssertFatal(NPRB>0,"DCI 1A: NPRB = 0 (rnti %x, rnti type %d, tpc %d, round %d, resource_block_coding %d, harq process %d)\n",rel8->rnti,rel8->rnti_type,rel8->tpc,dlsch0_harq->round,rel8->resource_block_coding,rel8->harq_process); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch0_harq->Nl = 1; dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI; @@ -1253,7 +1279,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" dlsch0->harq_mask |= (1<harq_process); - if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x,rv %d, rnti %x\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti); + if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti,rel8->harq_process); break; case NFAPI_DL_DCI_FORMAT_1: @@ -1265,7 +1291,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" dlsch0->active = 1; #endif - LOG_D(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process); + LOG_D(PHY,"SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",frame,subframe,proc->frame_tx,subframe,rel8->harq_process); switch (fp->N_RB_DL) { case 6: @@ -1278,7 +1304,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1_1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_1_5MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_1_5MHz_FDD_t; @@ -1289,6 +1316,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1302,7 +1330,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_5MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_5MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_5MHz_FDD_t; @@ -1313,6 +1342,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1326,7 +1356,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_10MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1_10MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_10MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_10MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_10MHz_FDD_t; @@ -1337,6 +1368,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1_10MHz_FDD_t *)dci_pdu)->padding = 0; } break; case 100: @@ -1349,7 +1381,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_20MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI1_20MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_20MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI1_20MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_20MHz_FDD_t; @@ -1360,6 +1393,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI1_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; + ((DCI1_20MHz_FDD_t *)dci_pdu)->padding = 0; } break; } @@ -1448,6 +1482,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + /* there is no padding in this structure, it is exactly 32 bits */ // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; @@ -1462,6 +1497,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1478,8 +1514,9 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; - ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; @@ -1494,6 +1531,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1510,8 +1548,9 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; - ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; @@ -1525,7 +1564,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->padding = 0; } break; case 100: @@ -1541,8 +1581,9 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; - ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; @@ -1556,7 +1597,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; @@ -1795,6 +1837,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; @@ -1809,6 +1852,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1828,6 +1872,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_5MHz_2A_FDD_t; @@ -1842,7 +1887,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; - ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; @@ -1862,6 +1908,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_10MHz_2A_FDD_t; @@ -1875,13 +1922,14 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; case 100: if (fp->frame_type == TDD) { - dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_TDD_t; + dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_TDD_t; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; @@ -1892,12 +1940,13 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; - ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; + ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { - dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_FDD_t; + dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_FDD_t; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; @@ -1908,8 +1957,9 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; - ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; + ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; + ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; @@ -2180,11 +2230,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" } if (dlsch0_harq) { - dlsch0_harq->frame = proc->frame_tx; + dlsch0_harq->frame = frame; dlsch0_harq->subframe = subframe; } if (dlsch1_harq) { - dlsch1_harq->frame = proc->frame_tx; + dlsch1_harq->frame = frame; dlsch1_harq->subframe = subframe; } @@ -2222,7 +2272,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n" #if T_TRACER if (dlsch0->active) - T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx), + T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe), T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process), T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS)); #endif @@ -2292,6 +2342,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1A_5MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1A_5MHz_t *)dci_pdu)->padding = 0; break; case 50: @@ -2308,6 +2359,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1A_10MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1A_10MHz_t *)dci_pdu)->padding = 0; break; case 100: dci_alloc->dci_length = sizeof_DCI6_1A_20MHz_t; @@ -2323,6 +2375,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1A_20MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1A_20MHz_t *)dci_pdu)->padding = 0; break; } break; @@ -2345,6 +2398,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1B_5MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1B_5MHz_t *)dci_pdu)->padding = 0; break; case 50: @@ -2357,6 +2411,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1B_10MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1B_10MHz_t *)dci_pdu)->padding = 0; break; case 100: dci_alloc->dci_length = sizeof_DCI6_1B_20MHz_t; @@ -2368,6 +2423,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_1B_20MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_1B_20MHz_t *)dci_pdu)->padding = 0; break; } case 12: // Format 6-2 @@ -2383,6 +2439,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_5MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_5MHz_t *)dci_pdu)->di_info = rel13->direct_indication; + ((DCI6_2_di_5MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_5MHz_t *)dci_pdu)->type = 1; @@ -2390,6 +2447,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_2_paging_5MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_5MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_2_paging_5MHz_t *)dci_pdu)->padding = 0; } break; @@ -2398,6 +2456,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_10MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_10MHz_t *)dci_pdu)->di_info = rel13->direct_indication; + ((DCI6_2_di_10MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_10MHz_t *)dci_pdu)->type = 1; @@ -2405,6 +2464,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_2_paging_10MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_10MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_2_paging_10MHz_t *)dci_pdu)->padding = 0; } break; @@ -2413,6 +2473,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_20MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_20MHz_t *)dci_pdu)->di_info = rel13->direct_indication; + ((DCI6_2_di_20MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_20MHz_t *)dci_pdu)->type = 1; @@ -2420,6 +2481,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d ((DCI6_2_paging_20MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_20MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; + ((DCI6_2_paging_20MHz_t *)dci_pdu)->padding = 0; } break; @@ -2485,8 +2547,8 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d } -void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, - nfapi_hi_dci0_dci_pdu *pdu) +void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, + DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu) { LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; @@ -2503,8 +2565,8 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, uint32_t ndi = pdu->dci_pdu_rel8.new_data_indication_1; #ifdef T_TRACER - T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx), - T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((proc->frame_tx*10+proc->subframe_tx+4) % 8) /* TODO: correct harq pid */), + T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((frame*10+subframe+4) % 8) /* TODO: correct harq pid */), T_INT(mcs), T_INT(-1 /* TODO: remove round? */), T_INT(pdu->dci_pdu_rel8.resource_block_start), T_INT(pdu->dci_pdu_rel8.number_of_resource_block), @@ -2515,9 +2577,11 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, void *dci_pdu = (void*)dci_alloc->dci_pdu; - LOG_D(PHY,"Filling DCI0 with cqi %d, mcs %d, hopping %d, rballoc %x (%d,%d) ndi %d TPC %d cshift %d\n",cqi_req, - mcs,hopping,rballoc,pdu->dci_pdu_rel8.resource_block_start,pdu->dci_pdu_rel8.number_of_resource_block, - ndi,TPC,cshift); + LOG_D(PHY,"SFN/SF:%04d%d DCI0[rnti %x cqi %d mcs %d hopping %d rballoc %x (%d,%d) ndi %d TPC %d cshift %d]\n", + frame,subframe, + pdu->dci_pdu_rel8.rnti,cqi_req, mcs,hopping,rballoc, + pdu->dci_pdu_rel8.resource_block_start, + pdu->dci_pdu_rel8.number_of_resource_block, ndi,TPC,cshift); dci_alloc->format = format0; dci_alloc->firstCCE = pdu->dci_pdu_rel8.cce_index; @@ -2680,10 +2744,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->dci_alloc = 1; ulsch->harq_processes[harq_pid]->rar_alloc = 0; ulsch->harq_processes[harq_pid]->n_DMRS = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms; - + ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch->harq_processes[harq_pid]->srs_active = use_srs; - + //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) if(ulsch->harq_processes[harq_pid]->n_DMRS == 0) ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; @@ -2701,23 +2765,25 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - - LOG_D(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n", - eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS, - frame,subframe); - + + LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d\n", + eNB->Mod_id,harq_pid,frame,subframe, + ulsch->harq_processes[harq_pid]->n_DMRS2, + ulsch->harq_processes[harq_pid]->n_DMRS, + ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status); + ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type; - // Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be + // Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be ulsch->harq_processes[harq_pid]->O_ACK = 0; if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) || (ulsch->harq_processes[harq_pid]->ndi != ulsch_pdu->ulsch_pdu_rel8.new_data_indication) || (new_ulsch == TRUE)){ ulsch->harq_processes[harq_pid]->status = ACTIVE; - + ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; - + ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch; ulsch->harq_processes[harq_pid]->round = 0; @@ -2738,19 +2804,21 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu } #endif ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti; - LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n", + LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, status %d, handled %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n", ulsch->rnti, UE_id, new_ulsch, frame, subframe, harq_pid, + ulsch->harq_processes[harq_pid]->status, + ulsch->harq_processes[harq_pid]->handled, ulsch->harq_processes[harq_pid]->first_rb, ulsch->harq_processes[harq_pid]->nb_rb, ulsch->harq_processes[harq_pid]->rvidx, ulsch->harq_processes[harq_pid]->Qm, ulsch->harq_processes[harq_pid]->TBS, - ulsch->harq_processes[harq_pid]->round); + ulsch->harq_processes[harq_pid]->round); } int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) @@ -6514,7 +6582,7 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t uint8_t ret = 255; if (frame_parms->frame_type == FDD) { - ret = (((frame<<1)+subframe)&7); + ret = (((frame*10)+subframe)&7); } else { switch (frame_parms->tdd_config) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 7482524d41..bd5c1b05c2 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -252,6 +252,7 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) #else dlsch->active = 0; #endif + dlsch->harq_mask = 0; for (i=0; i<10; i++) dlsch->harq_ids[i] = Mdlharq; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 271de54795..7acf6480eb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -758,318 +758,3 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return(ret); } -#ifdef PHY_ABSTRACTION -#include "SIMULATION/TOOLS/defs.h" -#ifdef OPENAIR2 -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" -#endif - -int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], uint8_t mcs, uint8_t dl_power_off) -{ - - int ii; - double sinr_eff = 0; - int rb_count = 0; - int offset; - double bler = 0; - - if(TM==5 && dl_power_off==1) { - //do nothing -- means there is no second UE and TM 5 is behaving like TM 6 for a singal user - } else - TM = TM-1; - - for (offset = 0; offset <= 24; offset++) { - if (rb_alloc[0] & (1<qpsk_max) - I += 1; - else - I += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]); - } else if(mcs>9 && mcs<17) { - if(x>qam16_max) - I += 1; - else - I += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]); - } else if(mcs>16 && mcs<23) { - - if(x>qam64_max) - I += 1; - else - I += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]); - } - } - } - } - } - - // averaging of accumulated MI - I = I/(12*rb_count); - //Now I->SINR_effective Mapping - - if(mcs<10) { - sinr_eff = (p_qpsk[0]*pow(I,7) + p_qpsk[1]*pow(I,6) + p_qpsk[2]*pow(I,5) + p_qpsk[3]*pow(I,4) + p_qpsk[4]*pow(I,3) + p_qpsk[5]*pow(I,2) + p_qpsk[6]*I + p_qpsk[7]); - } else if(mcs>9 && mcs<17) { - sinr_eff = (p_qam16[0]*pow(I,7) + p_qam16[1]*pow(I,6) + p_qam16[2]*pow(I,5) + p_qam16[3]*pow(I,4) + p_qam16[4]*pow(I,3) + p_qam16[5]*pow(I,2) + p_qam16[6]*I + p_qam16[7]); - } else if(mcs>16 && mcs<23) { - sinr_eff = (p_qam64[0]*pow(I,7) + p_qam64[1]*pow(I,6) + p_qam64[2]*pow(I,5) + p_qam64[3]*pow(I,4) + p_qam64[4]*pow(I,3) + p_qam64[5]*pow(I,2) + p_qam64[6]*I + p_qam64[7]); - } - - //sinr_eff = sinr_eff + 10*log10(beta2_dlsch_MI[TM][mcs]); - LOG_D(OCM,"SINR_Eff = %e\n",sinr_eff); - - bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]); - -#ifdef USER_MODE // need to be adapted for the emulation in the kernel space - - if (uniformrandom() < bler) { - LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(0); - } else { - LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(1); - } - -#endif -} - -/* -uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, - uint8_t subframe, - PDSCH_t dlsch_id, - uint8_t eNB_id) -{ - - LTE_UE_DLSCH_t *dlsch_ue; - LTE_eNB_DLSCH_t *dlsch_eNB; - uint8_t harq_pid; - uint32_t eNB_id2; - uint32_t ue_id; -#ifdef DEBUG_DLSCH_DECODING - uint16_t i; -#endif - uint8_t CC_id = phy_vars_ue->CC_id; - - // may not be necessary for PMCH?? - for (eNB_id2=0; eNB_id2frame_parms.Nid_cell == phy_vars_ue->frame_parms.Nid_cell) - break; - } - - AssertFatal(eNB_id2!=NB_eNB_INST, - "FATAL : Could not find attached eNB for DLSCH emulation !!!!\n"); - - LOG_D(PHY,"[UE] dlsch_decoding_emul : subframe %d, eNB_id %d, dlsch_id %d\n",subframe,eNB_id2,dlsch_id); - - // printf("dlsch_eNB_ra->harq_processes[0] %p\n",PHY_vars_eNB_g[eNB_id]->dlsch_eNB_ra->harq_processes[0]); - - - switch (dlsch_id) { - case SI_PDSCH: // SI - dlsch_ue = phy_vars_ue->dlsch_SI[eNB_id]; - dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch_SI; - // printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3); - memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3); -#ifdef DEBUG_DLSCH_DECODING - LOG_D(PHY,"SI Decoded\n"); - - for (i=0; iharq_processes[0]->TBS>>3; i++) - LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[0]->b[i]); - - LOG_T(PHY,"\n"); -#endif - return(1); - break; - - case RA_PDSCH: // RA - dlsch_ue = phy_vars_ue->dlsch_ra[eNB_id]; - dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch_ra; - memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3); -#ifdef DEBUG_DLSCH_DECODING - LOG_D(PHY,"RA Decoded\n"); - - for (i=0; iharq_processes[0]->TBS>>3; i++) - LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[0]->b[i]); - - LOG_T(PHY,"\n"); -#endif - return(1); - break; - - case PDSCH: // TB0 - dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; - harq_pid = dlsch_ue->current_harq_pid; - ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][(uint32_t)eNB_id]->crnti,RC.eNB[eNB_id2][CC_id]); - DevAssert( ue_id != (uint32_t)-1 ); - dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch[ue_id][0]; - -#ifdef DEBUG_DLSCH_DECODING - - for (i=0; iharq_processes[harq_pid]->TBS>>3; i++) - LOG_T(PHY,"%x.",dlsch_eNB->harq_processes[harq_pid]->b[i]); - - LOG_T(PHY,"\n current harq pid is %d ue id %d \n", harq_pid, ue_id); -#endif - - if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB, - phy_vars_ue->transmission_mode[eNB_id], - dlsch_eNB->harq_processes[harq_pid]->rb_alloc, - dlsch_eNB->harq_processes[harq_pid]->mcs, - RC.eNB[eNB_id][CC_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) { - // reset HARQ - dlsch_ue->harq_processes[harq_pid]->status = SCH_IDLE; - dlsch_ue->harq_processes[harq_pid]->round = 0; - dlsch_ue->harq_ack[subframe].ack = 1; - dlsch_ue->harq_ack[subframe].harq_id = harq_pid; - dlsch_ue->harq_ack[subframe].send_harq_status = 1; - - if (dlsch_ue->harq_processes[harq_pid]->round == 0) - memcpy(dlsch_ue->harq_processes[harq_pid]->b, - dlsch_eNB->harq_processes[harq_pid]->b, - dlsch_ue->harq_processes[harq_pid]->TBS>>3); - - return(1); - } else { - // retransmission - dlsch_ue->harq_processes[harq_pid]->status = ACTIVE; - dlsch_ue->harq_processes[harq_pid]->round++; - dlsch_ue->harq_ack[subframe].ack = 0; - dlsch_ue->harq_ack[subframe].harq_id = harq_pid; - dlsch_ue->harq_ack[subframe].send_harq_status = 1; - dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; - return(1+dlsch_ue->max_turbo_iterations); - } - - break; - - case PDSCH1: { // TB1 - dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]; - harq_pid = dlsch_ue->current_harq_pid; - int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->crnti, RC.eNB[eNB_id2][CC_id] ); - - DevAssert( UE_id != -1 ); - dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch[UE_id][1]; - // reset HARQ - dlsch_ue->harq_processes[harq_pid]->status = SCH_IDLE; - dlsch_ue->harq_processes[harq_pid]->round = 0; - dlsch_ue->harq_ack[subframe].ack = 1; - dlsch_ue->harq_ack[subframe].harq_id = harq_pid; - dlsch_ue->harq_ack[subframe].send_harq_status = 1; - - if (dlsch_ue->harq_processes[harq_pid]->round == 0) - memcpy(dlsch_eNB->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->b,dlsch_ue->harq_processes[harq_pid]->TBS>>3); - - break; - } - - case PMCH: // PMCH - - dlsch_ue = phy_vars_ue->dlsch_MCH[eNB_id]; - dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch_MCH; - - LOG_D(PHY,"decoding pmch emul (size is %d, enb %d %d)\n", dlsch_ue->harq_processes[0]->TBS>>3, eNB_id, eNB_id2); -#ifdef DEBUG_DLSCH_DECODING - - for (i=0; iharq_processes[0]->TBS>>3; i++) - printf("%x.",dlsch_eNB->harq_processes[0]->b[i]); - - printf("\n"); -#endif - - - // if (dlsch_abstraction_MIESM(phy_vars_ue->sinr_dB, phy_vars_ue->transmission_mode[eNB_id], dlsch_eNB->rb_alloc, - // dlsch_eNB->harq_processes[0]->mcs,RC.eNB[eNB_id]->mu_mimo_mode[ue_id].dl_pow_off) == 1) { - - if (1) { - // reset HARQ - dlsch_ue->harq_processes[0]->status = SCH_IDLE; - dlsch_ue->harq_processes[0]->round = 0; - memcpy(dlsch_ue->harq_processes[0]->b, - dlsch_eNB->harq_processes[0]->b, - dlsch_ue->harq_processes[0]->TBS>>3); - dlsch_ue->last_iteration_cnt = 1; - return(1); - } else { - // retransmission - dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; - return(1+dlsch_ue->max_turbo_iterations); - } - - break; - - default: - dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; - LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id); - dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; - return(1+dlsch_ue->max_turbo_iterations); - } - - LOG_E(PHY,"[FATAL] dlsch_decoding.c: Should never exit here ...\n"); - return(0); - }*/ -#endif - diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index f53e83dbaf..1bd0076e14 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -37,11 +37,7 @@ #include "PHY/sse_intrin.h" #include "T.h" -#ifndef USER_MODE -#define NOCYGWIN_STATIC static -#else #define NOCYGWIN_STATIC -#endif /* dynamic shift for LLR computation for TM3/4 * set as command line argument, see lte-softmodem.c @@ -6027,9 +6023,6 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, //============================================================================================== -#ifdef USER_MODE - - void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) { unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; @@ -6119,7 +6112,6 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c // printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh); } -#endif #ifdef DEBUG_DLSCH_DEMOD /* diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 90450b7c1c..49b41615f4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -38,7 +38,7 @@ #include "defs.h" #include "UTIL/LOG/vcd_signal_dumper.h" -//#define DEBUG_DLSCH_MODULATION +//#define DEBUG_DLSCH_MODULATION 1 //#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0) @@ -78,7 +78,7 @@ uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) && (re!=((nushift+8+offset)%12))) return(1); /*else{ - printf("(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset); + LOG_I(PHY,"(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset); }*/ } else { if ((re!=nushift+offset) && (re!=((nushift+3+offset)%12)) && (re!=((nushift+6+offset)%12)) && (re!=((nushift+9+offset)%12))) @@ -270,7 +270,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, if (skip_dc == 0) { - // printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); + // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; re<12; x0p+=4) { @@ -281,7 +281,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; - // printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); + // LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } @@ -497,7 +497,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, if (skip_dc == 0) { - // printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); + // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; re<12; x0p+=6) { @@ -510,7 +510,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; - // printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); + // LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } @@ -667,11 +667,11 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, if (dlsch0_harq != NULL){ #ifdef DEBUG_DLSCH_MODULATION - printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); + LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); #endif } else{ #ifdef DEBUG_DLSCH_MODULATION - printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); + LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); #endif } @@ -685,7 +685,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, for (re=first_re; reofdm_symbol_size+1; @@ -695,7 +695,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, //check that RE is not from Cell-specific RS if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) { - //printf("re %d (jj %d)\n",re,*jj); + //LOG_I(PHY,"re %d (jj %d)\n",re,*jj); if (mimo_mode == SISO) { //SISO mapping @@ -705,7 +705,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, case 2: //QPSK - //printf("re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; @@ -971,12 +971,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, break; case 2: //QPSK - //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; - //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; case 4: //16QAM @@ -1042,12 +1042,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, break; case 2: //QPSK - //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; - //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; case 4: //16QAM @@ -1114,7 +1114,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1); ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1)); /* - printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n", + LOG_I(PHY,"CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n", xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1], ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]); */ @@ -1244,7 +1244,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, precoder_index1 = 3; //[1 -j] } else { - printf("problem with precoder in TM4\n"); + LOG_I(PHY,"problem with precoder in TM4\n"); return(-1); } @@ -1263,7 +1263,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); @@ -1466,7 +1466,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&txdataF[5][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; - //printf("%d(%d) : %d,%d => + //LOG_I(PHY,"%d(%d) : %d,%d => //",tti_offset,*jj,((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[1]); break; @@ -1545,7 +1545,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, } } else { //precoding UE spec RS - //printf("precoding UE spec RS\n"); + //LOG_I(PHY,"precoding UE spec RS\n"); ind = 3*lprime*dlsch0_harq->nb_rb+mprime2; ind_dword = ind>>4; @@ -1563,7 +1563,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, switch (mod_order0) { case 2: //QPSK - // printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + // LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) { ((int16_t*)&txdataF[layer][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; @@ -1651,7 +1651,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, } } } else if (mimo_mode>=TM9_10) { - printf("allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode); + LOG_I(PHY,"allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode); return(-1); } } @@ -1686,7 +1686,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, uint8_t first_re,last_re; int inc; #ifdef DEBUG_DLSCH_MODULATION - printf("allocate_re_MCH (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]); + LOG_I(PHY,"allocate_re_MCH (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]); #endif last_re=12; @@ -1707,7 +1707,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, tti_offset = symbol_offset + re_off + re; - //printf("re %d (jj %d)\n",re,*jj); + //LOG_I(PHY,"re %d (jj %d)\n",re,*jj); *re_allocated = *re_allocated + 1; @@ -1715,7 +1715,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, case 2: //QPSK - // printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + // LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); ((int16_t*)&txdataF[4][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; @@ -1724,7 +1724,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, *jj = *jj + 1; - //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; @@ -1931,7 +1931,7 @@ inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline)); inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) { - // printf("check_skiphalf : rb %d, subframe_offset %d,l %d, nsymb %d\n",rb,subframe_offset,l,nsymb); + // LOG_I(PHY,"check_skiphalf : rb %d, subframe_offset %d,l %d, nsymb %d\n",rb,subframe_offset,l,nsymb); if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL @@ -2154,19 +2154,19 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, re_allocated=0; - // printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); + // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); for (l=num_pdcch_symbols; lmimo_mode, pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), mod_order0, mod_order1, - rb_alloc[0], - len); + rb_alloc[0] + ); #endif } @@ -2216,6 +2216,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, for (eNB_id=0;eNB_idnum_eNB;eNB_id++){ if (phy_vars_eNB == ru->eNB_list[eNB_id]) { for (aa=0;aanb_tx;aa++){ + LOG_I(PHY,"ru_id:%d eNB_id:%d aa:%d memcpy(ru->beam_weights, dlsch0->ue_spec_bf_weights[ru_id][0],)\n", ru_id, eNB_id, aa); memcpy(ru->beam_weights[eNB_id][5][aa], dlsch0->ue_spec_bf_weights[ru_id][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)); @@ -2233,7 +2234,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, if (pilots>0) { // compute pilot arrays, could be done statically if performance suffers if (frame_parms->nb_antenna_ports_eNB == 1) { - // printf("l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset); + // LOG_I(PHY,"l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset); for (i=0,i2=0;i<12;i++) { if ((i!=(frame_parms->nushift+offset)) && (i!=((frame_parms->nushift+6+offset)%12))) P1_SHIFT[i2++]=1; @@ -2340,7 +2341,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, //for (aa=0;aanb_antennas_tx;aa++) //memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2); - //printf("symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots); + //LOG_I(PHY,"symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots); for (rb=0; rbN_RB_DL; rb++) { if (rb < 32) @@ -2371,7 +2372,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, if (dlsch1) { if (dlsch1_harq->Nlayers>1) { - printf("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); + LOG_I(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); return(-1); } } @@ -2379,7 +2380,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, if (rb_alloc_ind > 0) { - // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); + // LOG_I(PHY,"Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); if (dlsch0 != NULL) { get_pmi_temp = get_pmi(frame_parms->N_RB_DL, @@ -2419,7 +2420,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, mprime +=3+frame_parms->Ncp; } else { - // printf("Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj); + // LOG_I(PHY,"Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj); } re_offset+=12; // go to next RB @@ -2436,9 +2437,9 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, #ifdef DEBUG_DLSCH_MODULATION if (dlsch0 != NULL){ - printf("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset)); + LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1)); }else{ - printf("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset)); + LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset,1)); } #endif @@ -2493,7 +2494,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, jj = jj + 1; - //printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); + //LOG_I(PHY,"recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); i++; break; @@ -2580,7 +2581,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, #ifdef DEBUG_DLSCH_MODULATION - printf("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1/*transmission mode*/)); + LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1/*transmission mode*/)); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT); @@ -2618,11 +2619,11 @@ int mch_modulation(int32_t **txdataF, jj=0; re_allocated=0; - // printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); + // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); for (l=2; lfirst_carrier_offset; @@ -2647,7 +2648,7 @@ int mch_modulation(int32_t **txdataF, else qam_table_s = NULL; - //printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); + //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); allocate_REs_in_RB_MCH(txdataF, &jj, re_offset, @@ -2674,7 +2675,7 @@ int mch_modulation(int32_t **txdataF, } #ifdef DEBUG_DLSCH_MODULATION - printf("generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/)); + LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/)); #endif return (re_allocated); diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c index 2a94d77b8e..a432cde4e4 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c @@ -81,7 +81,6 @@ int generate_drs_pusch(PHY_VARS_UE *ue, // cyclic_shift1 = 0; Msc_RS = 12*nb_rb; -#ifdef USER_MODE Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints); if (Msc_idx_ptr) @@ -91,20 +90,6 @@ int generate_drs_pusch(PHY_VARS_UE *ue, return(-1); } -#else - uint8_t b; - - for (b=0; b<33; b++) - if (Msc_RS==dftsizes[b]) - Msc_RS_idx = b; - -#endif -#ifdef DEBUG_DRS - printf("[PHY] drs_modulation: Msc_RS = %d, Msc_RS_idx = %d,cyclic_shift %d, u0 %d, v0 %d, u1 %d, v1 %d,cshift0 %d,cshift1 %d\n",Msc_RS, Msc_RS_idx,cyclic_shift,u0,v0,u1,v1,cyclic_shift0,cyclic_shift1); - -#endif - - for (l = (3 - frame_parms->Ncp),u=u0,v=v0,cyclic_shift=cyclic_shift0; lsymbols_per_tti; l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index 49a60ae9e8..37b1c56349 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -29,11 +29,9 @@ * \note * \warning */ -#ifdef USER_MODE #include #include #include -#endif #include "PHY/defs.h" #include "PHY/extern.h" #include "SCHED/defs.h" diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c index d1880b0c55..918696968b 100644 --- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c +++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c @@ -237,10 +237,6 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; ue->proc.proc_rxtx[i].frame_rx = (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2; -#ifndef USER_MODE - // one frame delay - ue->proc.proc_rxtx[i].frame_rx ++; -#endif ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; } #ifdef DEBUG_INITIAL_SYNCH diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index e86f225157..9e5b6757fc 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -37,11 +37,6 @@ #include "PHY/extern.h" #include "PHY/sse_intrin.h" -#ifdef PHY_ABSTRACTION -#include "SIMULATION/TOOLS/defs.h" -#endif - - //#define DEBUG_PBCH 1 //#define DEBUG_PBCH_ENCODING //#define INTERFERENCE_MITIGATION 1 @@ -174,6 +169,8 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, pbch_E = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK) // pbch_E_bytes = pbch_coded_bits>>3; + LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0); + if (frame_mod4==0) { bzero(pbch_a,PBCH_A>>3); bzero(eNB_pbch->pbch_e,pbch_E); @@ -258,13 +255,11 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, #endif #ifdef DEBUG_PBCH - #ifdef USER_MODE write_output("pbch_encoded_output2.m","pbch_encoded_out2", pbch_coded_data2, pbch_coded_bits, 1, 4); - #endif //USER_MODE #endif //DEBUG_PBCH */ #ifdef DEBUG_PBCH_ENCODING @@ -286,8 +281,6 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, #ifdef DEBUG_PBCH -#ifdef USER_MODE - if (frame_mod4==0) { write_output("pbch_e.m","pbch_e", eNB_pbch->pbch_e, @@ -298,8 +291,6 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, for (i=0; i<16; i++) printf("e[%d] %d\n",i,eNB_pbch->pbch_e[i]); } - -#endif //USER_MODE #endif //DEBUG_PBCH // scrambling @@ -307,8 +298,6 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, eNB_pbch->pbch_e, pbch_E); #ifdef DEBUG_PBCH -#ifdef USER_MODE - if (frame_mod4==0) { write_output("pbch_e_s.m","pbch_e_s", eNB_pbch->pbch_e, @@ -319,8 +308,6 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, for (i=0; i<16; i++) printf("e_s[%d] %d\n",i,eNB_pbch->pbch_e[i]); } - -#endif //USER_MODE #endif //DEBUG_PBCH } // frame_mod4==0 @@ -1026,44 +1013,3 @@ uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars, } - -#ifdef PHY_ABSTRACTION -uint16_t rx_pbch_emul(PHY_VARS_UE *phy_vars_ue, - uint8_t eNB_id, - uint8_t pbch_phase) -{ - - double bler=0.0;//, x=0.0; - double sinr=0.0; - uint16_t nb_rb = phy_vars_ue->frame_parms.N_RB_DL; - int16_t f; - uint8_t CC_id=phy_vars_ue->CC_id; - int frame_rx = phy_vars_ue->proc.proc_rxtx[0].frame_rx; - - // compute effective sinr - // TODO: adapt this to varible bandwidth - for (f=(nb_rb*6-3*12); f<(nb_rb*6+3*12); f++) { - if (f!=0) //skip DC - sinr += pow(10, 0.1*(phy_vars_ue->sinr_dB[f])); - } - - sinr = 10*log10(sinr/(6*12)); - - bler = pbch_bler(sinr); - - LOG_D(PHY,"EMUL UE rx_pbch_emul: eNB_id %d, pbch_phase %d, sinr %f dB, bler %f \n", - eNB_id, - pbch_phase, - sinr, - bler); - - if (pbch_phase == (frame_rx % 4)) { - if (uniformrandom() >= bler) { - memcpy(phy_vars_ue->pbch_vars[eNB_id]->decoded_output,RC.eNB[eNB_id][CC_id]->pbch_pdu,PBCH_PDU_SIZE); - return(RC.eNB[eNB_id][CC_id]->frame_parms.nb_antenna_ports_eNB); - } else - return(-1); - } else - return(-1); -} -#endif diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index dd96910549..2bd7140c32 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -38,10 +38,6 @@ #include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/defs.h" -#ifndef USER_MODE -#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" -#endif - #include "T.h" //#define DEBUG_PHICH 1 @@ -162,7 +158,7 @@ int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int sub pusch_frame = (frame); } - LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame); + //LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame); return pusch_frame % 1024; } diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 606900677e..a332670a59 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -39,6 +39,7 @@ #include "UTIL/LOG/vcd_signal_dumper.h" //#define PRACH_DEBUG 1 +//#define PRACH_WRITE_OUTPUT_DEBUG 1 uint16_t NCS_unrestricted[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; uint16_t NCS_restricted[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case @@ -341,7 +342,6 @@ uint16_t prach_root_sequence_map4[138] = { 1,138,2,137,3,136,4,135,5,134,6,133, 61,78,62,77,63,76,64,75,65,74,66,73,67,72,68,71,69,70 }; -#ifdef USER_MODE void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { @@ -362,7 +362,6 @@ void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) fclose(fd); } -#endif // This function computes the du void fill_du(uint8_t prach_fmt) @@ -562,7 +561,7 @@ int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra; t2_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t2_ra; #ifdef PRACH_DEBUG - LOG_D(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n", + LOG_I(PHY,"[PRACH] Checking for PRACH format (ConfigIndex %d) in TDD subframe %d (%d,%d,%d)\n", prach_ConfigIndex, subframe, t0_ra,t1_ra,t2_ra); @@ -655,7 +654,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 #else //normal case (simulation) prach_start = subframe*ue->frame_parms.samples_per_tti-ue->N_TA_offset; - LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, + LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, prach_start, ue->rx_offset, ue->hw_timing_advance, @@ -723,7 +722,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 } else { // This is the high-speed case #ifdef PRACH_DEBUG - LOG_D(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); + LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); #endif not_found = 1; @@ -784,7 +783,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 #ifdef PRACH_DEBUG if (NCS>0) - LOG_D(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, NCS %d (NCS_config %d, N_ZC/NCS %d) n_ra_prb %d: Preamble_offset %d, Preamble_shift %d\n", + LOG_I(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, NCS %d (NCS_config %d, N_ZC/NCS %d) n_ra_prb %d: Preamble_offset %d, Preamble_shift %d\n", rootSequenceIndex,preamble_index,NCS,Ncs_config,N_ZC/NCS,n_ra_prb, preamble_offset,preamble_shift); @@ -1039,14 +1038,14 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 break; } - //LOG_D(PHY,"prach_len=%d\n",prach_len); + //LOG_I(PHY,"prach_len=%d\n",prach_len); AssertFatal(prach_fmt<4, "prach_fmt4 not fully implemented" ); #if defined(EXMIMO) || defined(OAI_USRP) int j; int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*ue->frame_parms.samples_per_tti; - LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); + LOG_I( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); for (i=prach_start,j=0; iframe_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]<<4; @@ -1079,7 +1078,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 -#if 0 +#if defined(PRACH_WRITE_OUTPUT_DEBUG) write_output("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1); write_output("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1); write_output("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][0]),2*ue->frame_parms.samples_per_tti,1,1); @@ -1114,7 +1113,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint8_t restricted_set; uint8_t n_ra_prb; +#ifdef PRACH_DEBUG int frame; +#endif int subframe; int16_t *prachF=NULL; int16_t **rxsigF=NULL; @@ -1131,7 +1132,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t numshift=0; uint16_t *prach_root_sequence_map; uint8_t not_found; - int k; + int k=0; uint16_t u; int16_t *Xu; uint16_t offset; @@ -1152,8 +1153,6 @@ void rx_prach0(PHY_VARS_eNB *eNB, int en0=0; #endif - (void)frame; /* avoid gcc warnings */ - if (ru) { fp = &ru->frame_parms; nb_rx = ru->nb_rx; @@ -1204,7 +1203,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, #ifdef Rel14 if (br_flag == 1) { prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level]; +#ifdef PRACH_DEBUG frame = eNB->proc.frame_prach_br; +#endif subframe = eNB->proc.subframe_prach_br; prachF = eNB->prach_vars_br.prachF; rxsigF = eNB->prach_vars_br.rxsigF[ce_level]; @@ -1221,19 +1222,23 @@ void rx_prach0(PHY_VARS_eNB *eNB, #endif { prach_ifftp = eNB->prach_vars.prach_ifft[0]; +#ifdef PRACH_DEBUG frame = eNB->proc.frame_prach; +#endif subframe = eNB->proc.subframe_prach; prachF = eNB->prach_vars.prachF; rxsigF = eNB->prach_vars.rxsigF[0]; #ifdef PRACH_DEBUG - if ((frame&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); + //if ((frame&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); #endif } } else { #ifdef Rel14 if (br_flag == 1) { +#ifdef PRACH_DEBUG + frame = ru->proc.frame_prach_br; +#endif subframe = ru->proc.subframe_prach_br; rxsigF = ru->prach_rxsigF_br[ce_level]; #ifdef PRACH_DEBUG @@ -1244,6 +1249,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, else #endif { +#ifdef PRACH_DEBUG + frame = ru->proc.frame_prach; +#endif subframe = ru->proc.subframe_prach; rxsigF = ru->prach_rxsigF; #ifdef PRACH_DEBUG @@ -1258,9 +1266,32 @@ void rx_prach0(PHY_VARS_eNB *eNB, for (aa=0; aaif_south == LOCAL_RF) { // set the time-domain signal if we have to use it in this node + // DJP - indexing below in subframe zero takes us off the beginning of the array??? prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset]; #ifdef PRACH_DEBUG - if ((frame&1023) < 20) LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d, : prach %p (energy %d)\n",ru->idx,br_flag,ce_level,frame,subframe,prach[aa],dB_fixed(en0=signal_energy(prach[aa],fp->samples_per_tti))); + int32_t en0=signal_energy((int32_t*)prach[aa],fp->samples_per_tti); + int8_t dbEn0 = dB_fixed(en0); + int8_t rach_dBm = dbEn0 - eNB->rx_total_gain_dB; + +#ifdef PRACH_WRITE_OUTPUT_DEBUG + if (dbEn0>32 && prach[0]!= NULL) + { + static int counter=0; + + char buffer[80]; + //counter++; + sprintf(buffer, "%s%d", "/tmp/prach_rx",counter); + write_output(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13); + } +#endif + + if (dbEn0>32) + { +#ifdef PRACH_WRITE_OUTPUT_DEBUG + if (prach[0]!= NULL) write_output("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1); +#endif + LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d rach_dBm:%d rxdata:%p index:%d\n",ru->idx,br_flag,ce_level,frame,subframe,fp->samples_per_tti,prach[aa],dbEn0,ru->N_TA_offset,rach_dBm,ru->common.rxdata[aa], (subframe*fp->samples_per_tti)-ru->N_TA_offset); + } #endif } } @@ -1343,7 +1374,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, if (((eNB!=NULL) && (ru->function != NGFI_RAU_IF4p5))|| ((eNB==NULL) && (ru->function == NGFI_RRU_IF4p5))) { // compute the DFTs of the PRACH temporal resources // Do forward transform - LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d\n",fp->N_RB_UL); +#ifdef PRACH_DEBUG + LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d nb_rx:%d Ncp:%d\n",fp->N_RB_UL, nb_rx, Ncp); +#endif for (aa=0; aaofdm_symbol_size*24; - LOG_D(PHY,"Shifting prach_rxF from %d to 0\n",k); + //LOG_D(PHY,"Shifting prach_rxF from %d to 0\n",k); if ((k+(839*2)) > dftsize_x2) { // PRACH signal is split around DC memmove((void*)&rxsigF[aa][dftsize_x2-k],(void*)&rxsigF[aa][0],(k+(839*2)-dftsize_x2)*2); @@ -1478,7 +1511,6 @@ void rx_prach0(PHY_VARS_eNB *eNB, 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); #endif - } // in case of RAU and prach received rx_thread wakes up prach @@ -1623,7 +1655,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } memset(prachF, 0, sizeof(int16_t)*2*1024 ); -#ifdef PRACH_DEBUG +#if defined(PRACH_WRITE_OUTPUT_DEBUG) if (prach[0]!= NULL) write_output("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1); #endif // write_output("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1); @@ -1657,7 +1689,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, 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; } -#ifdef PRACH_DEBUG +#if defined(PRACH_WRITE_OUTPUT_DEBUG) if (aa==0) write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); #endif // if (aa=1) write_output("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1); @@ -1706,19 +1738,22 @@ void rx_prach0(PHY_VARS_eNB *eNB, k*=2; if (br_flag == 0) { - /* +#if defined(PRACH_WRITE_OUTPUT_DEBUG) write_output("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1); write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); write_output("Xu.m","xu",Xu,N_ZC,1,1); - write_output("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);*/ + write_output("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); +#endif } else { +#if defined(PRACH_WRITE_OUTPUT_DEBUG) printf("Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb); write_output("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1); write_output("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1); write_output("Xu_br.m","xu_br",Xu,N_ZC,1,1); write_output("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1); exit(-1); +#endif } } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 5b6d2da93d..be13e5938d 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1716,13 +1716,15 @@ int generate_ue_dlsch_params_from_dci(int frame, uint16_t tc_rnti); void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, + int frame, + int subframe, eNB_rxtx_proc_t *proc, DCI_ALLOC_t *dci_alloc, nfapi_dl_config_dci_dl_pdu *pdu); void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); -void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, +void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, nfapi_hi_dci0_dci_pdu *pdu); void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe); @@ -2149,9 +2151,13 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, +#ifdef Rel14 uint16_t Nf, uint8_t tdd_mapindex, - uint8_t br_flag); - + uint8_t br_flag +#else + uint16_t Nf, uint8_t tdd_mapindex +#endif + ); /*! \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index @param frame_parms Pointer to LTE_DL_FRAME_PARMS structure diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index c8da27bcb8..9a19b0ddaf 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -2455,9 +2455,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, *(1+payload) = (stat_im<0) ? 1 : 2; } else { // insufficient energy on PUCCH so NAK #if defined(USRP_REC_PLAY) - LOG_I(PHY,"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); + LOG_D(PHY,"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); #else - LOG_I(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); + LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); #endif *payload = 4; // DTX ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index f10b79ed65..9934b71d78 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -173,7 +173,9 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, &ulsch_harq->frame, &ulsch_harq->subframe); - LOG_I(PHY,"Programming msg3 reception in (%d,%d)\n",ulsch_harq->frame,ulsch_harq->subframe); + LOG_I(PHY,"Programming msg3 reception in (%d,%d) mcs:%d TBS:%d Qm:%d Mcs_intial:%d Nsymb_intial:%d round:%d\n", + ulsch_harq->frame,ulsch_harq->subframe, + mcs, ulsch_harq->TBS, ulsch_harq->Qm, ulsch_harq->Msc_initial, ulsch_harq->Nsymb_initial, ulsch_harq->round); use_srs = is_srs_occasion_common(frame_parms,ulsch_harq->frame,ulsch_harq->subframe); ulsch_harq->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch_harq->srs_active = use_srs; @@ -185,7 +187,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, LOG_D(PHY,"ulsch ra (eNB): harq_pid %d\n",harq_pid); LOG_D(PHY,"ulsch ra (eNB): round %d\n",ulsch_harq->round); LOG_D(PHY,"ulsch ra (eNB): TBS %d\n",ulsch_harq->TBS); - LOG_D(PHY,"ulsch ra (eNB): mcs %d\n",ulsch_harq->mcs); + LOG_D(PHY,"ulsch ra (eNB): mcs %d\n",ulsch_harq->Msc_initial); LOG_D(PHY,"ulsch ra (eNB): Or1 %d\n",ulsch_harq->Or1); LOG_D(PHY,"ulsch ra (eNB): ORI %d\n",ulsch_harq->O_RI); #endif diff --git a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c index a360b35ff6..c4c02e6312 100644 --- a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c @@ -180,7 +180,6 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } -#ifdef USER_MODE Msc_idx_ptr = (uint16_t*) bsearch((uint16_t*) &Msc_RS, (uint16_t*) dftsizes, 33, sizeof(uint16_t), compareints); if (Msc_idx_ptr) @@ -190,19 +189,6 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } -#else //stdlib not availiable in RTAI - - if (Msc_RS==216) - Msc_RS_idx = 12; - else if (Msc_RS==144) - Msc_RS_idx = 9; - else { - LOG_E(PHY,"generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); - return(-1); - } - -#endif - #ifdef DEBUG_SRS LOG_D(PHY,"generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d, k0 = %d\n",Msc_RS, Msc_RS_idx,k0); #endif @@ -279,7 +265,6 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } -#ifdef USER_MODE Msc_idx_ptr = (uint16_t*) bsearch((uint16_t*) &Msc_RS, (uint16_t*) dftsizes, 33, sizeof(uint16_t), compareints); if (Msc_idx_ptr) @@ -289,19 +274,6 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } -#else //stdlib not availiable in RTAI - - if (Msc_RS==216) - Msc_RS_idx = 12; - else if (Msc_RS==144) - Msc_RS_idx = 9; - else { - LOG_E(PHY,"generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); - return(-1); - } - -#endif - #ifdef DEBUG_SRS LOG_I(PHY,"generate_srs_rx: Msc_RS = %d, Msc_RS_idx = %d, k0=%d\n",Msc_RS, Msc_RS_idx,k0); #endif diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 71c36f7c3c..87209e190b 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -953,77 +953,3 @@ uint32_t ulsch_encoding(uint8_t *a, return(0); } - -#ifdef PHY_ABSTRACTION -#ifdef OPENAIR2 -#include "LAYER2/MAC/extern.h" -#include "LAYER2/MAC/defs.h" -#endif -int ulsch_encoding_emul(uint8_t *ulsch_buffer, - PHY_VARS_UE *ue, - uint8_t eNB_id, - uint8_t subframe_rx, - uint8_t harq_pid, - uint8_t control_only_flag) -{ - - LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id]; - PHY_MEASUREMENTS *meas = &ue->measurements; - uint8_t tmode = ue->transmission_mode[eNB_id]; - uint16_t rnti=ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti; - LOG_D(PHY,"EMUL UE ulsch_encoding for eNB %d,mod_id %d, harq_pid %d rnti %x, ACK(%d,%d) \n", - eNB_id,ue->Mod_id, harq_pid, rnti,ulsch->o_ACK[0],ulsch->o_ACK[1]); - - if (ulsch->O>0) { - /* - if(flag_LA==1) - sinr_eff = sinr_eff_cqi_calc(ue, eNB_id); - else - sinr_eff = meas->wideband_cqi_avg[eNB_id]; - */ - - fill_CQI(ulsch,meas,eNB_id,harq_pid,ue->frame_parms.N_RB_DL,rnti,tmode,ue->sinr_eff); - //LOG_D(PHY,"UE CQI\n"); - // print_CQI(ulsch->o,ulsch->uci_format,eNB_id); - - // save PUSCH pmi for later (transmission modes 4,5,6) - // printf("ulsch: saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi)); - // if (ulsch->uci_format != HLC_subband_cqi_mcs_CBA) - dlsch[0]->harq_processes[harq_pid]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi; - } - - memcpy(ue->ulsch[eNB_id]->harq_processes[harq_pid]->b, - ulsch_buffer, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3); - - - //memcpy(&UE_transport_info[ue->Mod_id].transport_blocks[UE_transport_info_TB_index[ue->Mod_id]], - memcpy(&UE_transport_info[ue->Mod_id][ue->CC_id].transport_blocks, - ulsch_buffer, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3); - //UE_transport_info_TB_index[ue->Mod_id]+=ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; - // navid: currently more than one eNB is not supported in the code - UE_transport_info[ue->Mod_id][ue->CC_id].num_eNB = 1; - UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][0]->crnti; - UE_transport_info[ue->Mod_id][ue->CC_id].eNB_id[0] = eNB_id; - UE_transport_info[ue->Mod_id][ue->CC_id].harq_pid[0] = harq_pid; - UE_transport_info[ue->Mod_id][ue->CC_id].tbs[0] = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3 ; - // printf("\nue->Mod_id%d\n",ue->Mod_id); - - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_flag = 1; - //UE_transport_info[ue->Mod_id].cntl.pusch_uci = *(uint32_t *)ulsch->o; - memcpy(UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_uci, - ulsch->o, - MAX_CQI_BYTES); - // printf("[UE]cqi is %d \n", ((HLC_subband_cqi_rank1_2A_5MHz *)ulsch->o)->cqi1); - - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.length_uci = ulsch->O; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.uci_format = ulsch->uci_format; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_ri = (ulsch->o_RI[0]&1)+((ulsch->o_RI[1]&1)<<1); - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pusch_ack = (ulsch->o_ACK[0]&1) + ((ulsch->o_ACK[1]&1)<<1); - //printf("ack is %d %d %d\n",UE_transport_info[ue->Mod_id].cntl.pusch_ack, (ulsch->o_ACK[1]&1)<<1, ulsch->o_ACK[0]&1); - return(0); - -} -#endif diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index a5f4666210..5d93178b7c 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -44,11 +44,6 @@ #include "PHY_INTERFACE/extern.h" #endif -#ifdef PHY_ABSTRACTION -#include "UTIL/OCG/OCG.h" -#include "UTIL/OCG/OCG_extern.h" -#endif - #include "UTIL/LOG/vcd_signal_dumper.h" //#define DEBUG_ULSCH_DECODING @@ -170,6 +165,7 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) //ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t)); if (ulsch) { ulsch->rnti = 0; + ulsch->harq_mask = 0; for (i=0; i<8; i++) { if (ulsch->harq_processes[i]) { @@ -891,12 +887,13 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, int16_t cseq[6*14*1200] __attribute__((aligned(32))); int off; + int frame = proc->frame_rx; int subframe = proc->subframe_rx; LTE_UL_eNB_HARQ_t *ulsch_harq; - harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); + harq_pid = subframe2harq_pid(frame_parms,frame,subframe); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1); @@ -921,7 +918,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, //#ifdef DEBUG_ULSCH_DECODING - LOG_D(PHY,"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\n", + 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", + harq_pid, proc->frame_rx,subframe, frame_parms->Nid_cell,ulsch->rnti,x2, A, @@ -930,7 +928,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, ulsch_harq->Or1, ulsch_harq->O_RI, ulsch_harq->O_ACK, - G); + G, + ulsch_harq->Qm, + ulsch_harq->Nsymb_pusch, + nb_rb); //#endif #ifndef UE_EXPANSION @@ -1279,7 +1280,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, } if (ulsch_harq->O_ACK > 2) { - LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n"); + LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet O_ACK:%d SFN/SF:%04d%d UE_id:%d rnti:%x\n",ulsch_harq->O_ACK,proc->frame_rx,proc->subframe_rx,UE_id,ulsch->rnti); return(-1); } @@ -1591,6 +1592,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, #endif } + 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 @@ -1600,461 +1602,3 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, return(ret); } - -#ifdef PHY_ABSTRACTION - -#ifdef PHY_ABSTRACTION_UL -int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb) -{ - - int index,ii; - double sinr_eff = 0; - int rb_count = 0; - int offset; - double bler = 0; - TM = TM-1; - sinr_eff = sinr_dB[frb]; //the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function - - - sinr_eff *= 10; - sinr_eff = floor(sinr_eff); - sinr_eff /= 10; - - LOG_D(PHY,"[ABSTRACTION] sinr_eff after rounding = %f\n",sinr_eff); - - for (index = 0; index < 16; index++) { - if(index == 0) { - if (sinr_eff < sinr_bler_map_up[mcs][0][index]) { - bler = 1; - break; - } - } - - if (sinr_eff == sinr_bler_map_up[mcs][0][index]) { - bler = sinr_bler_map_up[mcs][1][index]; - } - } - -#ifdef USER_MODE // need to be adapted for the emulation in the kernel space - - if (uniformrandom() < bler) { - LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(0); - } else { - LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(1); - } - -#endif -} - - - - - - - -int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb) -{ - int index; - double sinr_eff = 0; - double sinr_db1 = 0; - double sinr_db2 = 0; - double SI=0; - double RBIR=0; - int rb_count = 0; - int offset, M=0; - double bler = 0; - int start,middle,end; - TM = TM-1; - - for (offset = frb; offset <= (frb + nrb -1); offset++) { - - rb_count++; - - //we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB. - - sinr_db1 = sinr_dB[offset*2]; - sinr_db2 = sinr_dB[offset*2+1]; - - printf("sinr_db1=%f\n,sinr_db2=%f\n",sinr_db1,sinr_db2); - - //rounding up for the table lookup - sinr_db1 *= 10; - sinr_db2 *= 10; - - sinr_db1 = floor(sinr_db1); - sinr_db2 = floor(sinr_db2); - - if ((int)sinr_db1%2) { - sinr_db1 += 1; - } - - if ((int)sinr_db2%2) { - sinr_db2 += 1; - } - - sinr_db1 /= 10; - sinr_db2 /= 10; - - if(mcs<10) { - //for sinr_db1 - for (index = 0; index < 162; index++) { - if (sinr_db1 < MI_map_4qam[0][0]) { - SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - - if (sinr_db1 > MI_map_4qam[0][161]) { - SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - - if (sinr_db1 == MI_map_4qam[0][index]) { - SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - } - - //for sinr_db2 - for (index = 0; index < 162; index++) { - if (sinr_db2 < MI_map_4qam[0][0]) { - SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - - if (sinr_db2 > MI_map_4qam[0][161]) { - SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - - if (sinr_db2 == MI_map_4qam[0][index]) { - SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=2; - break; - } - } - - } else if(mcs>9 && mcs<17) { - //for sinr_db1 - for (index = 0; index < 197; index++) { - if (sinr_db1 < MI_map_16qam[0][0]) { - SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - - if (sinr_db1 > MI_map_16qam[0][196]) { - SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - - if (sinr_db1 == MI_map_16qam[0][index]) { - SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - } - - //for sinr_db2 - for (index = 0; index < 197; index++) { - if (sinr_db2 < MI_map_16qam[0][0]) { - SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - - if (sinr_db2 > MI_map_16qam[0][196]) { - SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - - if (sinr_db2 == MI_map_16qam[0][index]) { - SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=4; - break; - } - } - - } else if(mcs>16 && mcs<22) { - //for sinr_db1 - for (index = 0; index < 227; index++) { - if (sinr_db1 < MI_map_64qam[0][0]) { - SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - - if (sinr_db1 > MI_map_64qam[0][226]) { - SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - - if (sinr_db1 == MI_map_64qam[0][index]) { - SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - } - - //for sinr_db2 - for (index = 0; index < 227; index++) { - if (sinr_db2 < MI_map_64qam[0][0]) { - SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - - if (sinr_db2 > MI_map_64qam[0][226]) { - SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - - if (sinr_db2 == MI_map_64qam[0][index]) { - SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]); - M +=6; - break; - } - } - } - } - - // } - - RBIR = SI/M; - - //Now RBIR->SINR_effective Mapping - //binary search method is performed here - if(mcs<10) { - start = 0; - end = 161; - middle = end/2; - - if (RBIR <= MI_map_4qam[2][start]) { - sinr_eff = MI_map_4qam[0][start]; - } else { - if (RBIR >= MI_map_4qam[2][end]) - sinr_eff = MI_map_4qam[0][end]; - else { - //while((end-start > 1) && (RBIR >= MI_map_4qam[2])) - if (RBIR < MI_map_4qam[2][middle]) { - end = middle; - middle = end/2; - } else { - start = middle; - middle = (end-middle)/2; - } - } - - for (; end>start; end--) { - if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end-2])) { - sinr_eff = MI_map_4qam[0][end-1]; - break; - } - } - } - - sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; - } - - - - else if (mcs>9 && mcs<17) { - - start = 0; - end = 196; - middle = end/2; - - if (RBIR <= MI_map_16qam[2][start]) { - sinr_eff = MI_map_16qam[0][start]; - } else { - if (RBIR >= MI_map_16qam[2][end]) - sinr_eff = MI_map_16qam[0][end]; - else { - //while((end-start > 1) && (RBIR >= MI_map_4qam[2])) - if (RBIR < MI_map_16qam[2][middle]) { - end = middle; - middle = end/2; - } else { - start = middle; - middle = (end-middle)/2; - } - } - - for (; end>start; end--) { - if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end-2])) { - sinr_eff = MI_map_16qam[0][end-1]; - break; - } - } - } - - sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; - } else if (mcs>16) { - start = 0; - end = 226; - middle = end/2; - - if (RBIR <= MI_map_64qam[2][start]) { - sinr_eff = MI_map_64qam[0][start]; - } else { - if (RBIR >= MI_map_64qam[2][end]) - sinr_eff = MI_map_64qam[0][end]; - else { - //while((end-start > 1) && (RBIR >= MI_map_4qam[2])) - if (RBIR < MI_map_64qam[2][middle]) { - end = middle; - middle = end/2; - } else { - start = middle; - middle = (end-middle)/2; - } - } - - for (; end>start; end--) { - if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end-2])) { - sinr_eff = MI_map_64qam[0][end-1]; - break; - } - } - } - - sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; - } - - printf("SINR_Eff = %e\n",sinr_eff); - - sinr_eff *= 10; - sinr_eff = floor(sinr_eff); - // if ((int)sinr_eff%2) { - // sinr_eff += 1; - // } - sinr_eff /= 10; - printf("sinr_eff after rounding = %f\n",sinr_eff); - - for (index = 0; index < 16; index++) { - if(index == 0) { - if (sinr_eff < sinr_bler_map_up[mcs][0][index]) { - bler = 1; - break; - } - } - - if (sinr_eff == sinr_bler_map_up[mcs][0][index]) { - bler = sinr_bler_map_up[mcs][1][index]; - } - } - -#ifdef USER_MODE // need to be adapted for the emulation in the kernel space - - if (uniformrandom() < bler) { - printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(0); - } else { - printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); - return(1); - } - -#endif - -} - -#endif - -uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, - uint8_t UE_index, - uint16_t *crnti) -{ - - uint8_t UE_id; - uint16_t rnti; - int subframe = proc->subframe_rx; - uint8_t harq_pid; - uint8_t CC_id = eNB->CC_id; - - harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe); - - rnti = eNB->ulsch[UE_index]->rnti; -#ifdef DEBUG_PHY - LOG_D(PHY,"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x\n",eNB->Mod_id,subframe,UE_index,harq_pid,rnti); -#endif - - for (UE_id=0; UE_idpdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti) - break; - - } - - if (UE_id==NB_UE_INST) { - LOG_W(PHY,"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)\n", - eNB->Mod_id, rnti, UE_index); - return(1+eNB->ulsch[UE_id]->max_turbo_iterations); - } else { - LOG_D(PHY,"[eNB %d] Found UE with rnti %x => UE_id %d\n",eNB->Mod_id, rnti, UE_id); - } - - if (PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status == CBA_ACTIVE) { - *crnti = rnti; - PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status=IDLE; - } else - *crnti = 0x0; - - if (1) { - LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n"); - - memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->b, - PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->b, - eNB->ulsch[UE_index]->harq_processes[harq_pid]->TBS>>3); - - // get local ue's ack - if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) { - get_ack(&eNB->frame_parms, - PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack, - proc->subframe_tx, - proc->subframe_rx, - eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0); - } else { // get remote UEs' ack - eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0]; - eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1]; - } - - // Do abstraction of PUSCH feedback -#ifdef DEBUG_PHY - LOG_D(PHY,"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)\n", - eNB->Mod_id,UE_index, UE_id, subframe,eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0], - eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1], - ((HLC_subband_cqi_rank1_2A_5MHz *)PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o)->cqi1, - PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O); -#endif - - eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or1 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O; - eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or2 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O; - - eNB->ulsch[UE_index]->harq_processes[harq_pid]->uci_format = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->uci_format; - memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o,MAX_CQI_BYTES); - memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_RI,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_RI,2); - - eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 1; - - return(1); - } else { - LOG_W(PHY,"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d\n",eNB->Mod_id,UE_index); - - eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 0; - - // retransmission - return(1+eNB->ulsch[UE_index]->max_turbo_iterations); - } - -} -#endif - diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 795ed5896b..93c1af8d91 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1360,7 +1360,6 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); - //#ifndef OAI_EMU write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0); if (eNB->common_vars.rxdata) write_output("/tmp/rxsig0.m","rxs0", &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index f2e43a533e..80efc70c40 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -23,11 +23,7 @@ #include "PHY/extern.h" #include "extern.h" #include "kHz_7_5.h" -#ifdef USER_MODE #include -#else -#include "rtai_math.h" -#endif #include "PHY/sse_intrin.h" short conjugate75[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; diff --git a/openair1/PHY/TOOLS/Makefile b/openair1/PHY/TOOLS/Makefile index eee9d78344..59b6a1e03b 100644 --- a/openair1/PHY/TOOLS/Makefile +++ b/openair1/PHY/TOOLS/Makefile @@ -1,14 +1,14 @@ lte_dfts_sse4: lte_dfts.c - gcc -O2 -msse4.1 -g -ggdb -o lte_dfts_sse4 lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS + gcc -O2 -msse4.1 -g -ggdb -o lte_dfts_sse4 lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS lte_dfts_avx2: lte_dfts.c - gcc -O2 -mavx2 -g -ggdb -o lte_dfts_avx2 lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS + gcc -O2 -mavx2 -g -ggdb -o lte_dfts_avx2 lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS lte_dfts_avx2.s: lte_dfts.c - gcc -O2 -mavx2 -S lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS + gcc -O2 -mavx2 -S lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS lte_dfts_sse4.s: lte_dfts.c - gcc -O2 -msse4.1 -S lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS + gcc -O2 -msse4.1 -S lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS dft_cycles_avx2: lte_dfts_avx2 ./lte_dfts_avx2 | egrep cycles diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index b5b551f008..13facf6907 100644 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -20,10 +20,7 @@ */ #include "defs.h" -//#include "MAC_INTERFACE/extern.h" -#ifdef USER_MODE #include -#endif #if defined(__x86_64__) || defined(__i386__) int16_t conjug[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; @@ -267,4 +264,4 @@ int multadd_cpx_vector(int16_t *x1, _mm_empty(); _m_empty(); return(0); -} \ No newline at end of file +} diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h index 41d7c9528a..b92c2a4236 100644 --- a/openair1/PHY/TOOLS/defs.h +++ b/openair1/PHY/TOOLS/defs.h @@ -34,13 +34,10 @@ #include "PHY/sse_intrin.h" -//defined in rtai_math.h -#ifndef _RTAI_MATH_H struct complex { double x; double y; }; -#endif struct complexf { float r; @@ -286,7 +283,6 @@ void bit8_txmux(int32_t length,int32_t offset); void bit8_rxdemux(int32_t length,int32_t offset); -#ifdef USER_MODE /*!\fn int32_t write_output(const char *fname, const char *vname, void *data, int length, int dec, char format); \brief Write output file from signal data @param fname output file name @@ -297,7 +293,6 @@ void bit8_rxdemux(int32_t length,int32_t offset); @param format data format (0 = real 16-bit, 1 = complex 16-bit,2 real 32-bit, 3 complex 32-bit,4 = real 8-bit, 5 = complex 8-bit) */ int32_t write_output(const char *fname, const char *vname, void *data, int length, int dec, char format); -#endif void Zero_Buffer(void *,uint32_t); void Zero_Buffer_nommx(void *buf,uint32_t length); @@ -361,17 +356,6 @@ int16_t dB_fixed_times10(uint32_t x); int32_t phy_phase_compensation_top (uint32_t pilot_type, uint32_t initial_pilot, uint32_t last_pilot, int32_t ignore_prefix); -/*!\fn void phy_phase_compensation (int16_t *ref_sch, int16_t *tgt_sch, int16_t *out_sym, int32_t ignore_prefix, int32_t aa, struct complex16 *perror_out); -This function is used by the EMOS to compensate the phase rotation of the RF. It has been designed for symbols of type CHSCH or SCH, but cannot be used for the data channels. -@param ref_sch reference symbol -@param tgt_sch target symbol -@param out_sym output of the operation -@param ignore_prefix set to 1 if cyclic prefix has not been removed (by the hardware) -@param aa antenna index -@param perror_out phase error (output parameter) -*/ -void phy_phase_compensation (int16_t *ref_sch, int16_t *tgt_sch, int16_t *out_sym, int32_t ignore_prefix, int32_t aa, struct complex16 *perror_out ); - int32_t dot_product(int16_t *x, int16_t *y, uint32_t N, //must be a multiple of 8 diff --git a/openair1/PHY/TOOLS/file_output.c b/openair1/PHY/TOOLS/file_output.c index 1a4adb04cd..1e0b31a47f 100644 --- a/openair1/PHY/TOOLS/file_output.c +++ b/openair1/PHY/TOOLS/file_output.c @@ -19,8 +19,6 @@ * contact@openairinterface.org */ -#ifdef USER_MODE - #include #include #include @@ -180,5 +178,3 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d return 0; } - -#endif // USER_MODE diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index dc4708ce6c..e0e171f6bf 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -19,11 +19,9 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include #include #include -#endif #include diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index c3a8a84169..3a5b920aa7 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -153,7 +153,9 @@ typedef struct { /// prach_Config_enabled=1 means enabled. \vr{[0..1]} uint8_t prach_Config_enabled; /// PRACH Configuration Information +#ifdef Rel14 PRACH_eMTC_CONFIG_INFO prach_ConfigInfo; +#endif } PRACH_eMTC_CONFIG_COMMON; /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. @@ -819,7 +821,7 @@ typedef struct { uint8_t narrowband; /// number of PRB pairs for MPDCCH uint8_t number_of_prb_pairs; - /// mpdcch resource assignement (combinatorial index r) + /// mpdcch resource assignment (combinatorial index r) uint8_t resource_block_assignment; /// transmission type (0=localized,1=distributed) uint8_t transmission_type; diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 6fe6b46a38..60d3fec5f4 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -125,10 +125,6 @@ #define FIRST_CARRIER_OFFSET (HALF_NUMBER_OF_USEFUL_CARRIERS+NUMBER_OF_ZERO_CARRIERS) #define NUMBER_OF_OFDM_SYMBOLS_PER_SLOT (NUMBER_OF_SYMBOLS_PER_FRAME/LTE_SLOTS_PER_FRAME) -#ifdef EMOS -#define EMOS_SCH_INDEX 1 -#endif //EMOS - #define EXTENSION_TYPE (PHY_config->PHY_framing.Extension_type) #define NUMBER_OF_OFDM_CARRIERS_BYTES NUMBER_OF_OFDM_CARRIERS*4 diff --git a/openair1/PHY/types.h b/openair1/PHY/types.h index be8ec7115a..c0a9af388c 100644 --- a/openair1/PHY/types.h +++ b/openair1/PHY/types.h @@ -22,11 +22,7 @@ #ifndef __openair_TYPES_H__ #define __openair_TYPES_H__ -#ifdef USER_MODE #include -#else -#include -#endif #endif /*__openair_TYPES_H__ */ diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 93e48ca92c..e6ffd33a02 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -208,11 +208,12 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,re @param phy_vars_eNB Pointer to eNB variables on which to act @param br_flag indicator for eMTC PRACH */ -void prach_procedures(PHY_VARS_eNB *eNB, #ifdef Rel14 - int br_flag +void prach_procedures(PHY_VARS_eNB *eNB, + int br_flag); +#else +void prach_procedures(PHY_VARS_eNB *eNB); #endif - ); /*! \brief Function to compute subframe Number(DL and S) as a function of Frame type and TDD Configuration @param frame_parms Pointer to DL frame parameter descriptor diff --git a/openair1/SCHED/extern.h b/openair1/SCHED/extern.h index 80a815dda7..b1e8df67ef 100644 --- a/openair1/SCHED/extern.h +++ b/openair1/SCHED/extern.h @@ -24,40 +24,6 @@ #ifndef __SCHED_EXTERN_H__ #define __SCHED_EXTERN_H__ -#ifndef USER_MODE -#define __NO_VERSION__ - - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - - - -#ifdef RTAI_ENABLED -#include -//#include -#include -#include -#include -//#include "rt_compat.h" - -#else -#include -#endif - -#endif /* USER_MODE */ - #include "defs.h" //#include "dlc_engine.h" @@ -71,11 +37,5 @@ extern int synch_wait_cnt; extern int16_t hundred_times_delta_TF[100]; extern uint16_t hundred_times_log10_NPRB[100]; -/* -#ifdef EMOS -extern fifo_dump_emos_UE emos_dump_UE; -extern fifo_dump_emos_eNB emos_dump_eNB; -#endif -*/ #endif /*__SCHED_EXTERN_H__ */ diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index dbce91776d..d4f4bec4b3 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -37,20 +37,32 @@ #include "nfapi_interface.h" #include "fapi_l1.h" +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req); +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); + +extern uint8_t nfapi_mode; + + void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, + int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) { - int idx = proc->subframe_tx&1; + int idx = subframe&1; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx]; nfapi_dl_config_dci_dl_pdu *pdu = &dl_config_pdu->dci_dl_pdu; - LOG_D(PHY,"Frame %d, Subframe %d: DCI processing\n",proc->frame_tx,proc->subframe_tx); + LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); // copy dci configuration into eNB structure - fill_dci_and_dlsch(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu); + fill_dci_and_dlsch(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu); + + LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); } +#ifdef Rel14 void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) @@ -64,27 +76,32 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, // copy dci configuration into eNB structure fill_mdci_and_dlsch(eNB,proc,&mpdcch_vars->mdci_alloc[mpdcch_vars->num_dci],pdu); } +#endif -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { - int idx = proc->subframe_tx&1; + int idx = subframe&1; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx]; + + //LOG_D(PHY,"%s() SFN/SF:%04d%d Before num_dci:%d\n", __FUNCTION__,frame,subframe,pdcch_vars->num_dci); + // copy dci configuration in to eNB structure - fill_dci0(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu); + fill_dci0(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu); } -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { - LTE_eNB_PHICH *phich = &eNB->phich_vars[proc->subframe_tx&1]; + LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1]; // copy dci configuration in to eNB structure - LOG_D(PHY,"Received HI PDU which value %d (rbstart %d,cshift %d)\n", + LOG_D(PHY,"Received HI PDU with value %d (rbstart %d,cshift %d)\n", hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms); + // DJP - TODO FIXME - transmission power ignored phich->config[phich->num_hi].hi = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value; phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start; phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms; @@ -100,7 +117,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, AssertFatal(rel8->length == 3, "BCH PDU has length %d != 3\n",rel8->length); - LOG_D(PHY,"bch_pdu: %x,%x,%x\n",sdu[0],sdu[1],sdu[2]); + //LOG_D(PHY,"bch_pdu: %x,%x,%x\n",sdu[0],sdu[1],sdu[2]); eNB->pbch_pdu[0] = sdu[2]; eNB->pbch_pdu[1] = sdu[1]; eNB->pbch_pdu[2] = sdu[0]; @@ -119,7 +136,7 @@ extern uint32_t localRIV2alloc_LUT100_2[6000]; extern uint32_t localRIV2alloc_LUT100_3[6000]; #endif -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu) @@ -144,11 +161,25 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, dlsch1 = eNB->dlsch[UE_id][1]; #ifdef Rel14 - if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[proc->subframe_tx] = 0; + if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[subframe] = 0; #endif - harq_pid = dlsch0->harq_ids[proc->subframe_tx]; - AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7\n",harq_pid); + harq_pid = dlsch0->harq_ids[subframe]; + AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7 frame:%d subframe:%d subframe(TX):%d rnti:%x UE_id:%d dlsch0[harq_ids:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d]\n", + harq_pid, + frame,subframe, + proc->subframe_tx,rel8->rnti,UE_id, + dlsch0->harq_ids[0], + dlsch0->harq_ids[1], + dlsch0->harq_ids[2], + dlsch0->harq_ids[3], + dlsch0->harq_ids[4], + dlsch0->harq_ids[5], + dlsch0->harq_ids[6], + dlsch0->harq_ids[7], + dlsch0->harq_ids[8], + dlsch0->harq_ids[9] + ); dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n"); @@ -173,20 +204,21 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); } - dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols; + dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols; if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU - AssertFatal(sdu!=NULL,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d\n", + AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", + frame,subframe, proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index); - if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); + if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", + frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); if (codeword_index == 0) dlsch0_harq->pdu = sdu; else dlsch1_harq->pdu = sdu; } else { - if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, + if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n", + frame,subframe,proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, rel8->rnti,UE_id,harq_pid); } @@ -202,12 +234,6 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, dlsch0->Kmimo = 1; dlsch0->Mdlharq = 4; dlsch0->Nsoft = 25344; -#ifdef UE_EXPANSION - dlsch0_harq->i0 = rel13->initial_transmission_sf_io; -#else - dlsch0->i0 = rel13->initial_transmission_sf_io; -#endif - dlsch0_harq->pdsch_start = rel10->pdsch_start; #ifdef UE_EXPANSION if (rel13->pdsch_payload_type == 0) dlsch0_harq->sib1_br_flag=1; @@ -257,6 +283,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, dlsch0_harq->TBS = rel8->length<<3; dlsch0_harq->Qm = rel8->modulation; dlsch0_harq->codeword = 0; + dlsch0_harq->pdsch_start = rel10->pdsch_start; } else { #ifdef UE_EXPANSION @@ -266,6 +293,21 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, #endif } #endif +#ifdef UE_EXPANSION + dlsch0_harq->i0 = rel13->initial_transmission_sf_io; +#else + dlsch0->i0 = rel13->initial_transmission_sf_io; +#endif + + LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", +#ifdef UE_EXPANSION + dlsch0_harq->i0, +#else + dlsch0->i0, +#endif + dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], + rel8->length + ); } uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; @@ -524,8 +566,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); - LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", - UE_id,rel8->rnti,frame,subframe); + //LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", UE_id,rel8->rnti,frame,subframe); fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_pdu,frame,subframe); @@ -617,8 +658,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); - AssertFatal(proc->frame_tx == frame, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); + // DJP - subframe assert will fail - not sure why yet + // DJP - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); + // DJP - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); + + uint8_t number_pdcch_ofdm_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; uint8_t number_hi_dci0_pdu = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi; @@ -630,15 +674,21 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) int i; - eNB->pdcch_vars[subframe&1].num_pdcch_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols; + eNB->pdcch_vars[subframe&1].num_pdcch_symbols = number_pdcch_ofdm_symbols; eNB->pdcch_vars[subframe&1].num_dci = 0; eNB->phich_vars[subframe&1].num_hi = 0; + LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d hi_dci0:SFN/SF:%04d%d:pdus:%d ul_cfg:SFN/SF:%04d%d:pdus:%d num_pdcch_symbols:%d\n", + frame,subframe, + NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu, + NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus, + NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),number_hi_dci0_pdu, + NFAPI_SFNSF2SFN(UL_req->sfn_sf),NFAPI_SFNSF2SF(UL_req->sfn_sf),number_ul_pdu, + eNB->pdcch_vars[subframe&1].num_pdcch_symbols); - LOG_D(PHY,"NFAPI: Frame %d, Subframe %d (ul_subframe %d): received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n", - frame,subframe,ul_subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu); - - + int do_oai =0; + int dont_send =0; + if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL\n"); harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); @@ -655,11 +705,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) } for (i=0;idl_config_request_body.dl_config_pdu_list[i]; - LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); + //LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); switch (dl_config_pdu->pdu_type) { case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - handle_nfapi_dci_dl_pdu(eNB,proc,dl_config_pdu); - eNB->pdcch_vars[subframe&1].num_dci++; + handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); + eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++; + //LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci); + do_oai=1; break; case NFAPI_DL_CONFIG_BCH_PDU_TYPE: AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_indextx_request_body.number_of_pdus, @@ -667,6 +719,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index, TX_req->tx_request_body.number_of_pdus); eNB->pbch_configured=1; + do_oai=1; + //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", + //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); + + handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); break; @@ -674,22 +731,48 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) // handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu); break; case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + nfapi_dl_config_dlsch_pdu_rel8_t *dlsch_pdu_rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; + uint16_t pdu_index = dlsch_pdu_rel8->pdu_index; + uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus; + uint16_t invalid_pdu = pdu_index == -1; + uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data; + + LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n", + __FUNCTION__, i, + NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf), + proc->frame_tx, proc->subframe_tx, + proc->frame_rx, proc->subframe_rx, + dlsch_pdu_rel8->transport_blocks, pdu_index, sdu); + /* AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_indextx_request_body.number_of_pdus, "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index, TX_req->tx_request_body.number_of_pdus); */ - AssertFatal((dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks<3) && - (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks>0), - "dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = %d not in [1,2]\n", - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks); - handle_nfapi_dlsch_pdu(eNB,proc,dl_config_pdu, - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks-1, - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index == -1 ? NULL - : TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data); + AssertFatal((dlsch_pdu_rel8->transport_blocks<3) && + (dlsch_pdu_rel8->transport_blocks>0), + "dlsch_pdu_rel8->transport_blocks = %d not in [1,2]\n", + dlsch_pdu_rel8->transport_blocks); + if (1)//sdu != NULL) + { + handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); + } + else + { + dont_send=1; + + LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus); + } + + // Send the data first so that the DL_CONFIG can just pluck it out of the buffer + // DJP - OAI was here - moved to bottom + do_oai=1; + /* if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu + LOG_D(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe); generate_eNB_ulsch_params_from_rar(eNB, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, @@ -697,6 +780,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) subframe); } */ + } break; case NFAPI_DL_CONFIG_PCH_PDU_TYPE: // handle_nfapi_pch_pdu(eNB,dl_config_pdu); @@ -710,12 +794,26 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: // handle_nfapi_epdcch_pdu(eNB,dl_config_pdu); break; +#ifdef Rel14 case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); eNB->mpdcch_vars[subframe&1].num_dci++; break; +#endif } } + + if (nfapi_mode && do_oai && !dont_send) { + oai_nfapi_tx_req(Sched_INFO->TX_req); + + oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu + } + + if (nfapi_mode && number_hi_dci0_pdu!=0) { + oai_nfapi_hi_dci0_req(HI_DCI0_req); + eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci=0; + eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0; + } for (i=0;ipdu_type) { + case NFAPI_HI_DCI0_DCI_PDU_TYPE: - case NFAPI_HI_DCI0_DCI_PDU_TYPE: - handle_nfapi_hi_dci0_dci_pdu(eNB,proc,hi_dci0_req_pdu); - eNB->pdcch_vars[subframe&1].num_dci++; - break; + handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); - case NFAPI_HI_DCI0_HI_PDU_TYPE: - handle_nfapi_hi_dci0_hi_pdu(eNB,proc,hi_dci0_req_pdu); + eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++; + break; - break; + case NFAPI_HI_DCI0_HI_PDU_TYPE: + handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); + break; } } - for (i=0;iul_config_request_body.ul_config_pdu_list[i]; - LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); - AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - , - "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); - handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present); + if (nfapi_mode) { + if (number_ul_pdu>0) + { + //LOG_D(PHY, "UL_CONFIG to send to PNF\n"); + oai_nfapi_ul_config_req(UL_req); + UL_req->ul_config_request_body.number_of_pdus=0; + number_ul_pdu=0; + } + } + else { + for (i=0;iul_config_request_body.ul_config_pdu_list[i]; + LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); + AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + , + "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); + handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present); + } } } diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 3f4267c7f2..725bb31c45 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -42,13 +42,13 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe void fill_sr_indication(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,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); +void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c index 15c6fa7557..664791f7c4 100644 --- a/openair1/SCHED/phy_mac_stub.c +++ b/openair1/SCHED/phy_mac_stub.c @@ -36,10 +36,6 @@ #include "SCHED/extern.h" #include "LAYER2/MAC/extern.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif - /* SYRTEM */ uint8_t dci_ndi_toggle_even[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t dci_ndi_toggle_odd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -733,181 +729,3 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } */ } - -void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB) -{ - - //uint8_t cooperation_flag = eNB->cooperation_flag; - uint8_t transmission_mode = eNB->transmission_mode[0]; - - //uint32_t rballoc = 0x00F0; - //uint32_t rballoc2 = 0x000F; - /* - uint32_t rand = taus(); - if ((subframe==8) || (subframe==9) || (subframe==0)) - rand = (rand%5)+5; - else - rand = (rand%4)+5; - */ - - DCI_pdu->Num_dci = 0; - - switch (subframe) { - case 5: - DCI_pdu->Num_dci = 1; - - if (transmission_mode<3) { - //user 1 - DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t; - DCI_pdu->dci_alloc[0].L = 2; - DCI_pdu->dci_alloc[0].rnti = 0x1235; - DCI_pdu->dci_alloc[0].format = format1; - DCI_pdu->dci_alloc[0].ra_flag = 0; - DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE; - - DLSCH_alloc_pdu.rballoc = eNB->ue_dl_rb_alloc; - DLSCH_alloc_pdu.TPC = 0; - DLSCH_alloc_pdu.dai = 0; - DLSCH_alloc_pdu.harq_pid = 1; - DLSCH_alloc_pdu.mcs = eNB->target_ue_dl_mcs; - DLSCH_alloc_pdu.ndi = 1; - DLSCH_alloc_pdu.rv = 0; - memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t)); - - /* - //user2 - DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t; - DCI_pdu->dci_alloc[1].L = 2; - DCI_pdu->dci_alloc[1].rnti = 0x1236; - DCI_pdu->dci_alloc[1].format = format1; - DCI_pdu->dci_alloc[1].ra_flag = 0; - DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE; - - DLSCH_alloc_pdu.rballoc = rballoc2; - DLSCH_alloc_pdu.TPC = 0; - DLSCH_alloc_pdu.dai = 0; - DLSCH_alloc_pdu.harq_pid = 1; - DLSCH_alloc_pdu.mcs = eNB->target_ue_dl_mcs; - DLSCH_alloc_pdu.ndi = 1; - DLSCH_alloc_pdu.rv = 0; - memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t)); - */ - } else if (transmission_mode==5) { - DCI_pdu->Num_dci = 2; - // user 1 - DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - DCI_pdu->dci_alloc[0].L = 2; - DCI_pdu->dci_alloc[0].rnti = 0x1235; - DCI_pdu->dci_alloc[0].format = format1E_2A_M10PRB; - DCI_pdu->dci_alloc[0].ra_flag = 0; - DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE; - - DLSCH_alloc_pdu1E.tpmi = 5; //5=use feedback - DLSCH_alloc_pdu1E.rv = 0; - DLSCH_alloc_pdu1E.ndi = 1; - DLSCH_alloc_pdu1E.mcs = eNB->target_ue_dl_mcs; - DLSCH_alloc_pdu1E.harq_pid = 1; - DLSCH_alloc_pdu1E.dai = 0; - DLSCH_alloc_pdu1E.TPC = 0; - DLSCH_alloc_pdu1E.rballoc = eNB->ue_dl_rb_alloc; - DLSCH_alloc_pdu1E.rah = 0; - DLSCH_alloc_pdu1E.dl_power_off = 0; //0=second user present - memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - - //user 2 - DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - DCI_pdu->dci_alloc[1].L = 2; - DCI_pdu->dci_alloc[1].rnti = 0x1236; - DCI_pdu->dci_alloc[1].format = format1E_2A_M10PRB; - DCI_pdu->dci_alloc[1].ra_flag = 0; - DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE; - - memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - - // set the precoder of the second UE orthogonal to the first - eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); - } - - break; - - case 7: - DCI_pdu->Num_dci = 1; - DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - DCI_pdu->dci_alloc[0].L = 2; - DCI_pdu->dci_alloc[0].rnti = 0xbeef; - DCI_pdu->dci_alloc[0].format = format1A; - DCI_pdu->dci_alloc[0].ra_flag = 1; - DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE; - - RA_alloc_pdu.type = 1; - RA_alloc_pdu.vrb_type = 0; - RA_alloc_pdu.rballoc = computeRIV(25,12,3); - RA_alloc_pdu.ndi = 1; - RA_alloc_pdu.rv = 1; - RA_alloc_pdu.mcs = 4; - RA_alloc_pdu.harq_pid = 0; - RA_alloc_pdu.TPC = 1; - - memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); - break; - - case 9: - DCI_pdu->Num_dci = 1; - - //user 1 - DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; - DCI_pdu->dci_alloc[0].L = 2; - DCI_pdu->dci_alloc[0].rnti = 0x1235; - DCI_pdu->dci_alloc[0].format = format0; - DCI_pdu->dci_alloc[0].ra_flag = 0; - DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE; - - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - UL_alloc_pdu.rballoc = computeRIV(25,0,eNB->ue_ul_nb_rb); - UL_alloc_pdu.mcs = eNB->target_ue_ul_mcs; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - UL_alloc_pdu.cshift = 0; - UL_alloc_pdu.dai = 0; - UL_alloc_pdu.cqi_req = 1; - memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); - - /* - //user 2 - DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; - DCI_pdu->dci_alloc[1].L = 2; - DCI_pdu->dci_alloc[1].rnti = 0x1236; - DCI_pdu->dci_alloc[1].format = format0; - DCI_pdu->dci_alloc[1].ra_flag = 0; - - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - if (cooperation_flag==0) - UL_alloc_pdu.rballoc = computeRIV(25,2+eNB->ue_ul_nb_rb,eNB->ue_ul_nb_rb); - else - UL_alloc_pdu.rballoc = computeRIV(25,0,eNB->ue_ul_nb_rb); - UL_alloc_pdu.mcs = eNB->target_ue_ul_mcs; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - if ((cooperation_flag==0) || (cooperation_flag==1)) - UL_alloc_pdu.cshift = 0; - else - UL_alloc_pdu.cshift = 1; - UL_alloc_pdu.dai = 0; - UL_alloc_pdu.cqi_req = 1; - memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); - */ - break; - - default: - break; - } - /* - DCI_pdu->nCCE = 0; - - for (i=0; iNum_dci; i++) { - DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L)); - } - */ -} diff --git a/openair1/SCHED/phy_procedures_emos.h b/openair1/SCHED/phy_procedures_emos.h deleted file mode 100644 index 266a95b3c9..0000000000 --- a/openair1/SCHED/phy_procedures_emos.h +++ /dev/null @@ -1,108 +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 __PHY_PROCEDURES_EMOS_H__ -#define __PHY_PROCEDURES_EMOS_H__ - -/* -#ifndef RTAI -typedef uint64_t RTIME; -#else -*/ -#ifdef RTAI -#include -#include -#endif - -//#include "PHY/TOOLS/defs.h" -#include "PHY/defs.h" -#define CHANSOUNDER_FIFO_SIZE 10485760 // 10 Mbytes FIFO -//#define CHANSOUNDER_FIFO_SIZE 20971520 // 20 Mbytes FIFO -#define CHANSOUNDER_FIFO_MINOR 4 // minor of the FIFO device - this is /dev/rtf3 -#define CHANSOUNDER_FIFO_DEV "/dev/rtf4" - -#define NUMBER_OF_OFDM_CARRIERS_EMOS 512 // the number of OFDM carriers used for channel sounding -#define NUMBER_OF_USEFUL_CARRIERS_EMOS 300 // the number of OFDM carriers that contain data - -#define N_RB_UL_EMOS 25 -#define N_PILOTS_DL_EMOS 2 // ofdm symbols with pilots per slot -#define N_PILOTS_UL_EMOS 2 // ofdm symbols with pilots per subframe -#define N_SLOTS_DL_EMOS 2 // we take slots 14,15 -#define N_SUBFRAMES_UL_EMOS 1 // we take subframes 4 -#define NB_ANTENNAS_TX_EMOS 2 -#define NB_ANTENNAS_RX_EMOS 2 - -struct fifo_dump_emos_struct_UE { - // RX - uint64_t timestamp; //! Timestamp of the receiver - unsigned int frame_tx; //! Framenumber of the TX (encoded in the BCH) - unsigned int frame_rx; //! Framenumber of the RX - UE_MODE_t UE_mode; - PHY_MEASUREMENTS PHY_measurements; //! Structure holding all PHY measurements (one for every slot) - unsigned int pbch_errors; /// Total number of errors on PBCH - unsigned int pbch_errors_last; /// Total number of errors on PBCH 100 frames ago - unsigned int pbch_errors_conseq; /// Total number of consecutive errors on PBCH - unsigned int pbch_fer; /// PBCH FER (in percent) - unsigned int dlsch_errors; /// Total number of error on the DLSCH (data) - unsigned int dlsch_errors_last; - unsigned int dlsch_received; - unsigned int dlsch_received_last; - unsigned int dlsch_fer; - unsigned int dlsch_cntl_errors; /// Total number of error on the DLSCH (control) - unsigned int dlsch_ra_errors; /// Total number of error on the DLSCH (random access) - unsigned int total_TBS; - unsigned int total_TBS_last; - unsigned int bitrate; - unsigned int total_received_bits; - int timing_offset; /// Timing offset - int timing_advance; /// Timing advance - int freq_offset; /// Frequency offset - int use_ia_receiver; - unsigned short pmi_saved; - unsigned short mcs; - unsigned int rx_total_gain_dB; /// Total gain - unsigned char eNb_id; /// eNb_id UE is synched to - unsigned char mimo_mode; /// Transmission mode -#ifdef EMOS_CHANNEL - int channel[NB_ANTENNAS_RX_EMOS][NB_ANTENNAS_TX_EMOS][NUMBER_OF_OFDM_CARRIERS_EMOS*N_PILOTS_DL_EMOS*N_SLOTS_DL_EMOS]; -#endif -}; - -typedef struct fifo_dump_emos_struct_UE fifo_dump_emos_UE; - - -struct fifo_dump_emos_struct_eNB { - // TX - uint64_t timestamp; //! Timestamp of the receiver - unsigned int frame_tx; //! Framenumber of the TX - unsigned char mimo_mode; /// Transmission mode - // RX - PHY_MEASUREMENTS_eNB PHY_measurements_eNB; /// UL measurements - LTE_eNB_UE_stats eNB_UE_stats[NUMBER_OF_UE_MAX]; /// Contains received feedback - unsigned int rx_total_gain_dB; /// Total gain -#ifdef EMOS_CHANNEL - int channel[NB_ANTENNAS_RX_EMOS][N_RB_UL_EMOS*12*N_PILOTS_UL_EMOS*N_SUBFRAMES_UL_EMOS]; ///UL channel estimate -#endif -}; - -typedef struct fifo_dump_emos_struct_eNB fifo_dump_emos_eNB; - -#endif diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 81146289de..bbb6986ce9 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -938,7 +938,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf if(frame_parms->soundingrs_ul_config_common.enabled_flag) { - LOG_D(PHY," SRS SUBFRAMECONFIG: %d\n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig); + //LOG_D(PHY," SRS SUBFRAMECONFIG: %d\n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig); uint8_t TSFC; uint16_t deltaTSFC; // bitmap @@ -971,7 +971,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf } LOG_D(PHY," ISTDD: %d, TSFC: %d, deltaTSFC: %d, AbsSubframeTX: %d.%d\n", frame_parms->frame_type, TSFC, deltaTSFC, frame_tx, subframe_tx); } - LOG_D(PHY," isSubframeSRS %d\n", isSubframeSRS); + //LOG_D(PHY," isSubframeSRS %d\n", isSubframeSRS); return(isSubframeSRS); } diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 8500cd8b9b..d53ddf7c96 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -50,6 +50,8 @@ # include "intertask_interface.h" #endif +extern uint8_t nfapi_mode; +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); @@ -137,15 +139,13 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel #endif } -void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { +void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int **txdataF = eNB->common_vars.txdataF; uint8_t *pbch_pdu=&eNB->pbch_pdu[0]; - int subframe = proc->subframe_tx; - int frame = proc->frame_tx; - LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe); + //LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d fdd:%s dir:%s\n",frame,subframe,fp->frame_type == FDD?"FDD":"TDD", subframe_select(fp,subframe) == SF_DL?"DL":"UL?"); // generate Cell-Specific Reference Signals for both slots VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1); @@ -196,7 +196,8 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { /// generate PBCH if ((frame&3)==0) { - AssertFatal(eNB->pbch_configured==1,"PBCH was not configured by MAC\n"); + //AssertFatal(eNB->pbch_configured==1,"PBCH was not configured by MAC\n"); + if (eNB->pbch_configured!=1) return; eNB->pbch_configured=0; } generate_pbch(&eNB->pbch, @@ -272,7 +273,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, if (dlsch->rnti == 0x02) {//frame < 200) { - LOG_I(PHY, + LOG_D(PHY, "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", pdsch_start %d, G %d, nb_rb %"PRIu16", rb0 %x, rb1 %x, TBS %"PRIu16", pmi_alloc %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n", eNB->Mod_id, dlsch->rnti,harq_pid, frame, subframe, input_buffer_length, dlsch_harq->pdsch_start, @@ -332,42 +333,50 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, } - LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag); + LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n", + dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round); // 36-212 - start_meas(&eNB->dlsch_encoding_stats); - AssertFatal(dlsch_harq->pdu!=NULL,"dlsch_harq->pdu == NULL (rnti %x)\n",dlsch->rnti); - eNB->te(eNB, - dlsch_harq->pdu, - dlsch_harq->pdsch_start, - dlsch, - frame,subframe, - &eNB->dlsch_rate_matching_stats, - &eNB->dlsch_turbo_encoding_stats, - &eNB->dlsch_interleaving_stats); - stop_meas(&eNB->dlsch_encoding_stats); + if (nfapi_mode == 0 || nfapi_mode == 1) { // monolthic OR PNF - do not need turbo encoding on VNF + + if (dlsch_harq->pdu==NULL){ + LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]); + return; + } + + start_meas(&eNB->dlsch_encoding_stats); + + eNB->te(eNB, + dlsch_harq->pdu, + dlsch_harq->pdsch_start, + dlsch, + frame,subframe, + &eNB->dlsch_rate_matching_stats, + &eNB->dlsch_turbo_encoding_stats, + &eNB->dlsch_interleaving_stats); + stop_meas(&eNB->dlsch_encoding_stats); // 36-211 - start_meas(&eNB->dlsch_scrambling_stats); - dlsch_scrambling(fp, - 0, - dlsch, - harq_pid, - get_G(fp, - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc, - dlsch_harq->Qm, - dlsch_harq->Nl, - dlsch_harq->pdsch_start, - frame,subframe, - 0), - 0, - frame, - subframe<<1); - stop_meas(&eNB->dlsch_scrambling_stats); + start_meas(&eNB->dlsch_scrambling_stats); + dlsch_scrambling(fp, + 0, + dlsch, + harq_pid, + get_G(fp, + dlsch_harq->nb_rb, + dlsch_harq->rb_alloc, + dlsch_harq->Qm, + dlsch_harq->Nl, + dlsch_harq->pdsch_start, + frame,subframe, + 0), + 0, + frame, + subframe<<1); + stop_meas(&eNB->dlsch_scrambling_stats); + + start_meas(&eNB->dlsch_modulation_stats); + - start_meas(&eNB->dlsch_modulation_stats); - - - dlsch_modulation(eNB, + dlsch_modulation(eNB, eNB->common_vars.txdataF, AMP, subframe, @@ -376,12 +385,15 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, dlsch1); stop_meas(&eNB->dlsch_modulation_stats); + } #ifdef UE_EXPANSION dlsch->active[subframe] = 0; #else dlsch->active = 0; #endif dlsch_harq->round++; + + LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round); } @@ -423,12 +435,14 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } - if (is_pmch_subframe(frame,subframe,fp)) { - pmch_procedures(eNB,proc,rn,r_type); - } - else { - // this is not a pmch subframe, so generate PSS/SSS/PBCH - common_signal_procedures(eNB,proc); + if (nfapi_mode == 0 || nfapi_mode == 1) { + if (is_pmch_subframe(frame,subframe,fp)) { + pmch_procedures(eNB,proc,rn,r_type); + } + else { + // this is not a pmch subframe, so generate PSS/SSS/PBCH + common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx); + } } // clear existing ulsch dci allocations before applying info from MAC (this is table @@ -482,30 +496,34 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, num_dci = eNB->pdcch_vars[subframe&1].num_dci; // LOG_D(PHY,"num_pdcch_symbols %"PRIu8",(dci common %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols, // DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci); - LOG_D(PHY,"num_pdcch_symbols %"PRIu8",(number dci %"PRIu8"\n",num_pdcch_symbols, - num_dci); + LOG_D(PHY,"num_pdcch_symbols %"PRIu8",number dci %"PRIu8"\n",num_pdcch_symbols, num_dci); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,num_pdcch_symbols); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,(frame*10)+subframe); if (num_dci > 0) - LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe, - num_dci); + LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8") num_pdcch_symbols:%d\n",eNB->Mod_id,frame, subframe, num_dci, num_pdcch_symbols); + + //LOG_D(PHY,"Before generate_dci_top num_pdcch_symbols:%d num_dci:%d dci_alloc:dci_length:%d\n", num_pdcch_symbols, num_dci, eNB->pdcch_vars[subframe&1].dci_alloc[0].dci_length); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); + + if (nfapi_mode == 0 || nfapi_mode == 1) { + generate_dci_top(num_pdcch_symbols, + num_dci, + &eNB->pdcch_vars[subframe&1].dci_alloc[0], + 0, + AMP, + fp, + eNB->common_vars.txdataF, + subframe); + } - - generate_dci_top(num_pdcch_symbols, - num_dci, - &eNB->pdcch_vars[subframe&1].dci_alloc[0], - 0, - AMP, - fp, - eNB->common_vars.txdataF, - subframe); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); // Now scan UE specific DLSCH LTE_eNB_DLSCH_t *dlsch0,*dlsch1; for (UE_id=0; UE_idharq_ids[subframe]; AssertFatal(harq_pid>=0,"harq_pid is negative\n"); - // generate pdsch - pdsch_procedures(eNB, - proc, - harq_pid, - dlsch0, - dlsch1, - &eNB->UE_stats[(uint32_t)UE_id], - 0); + + if (harq_pid>=8) + { + LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti); + } + else + { + // generate pdsch + pdsch_procedures(eNB, + proc, + harq_pid, + dlsch0, + dlsch1, + &eNB->UE_stats[(uint32_t)UE_id], + 0); + } } @@ -545,16 +571,19 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, (dlsch0->active == 0)) { #endif - // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) - dlsch0->subframe_tx[subframe]=0; + // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) + dlsch0->subframe_tx[subframe]=0; } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH,1); generate_phich_top(eNB, proc, AMP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0); if (do_meas==1) stop_meas(&eNB->phy_proc_tx); @@ -562,11 +591,12 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } -void prach_procedures(PHY_VARS_eNB *eNB, #ifdef Rel14 - int br_flag +void prach_procedures(PHY_VARS_eNB *eNB, + int br_flag) { +#else +void prach_procedures(PHY_VARS_eNB *eNB) { #endif - ) { uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4]; uint16_t i; int frame,subframe; @@ -576,14 +606,14 @@ void prach_procedures(PHY_VARS_eNB *eNB, subframe = eNB->proc.subframe_prach_br; frame = eNB->proc.frame_prach_br; pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind_br.number_of_preambles=0; + eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles=0; pthread_mutex_unlock(&eNB->UL_INFO_mutex); } else #endif { pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.number_of_preambles=0; + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; pthread_mutex_unlock(&eNB->UL_INFO_mutex); subframe = eNB->proc.subframe_prach; frame = eNB->proc.frame_prach; @@ -625,18 +655,19 @@ void prach_procedures(PHY_VARS_eNB *eNB, //#ifdef DEBUG_PHY_PROC LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d\n", frame,subframe, - max_preamble[0], + max_preamble[0], max_preamble_energy[0]/10, max_preamble_delay[0]); //q#endif #ifdef Rel14 if (br_flag==1) { + int prach_mask; prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br); - eNB->UL_INFO.rach_ind_br.preamble_list = eNB->preamble_list_br; + eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; int ind=0; int ce_level=0; /* Save for later, it doesn't work @@ -650,7 +681,7 @@ void prach_procedures(PHY_VARS_eNB *eNB, if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]==1){ if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + 100)) { - eNB->UL_INFO.rach_ind_br.number_of_preambles++; + eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind];// eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; @@ -695,20 +726,33 @@ void prach_procedures(PHY_VARS_eNB *eNB, pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.preamble_list = eNB->preamble_list; + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; + eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; + eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; + eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; + eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - LOG_D(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); + if (nfapi_mode == 1) { // If NFAPI PNF then we need to send the message to the VNF + + LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), + eNB->preamble_list[0].preamble_rel8.timing_advance, + eNB->preamble_list[0].preamble_rel8.preamble, + eNB->preamble_list[0].preamble_rel8.rnti, + eNB->preamble_list[0].preamble_rel13.rach_resource_type); + + oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); + + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; + } + pthread_mutex_unlock(&eNB->UL_INFO_mutex); } // max_preamble_energy > prach_I0 + 100 @@ -757,21 +801,31 @@ void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) { pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_sr_indication_pdu_t *pdu = &eNB->UL_INFO.sr_ind.sr_pdu_list[eNB->UL_INFO.sr_ind.number_of_srs]; + nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind; + nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; + nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; + + sr_ind->sfn_sf = frame<<4|subframe; + sr_ind->header.message_id = NFAPI_RX_SR_INDICATION; + + sr_ind_body->tl.tag = NFAPI_SR_INDICATION_BODY_TAG; pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]); + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; + if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; pdu->ul_cqi_information.channel = 0; - eNB->UL_INFO.sr_ind.number_of_srs++; + sr_ind_body->number_of_srs++; pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1097,7 +1151,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } } uci->stat = max_metric; - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + fill_uci_harq_indication(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 @@ -1285,78 +1339,74 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - + if (fp->frame_type == FDD) harq_pid = ((10*frame) + subframe)&7; else harq_pid = subframe%10; for (i=0; iulsch[i]; ulsch_harq = ulsch->harq_processes[harq_pid]; - if (ulsch->rnti>0) LOG_D(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n", - frame,subframe,harq_pid,i,ulsch->rnti); - + if (ulsch->rnti>0) LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d handled:%d]\n", + i, harq_pid, frame,subframe,i,ulsch->rnti, + ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); + if ((ulsch) && (ulsch->rnti>0) && (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && + (ulsch_harq->frame == frame) && + (ulsch_harq->subframe == subframe) && (ulsch_harq->handled == 0)) { - + // UE has ULSCH scheduling for (int rb=0; rb<=ulsch_harq->nb_rb; - rb++) { - int rb2 = rb+ulsch_harq->first_rb; - eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + rb++) { + int rb2 = rb+ulsch_harq->first_rb; + eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); } - LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n", - eNB->Mod_id, - frame, - subframe, - i); + LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n", eNB->Mod_id, frame, subframe, i); nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - nPRS)%12; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + + nPRS)%12; LOG_D(PHY, - "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d, beta_cqi %d \n", - eNB->Mod_id,harq_pid,frame,subframe, - ulsch_harq->dci_alloc, - ulsch_harq->rar_alloc, - ulsch_harq->round, - ulsch_harq->first_rb, - ulsch_harq->nb_rb, - ulsch_harq->Qm, - ulsch_harq->TBS, - ulsch_harq->rvidx, - ulsch->cyclicShift, - ulsch_harq->n_DMRS2, - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, - nPRS, - ulsch_harq->O_ACK, - ulsch->beta_offset_cqi_times8); + "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, ), O_ACK %d, beta_cqi %d \n", + eNB->Mod_id,harq_pid,frame,subframe, + ulsch_harq->dci_alloc, + ulsch_harq->rar_alloc, + ulsch_harq->round, + ulsch_harq->first_rb, + ulsch_harq->nb_rb, + ulsch_harq->Qm, + ulsch_harq->TBS, + ulsch_harq->rvidx, + ulsch->cyclicShift, + ulsch_harq->n_DMRS2, + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, + ulsch_harq->O_ACK, + ulsch->beta_offset_cqi_times8); - start_meas(&eNB->ulsch_demodulation_stats); + start_meas(&eNB->ulsch_demodulation_stats); rx_ulsch(eNB,proc, i); - stop_meas(&eNB->ulsch_demodulation_stats); + stop_meas(&eNB->ulsch_demodulation_stats); - start_meas(&eNB->ulsch_decoding_stats); + start_meas(&eNB->ulsch_decoding_stats); - ret = ulsch_decoding(eNB,proc, - i, - 0, // control_only_flag - ulsch_harq->V_UL_DAI, - ulsch_harq->nb_rb>20 ? 1 : 0); + ret = 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); + 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\n", + 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, @@ -1366,51 +1416,54 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) 20,//eNB->measurements.n0_power_dB[1], ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1], - ret); + ret, + ulsch_harq->cqi_crc_status, + ulsch_harq->O_ACK, + eNB->ulsch_decoding_stats.diff_now, eNB->ulsch_decoding_stats.max); - //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 + //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 (ulsch_harq->cqi_crc_status == 1) { + 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); + //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); + fill_ulsch_cqi_indication(eNB,frame,subframe, + ulsch_harq, + ulsch->rnti); } - + 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 + 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-1, - ulsch->Mlimit, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1]); + LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", + eNB->Mod_id,harq_pid, + frame,subframe, i, + ulsch_harq->round-1, + ulsch->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; - } + } #if defined(MESSAGE_CHART_GENERATOR_PHY) 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 - ); + 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 + ); #endif /* Mark the HARQ process to release it later if max transmission reached @@ -1421,8 +1474,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ulsch_harq->handled = 1; } // ulsch in error else { - fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC + 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); @@ -1431,27 +1484,27 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) T_INT(harq_pid)); #if defined(MESSAGE_CHART_GENERATOR_PHY) - 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 - ); + 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 + ); #endif #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); + 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; jTBS>>3; j++) - LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); + for (j=0; jTBS>>3; j++) + LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); - LOG_T(PHY,"\n"); + LOG_T(PHY,"\n"); #endif #endif - } // ulsch not in error + } // ulsch not in error if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling); @@ -1474,14 +1527,14 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) (ulsch_harq->frame == frame) && (ulsch_harq->subframe == subframe) && (ulsch_harq->handled == 1)) { - // this harq process is stale, kill it, this 1024 frames later (10s), consider reducing that - ulsch_harq->status = SCH_IDLE; + // this harq process is stale, kill it, this 1024 frames later (10s), consider reducing that + ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; ulsch->harq_mask &= ~(1 << harq_pid); 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; iframe_parms, - frame,subframe); + frame,subframe); pthread_mutex_lock(&eNB->UL_INFO_mutex); - pdu = &eNB->UL_INFO.rx_ind.rx_pdu_list[eNB->UL_INFO.rx_ind.number_of_pdus]; + + eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe; + eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + + pdu = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; + pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; - pdu->rx_indication_rel8.offset = 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b; + 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; // 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 @@ -1565,11 +1624,12 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) 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] Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n", - harq_pid,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, - timing_advance_update); + 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,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, + timing_advance_update); - eNB->UL_INFO.rx_ind.number_of_pdus++; + eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; + eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe; pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1664,11 +1724,13 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; if (ulsch_harq->cqi_crc_status != 1) pdu->cqi_indication_rel9.data_offset = 0; else pdu->cqi_indication_rel9.data_offset = 1; // fill in after all cqi_indications have been generated when non-zero // by default set O to rank 1 value + pdu->cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG; pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); pdu->cqi_indication_rel9.ri[0] = 0; @@ -1683,6 +1745,8 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe pdu->ul_cqi_information.channel = 1; // PUSCH memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length); eNB->UL_INFO.cqi_ind.number_of_cqis++; + LOG_D(PHY,"eNB->UL_INFO.cqi_ind.number_of_cqis:%d\n", eNB->UL_INFO.cqi_ind.number_of_cqis); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1690,18 +1754,33 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe 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) { int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST); - AssertFatal(UE_id>=0,"UE_id doesn't exist\n"); + //AssertFatal(UE_id>=0,"UE_id doesn't exist\n"); + + if (UE_id < 0) + { + LOG_E(PHY,"%s(eNB, ulsch_harq, rnti:%04x, frame:%d, subframe:%d, bundling:%d) harq_pdus:%d - Could not find rnti - abort fill of ulsch harq ind\n", __FUNCTION__, rnti, frame, subframe, bundling,eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs); + return; + } + + LOG_D(PHY,"%s(eNB, ulsch_harq, rnti:%04x, frame:%d, subframe:%d, bundling:%d) harq_pdus:%d O_ACK:%d\n", __FUNCTION__, rnti, frame, subframe, bundling,eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,ulsch_harq->O_ACK); pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs]; + nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; int M; int i; + eNB->UL_INFO.harq_ind.header.message_id = NFAPI_HARQ_INDICATION; + eNB->UL_INFO.harq_ind.sfn_sf = frame<<4|subframe; + + eNB->UL_INFO.harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; if (eNB->frame_parms.frame_type == FDD) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; @@ -1727,8 +1806,9 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, M=ul_ACK_subframe2_M(&eNB->frame_parms, subframe); - pdu->harq_indication_fdd_rel13.mode = 1-bundling; - pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.mode = 1-bundling; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; for (i=0;iO_ACK;i++) { AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]); @@ -1746,7 +1826,9 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq, } } - eNB->UL_INFO.harq_ind.number_of_harqs++; + //LOG_E(PHY,"eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs:%d\n", eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs); + eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1759,17 +1841,30 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, uint16_t tdd_multiplexing_mask) { int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST); - AssertFatal(UE_id>=0,"UE_id doesn't exist\n"); - + //AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti); + if (UE_id < 0) { + LOG_E(PHY,"SFN/SF:%04d%d Unable to find rnti:%x do not send HARQ\n", frame, subframe, uci->rnti); + return; + } pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs]; + nfapi_harq_indication_t *ind = &eNB->UL_INFO.harq_ind; + nfapi_harq_indication_body_t *body = &ind->harq_indication_body; + nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; + + ind->sfn_sf = frame<<4|subframe; + ind->header.message_id = NFAPI_HARQ_INDICATION; + + body->tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; + pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = uci->rnti; // estimate UL_CQI for MAC (from antenna port 0 only) + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; int SNRtimes10 = dB_fixed_times10(uci->stat) - 200;//(10*eNB->measurements.n0_power_dB[0]); if (SNRtimes10 < -100) LOG_I(PHY,"uci->stat %d \n",uci->stat); @@ -1781,6 +1876,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (eNB->frame_parms.frame_type == FDD) { if (uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1; @@ -1799,6 +1895,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, #endif } else if (uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2; AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); @@ -1816,12 +1913,14 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, AssertFatal(tdd_mapping_mode==0 || tdd_mapping_mode==1 || tdd_mapping_mode==2, "Illegal tdd_mapping_mode %d\n",tdd_mapping_mode); + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode; switch (tdd_mapping_mode) { case 0: // bundling if (uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; @@ -1832,6 +1931,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; // release all DLSCH if needed @@ -1843,6 +1943,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, AssertFatal(uci->pucch_fmt == pucch_format1b,"uci->pucch_format %d is not format1b\n",uci->pucch_fmt); if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; @@ -1850,6 +1951,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); } else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); @@ -1860,6 +1962,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); } else { // num_pucch_resources (M) > 1 + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources; pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; @@ -1872,6 +1975,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, } break; case 2: // special bundling (SR collision) + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; int tdd_config5_sf2scheds=0; if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe); @@ -1907,7 +2011,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, } //TDD - eNB->UL_INFO.harq_ind.number_of_harqs++; + eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs++; + LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs:%d\n", eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs); pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1916,14 +2021,23 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB, void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag) { pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_pdu_list[eNB->UL_INFO.crc_ind.number_of_crcs]; + nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; + + eNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | subframe; + eNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; + eNB->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 = eNB->ulsch[UE_id]->rnti; + pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; pdu->crc_indication_rel8.crc_flag = crc_flag; - eNB->UL_INFO.crc_ind.number_of_crcs++; + eNB->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(&eNB->UL_INFO_mutex); } @@ -1954,8 +2068,8 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->rb_mask_ul[3]=0; // Fix me here, these should be locked - eNB->UL_INFO.rx_ind.number_of_pdus = 0; - eNB->UL_INFO.crc_ind.number_of_crcs = 0; + eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; + eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0; // Call SRS first since all others depend on presence of SRS or lack thereof srs_procedures(eNB,proc); @@ -1964,7 +2078,9 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const uci_procedures(eNB,proc); - pusch_procedures(eNB,proc); + if (nfapi_mode == 0 || nfapi_mode == 1) { // If PNF or monolithic + pusch_procedures(eNB,proc); + } lte_eNB_I0_measurements(eNB, subframe, @@ -1982,13 +2098,8 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const LOG_I(PHY,"max_I0 %d, min_I0 %d\n",max_I0,min_I0); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); stop_meas(&eNB->phy_proc_rx); } - - - - diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index f7419d4db2..4f24b2745d 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -51,10 +51,6 @@ #include "LAYER2/MAC/defs.h" #include "UTIL/LOG/log.h" -#ifdef EMOS -fifo_dump_emos_UE emos_dump_UE; -#endif - #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" @@ -68,6 +64,8 @@ fifo_dump_emos_UE emos_dump_UE; #include "T.h" +#include "PHY/TOOLS/defs.h" + #define DLSCH_RB_ALLOC 0x1fbf // skip DC RB (total 23/25 RBs) #define DLSCH_RB_ALLOC_12 0x0aaa // skip DC RB (total 23/25 RBs) @@ -75,7 +73,8 @@ fifo_dump_emos_UE emos_dump_UE; extern double cpuf; - +void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); +void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; @@ -1192,38 +1191,6 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, } -#ifdef EMOS -/* - void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) { - uint8_t harq_pid; - - - if (next_slot%2==0) { - // get harq_pid from subframe relationship - harq_pid = subframe2harq_pid(&ue->frame_parms,ue->frame,(next_slot>>1)); - if (harq_pid==255) { - LOG_E(PHY,"[UE%d] Frame %d : FATAL ERROR: illegal harq_pid, returning\n", - 0,ue->frame); - return; - } - - if (ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) { - emos_dump_UE.uci_cnt[next_slot>>1] = 1; - memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o,ulsch[eNB_id]->o,MAX_CQI_BITS*sizeof(char)); - emos_dump_UE.UCI_data[0][next_slot>>1].O = ulsch[eNB_id]->O; - memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_RI,ulsch[eNB_id]->o_RI,2*sizeof(char)); - emos_dump_UE.UCI_data[0][next_slot>>1].O_RI = ulsch[eNB_id]->O_RI; - memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_ACK,ulsch[eNB_id]->o_ACK,4*sizeof(char)); - emos_dump_UE.UCI_data[0][next_slot>>1].O_ACK = ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK; - } - else { - emos_dump_UE.uci_cnt[next_slot>>1] = 0; - } - } - } -*/ -#endif - void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empty_subframe) { int aa; @@ -1423,9 +1390,6 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->prach_cnt=0; #ifdef SMBV ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; -#endif -#ifdef OAI_EMU - ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex; #endif LOG_I(PHY,"mode %d\n",mode); @@ -1833,12 +1797,6 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } } -#ifdef PHY_ABSTRACTION - else { - ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0); - } - -#endif #if UE_TIMING_TRACE stop_meas(&ue->ulsch_encoding_stats); #endif @@ -2389,10 +2347,6 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui start_meas(&ue->phy_proc_tx); #endif -#ifdef EMOS - //phy_procedures_emos_UE_TX(next_slot); -#endif - ue->tx_power_dBm[subframe_tx]=-127; @@ -2673,11 +2627,6 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0); } -#ifdef EMOS - //emos_dump_UE.frame_tx = frame_tx; - //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1]; -#endif - if (first_run) { first_run = 0; @@ -4675,11 +4624,6 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr } -#ifdef EMOS - phy_procedures_emos_UE_RX(ue,slot,eNB_id); -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE @@ -5159,11 +5103,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); #endif -#ifdef EMOS - phy_procedures_emos_UE_RX(ue,slot,eNB_id); -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE diff --git a/openair1/SCHED/rt_compat.h b/openair1/SCHED/rt_compat.h deleted file mode 100644 index 35e99098fa..0000000000 --- a/openair1/SCHED/rt_compat.h +++ /dev/null @@ -1,138 +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 - */ - -/* Header file for making PLATON work on both RTLinux and RTAI using pthreads -* Copyright Frank Wartena, 2004 -* Version: 0.1 January 28th, 2004 ## First version for scheduling test -* 0.2 February 20th, 2004 ## All PLATON functions added -* It is mostly a conversion from RTLinux to RTAI, because PLATON was written -* for RTLinux. -* Not all necessary conversions can be done in this header file, other -* adjustments in the code are also necessary. -*/ - -#ifndef _RT_COMPAT_H_ -#define _RT_COMPAT_H_ - -#ifdef RTAI_ENABLED -//the conversions from RTLinux to RTAI - -//variable for containing times -#define hrtime_t RTIME - -//function for making a thread periodic -#define pthread_make_periodic_np(x,y,z) rt_task_make_periodic(x,rt_get_time(),nano2count(z)) - -//function for printing to the kernel log -#define rtl_printf printk - -//function for determining the current cpu -#define rtl_getcpuid hard_cpu_id - -//function for initialising a mutex -#define pthread_mutex_init pthread_mutex_init_rt - -//function for initialising a mutex attribute -#define pthread_mutexattr_init pthread_mutexattr_init_rt - -//function for setting a mutex protocol, does not exist in RTAI -#define pthread_mutexattr_setprotocol(x,y); - -//function for locking a mutex -#define pthread_mutex_lock pthread_mutex_lock_rt - -//function for unlocking a mutex -#define pthread_mutex_unlock pthread_mutex_unlock_rt - -//function for destroying a mutex -#define pthread_mutex_destroy pthread_mutex_destroy_rt - -//function for getting the current time -#define clock_gethrtime(x) rt_get_time_ns() -#define gethrtime rt_get_time_ns - -//function for initialising a condition -#define pthread_cond_init pthread_cond_init_rt - -//function for waiting on a condition -#define pthread_cond_wait pthread_cond_wait_rt - -//function for signalling a condition -#define pthread_cond_signal pthread_cond_signal_rt - -//function for destroying a condition -#define pthread_cond_destroy pthread_cond_destroy_rt - -//function for waking up a thread -#define pthread_wakeup_np rt_task_resume - -//function for getting the current thread -#define pthread_self rt_whoami - -//function for initialising an attribute -#define pthread_attr_init pthread_attr_init_rt - -//function for setting a schedparam -#define pthread_attr_setschedparam pthread_attr_setschedparam_rt - -//funcion for setting a schedpolicy -#define pthread_attr_setschedpolicy pthread_attr_setschedpolicy_rt - -//function for creating a thread -#define pthread_create pthread_create_rt - -//function for cancelling a thread -#define pthread_cancel pthread_cancel_rt - -//function for deleting a thread, in RTAI both by calling cancel -#define pthread_delete_np pthread_cancel_rt - -//testing if a cpuid exists -#define rtl_cpu_exists(x) xNcp==1) ? 6 : 7); int subframe = ru->proc.subframe_tx; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 ); + slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1)); - // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); + //LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot); for (aa=0; aanb_tx; aa++) { if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF], @@ -132,6 +131,7 @@ void feptx0(RU_t *ru,int slot) { } } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 0); } static void *feptx_thread(void *param) { @@ -302,11 +302,11 @@ void feptx_ofdm(RU_t *ru) { } txdata = (int16_t*)&ru->common.txdata[aa][0]; for (j=0; i<(len<<1); i++,j++) { - txdata[j++] = ((int16_t*)dummy_tx_b)[i]; + txdata[j++] = ((int16_t*)dummy_tx_b)[i]; } } else { - LOG_D(PHY,"feptx_ofdm: Writing to position %d\n",slot_offset); + //LOG_D(PHY,"feptx_ofdm: Writing to position %d\n",slot_offset); tx_offset = (int)slot_offset; txdata = (int16_t*)&ru->common.txdata[aa][tx_offset]; @@ -325,9 +325,9 @@ void feptx_ofdm(RU_t *ru) { */ if ((fp->frame_type == TDD) && ((fp->tdd_config==0) || - (fp->tdd_config==1) || - (fp->tdd_config==2) || - (fp->tdd_config==6)) && + (fp->tdd_config==1) || + (fp->tdd_config==2) || + (fp->tdd_config==6)) && ((subframe==0) || (subframe==5))) { // turn on tx switch N_TA_offset before //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,ru->N_TA_offset,slot_offset); @@ -363,10 +363,14 @@ void feptx_prec(RU_t *ru) { eNB = eNB_list[0]; fp = &eNB->frame_parms; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + for (aa=0;aanb_tx;aa++) memcpy((void*)ru->common.txdataF_BF[aa], (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size], fp->symbols_per_tti*fp->ofdm_symbol_size*sizeof(int32_t)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); } else { for (i=0;inum_eNB;i++) { @@ -385,9 +389,11 @@ void feptx_prec(RU_t *ru) { aa); } } +#if 0 LOG_D(PHY,"feptx_prec: frame %d, subframe %d: txp (freq) %d dB\n", ru->proc.frame_tx,subframe, dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[0],2*fp->symbols_per_tti*fp->ofdm_symbol_size))); +#endif } } } @@ -400,6 +406,8 @@ void fep0(RU_t *ru,int slot) { // printf("fep0: slot %d\n",slot); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 1); + remove_7_5_kHz(ru,(slot&1)+(proc->subframe_rx<<1)); for (l=0; lsymbols_per_tti/2; l++) { slot_fep_ul(ru, @@ -408,6 +416,7 @@ void fep0(RU_t *ru,int slot) { 0 ); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 0); } @@ -588,4 +597,3 @@ void do_prach_ru(RU_t *ru) { } } - diff --git a/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c b/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c index 01bc8f4901..e96db24521 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c @@ -38,10 +38,7 @@ #include "UTIL/OCG/OCG_extern.h" #include "UTIL/LOG/log.h" -#ifdef USER_MODE -# include "multicast_link.h" -# include "pgm_link.h" -#endif +#include "multicast_link.h" char rx_bufferP[BYPASS_RX_BUFFER_SIZE]; unsigned int num_bytesP = 0; @@ -51,10 +48,6 @@ static unsigned int byte_tx_count; unsigned int Master_list_rx; static uint64_t seq_num_tx = 0; -#if defined(ENABLE_PGM_TRANSPORT) -extern unsigned int pgm_would_block; -#endif - mapping transport_names[] = { {"WAIT PM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_PM}, {"WAIT SM TRANSPORT INFO", EMU_TRANSPORT_INFO_WAIT_SM}, @@ -62,9 +55,6 @@ mapping transport_names[] = { {"ENB_TRANSPORT INFO", EMU_TRANSPORT_INFO_ENB}, {"UE TRANSPORT INFO", EMU_TRANSPORT_INFO_UE}, {"RELEASE TRANSPORT INFO", EMU_TRANSPORT_INFO_RELEASE}, -#if defined(ENABLE_PGM_TRANSPORT) - {"NACK TRANSPORT INFO", EMU_TRANSPORT_NACK}, -#endif {NULL, -1} }; @@ -79,9 +69,6 @@ void init_bypass (void) pthread_mutex_init (&emul_low_mutex, NULL); pthread_cond_init (&emul_low_cond, NULL); emul_low_mutex_var = 1; -#endif -#if defined(ENABLE_PGM_TRANSPORT) - pgm_oai_init(oai_emulation.info.multicast_ifname); #endif bypass_init (emul_tx_handler, emul_rx_handler); } @@ -90,10 +77,8 @@ void init_bypass (void) void bypass_init (tx_handler_t tx_handlerP, rx_handler_t rx_handlerP) { /***************************************************************************/ -#if defined(USER_MODE) multicast_link_start (bypass_rx_handler, oai_emulation.info.multicast_group, oai_emulation.info.multicast_ifname); -#endif //USER_MODE tx_handler = tx_handlerP; rx_handler = rx_handlerP; Master_list_rx=0; @@ -322,20 +307,12 @@ int bypass_rx_data(unsigned int frame, unsigned int last_slot, frame, next_slot, is_master); #if defined(ENABLE_NEW_MULTICAST) -# if defined(ENABLE_PGM_TRANSPORT) - num_bytesP = pgm_recv_msg(oai_emulation.info.multicast_group, - (uint8_t *)&rx_bufferP[0], sizeof(rx_bufferP), - frame, next_slot); - - DevCheck(num_bytesP > 0, num_bytesP, 0, 0); -# else if (multicast_link_read_data_from_sock(is_master) == 1) { /* We got a timeout */ return -1; } -# endif #else pthread_mutex_lock(&emul_low_mutex); @@ -363,10 +340,6 @@ int bypass_rx_data(unsigned int frame, unsigned int last_slot, num_bytesP, map_int_to_str(transport_names, messg->Message_type), messg->master_id, messg->seq_num); -#if defined(ENABLE_PGM_TRANSPORT) - - if (messg->Message_type != EMU_TRANSPORT_NACK) -#endif DevCheck4((messg->frame == frame) && (messg->subframe == (next_slot>>1)), messg->frame, frame, messg->subframe, next_slot>>1); @@ -409,20 +382,6 @@ int bypass_rx_data(unsigned int frame, unsigned int last_slot, Master_list_rx = oai_emulation.info.master_list; LOG_E(EMU, "RX EMU_TRANSPORT_INFO_RELEASE\n"); break; -#if defined(ENABLE_PGM_TRANSPORT) - - case EMU_TRANSPORT_NACK: - if (messg->failing_master_id == oai_emulation.info.master_id) { - /* We simply re-send the last message */ - pgm_link_send_msg(oai_emulation.info.multicast_group, - (uint8_t *)bypass_tx_buffer, byte_tx_count); - } else { - /* Sleep awhile till other peers have recovered data */ - usleep(500); - } - - break; -#endif default: LOG_E(EMU, "[MAC][BYPASS] ERROR RX UNKNOWN MESSAGE\n"); @@ -448,35 +407,6 @@ int bypass_rx_data(unsigned int frame, unsigned int last_slot, return bytes_read; } -/******************************************************************************************************/ -#ifndef USER_MODE -int bypass_rx_handler(unsigned int fifo, int rw) -{ - /******************************************************************************************************/ - int bytes_read; - int bytes_processed=0; - int header_bytes; //, elapsed_time; - //printk("[BYPASS] BYPASS_RX_HANDLER IN...\n"); - header_bytes= rtf_get(fifo_bypass_phy_user2kern, rx_bufferP, - sizeof(bypass_proto2multicast_header_t) ); - - if (header_bytes> 0) { - bytes_read = rtf_get(fifo_bypass_phy_user2kern, &rx_bufferP[header_bytes], - ((bypass_proto2multicast_header_t *) (&rx_bufferP[0]))->size); - - // printk("BYTES_READ=%d\n",bytes_read); - if (bytes_read > 0) { - num_bytesP=header_bytes+bytes_read; - emul_low_mutex_var=0; - //printk("BYPASS_PHY SIGNAL MAC_LOW...\n"); - pthread_cond_signal(&emul_low_cond); - } - } - - // } - return 0; -} -#else //USER_MODE /******************************************************************************************************/ void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer) { @@ -503,7 +433,6 @@ void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer) #endif } } -#endif //USER_MODE /******************************************************************************************************/ void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, @@ -511,57 +440,12 @@ void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, { /******************************************************************************************************/ if (Master_list_rx != oai_emulation.info.master_list) { -#ifndef USER_MODE - rtf_put(fifo_mac_bypass, &tt, 1); - /* the Rx window is still opened (Re)signal bypass_phy (emulate MAC signal) */ -#endif bypass_rx_data(frame, last_slot, next_slot, is_master); } else { Master_list_rx = 0; } } -#ifndef USER_MODE -/***************************************************************************/ -int multicast_link_write_sock (int groupP, char *dataP, unsigned int sizeP) -{ - /***************************************************************************/ - int tx_bytes=0; - - pthread_mutex_lock(&Tx_mutex); - - while(!Tx_mutex_var) { - pthread_cond_wait(&Tx_cond,&Tx_mutex); - } - - Tx_mutex_var=0; - N_P=(int)((sizeP-sizeof (bypass_proto2multicast_header_t))/1000)+2; - tx_bytes += rtf_put (fifo_bypass_phy_kern2user, &dataP[tx_bytes], - sizeof (bypass_proto2multicast_header_t)); - - while(tx_bytesMessage_type = EMU_TRANSPORT_NACK; - - for (i = 0; i < oai_emulation.info.nb_master; i++) { - /* Skip our id */ - if (i == oai_emulation.info.master_id) - continue; - - if ((Master_list_rx & (1 << i)) == 0) { - messg->failing_master_id = i; - break; - } - } - - LOG_T(EMU,"[TX_DATA] NACK TRANSPORT\n"); - } else -#endif if (Type == WAIT_PM_TRANSPORT) { messg->Message_type = EMU_TRANSPORT_INFO_WAIT_PM; LOG_T(EMU,"[TX_DATA] WAIT SYNC PM TRANSPORT\n"); @@ -702,32 +566,11 @@ void bypass_tx_data(emu_transport_info_t Type, unsigned int frame, unsigned int ((bypass_proto2multicast_header_t *) bypass_tx_buffer)->size = byte_tx_count - sizeof (bypass_proto2multicast_header_t); -#if defined(ENABLE_PGM_TRANSPORT) - pgm_link_send_msg(oai_emulation.info.multicast_group, - (uint8_t *)bypass_tx_buffer, byte_tx_count); -#else multicast_link_write_sock(oai_emulation.info.multicast_group, bypass_tx_buffer, byte_tx_count); -#endif LOG_D(EMU, "Frame %d, subframe %d (%d): Sent %d bytes [%s] with master_id %d and seq %"PRIuMAX"\n", frame, next_slot>>1, next_slot,byte_tx_count, map_int_to_str(transport_names, Type), messg->master_id, messg->seq_num); } -#ifndef USER_MODE -/*********************************************************************************************************************/ -int bypass_tx_handler(unsigned int fifo, int rw) -{ - /***************************************************************************/ - if(++N_R==N_P) { - rtf_reset(fifo_bypass_phy_kern2user); - - Tx_mutex_var=1; - N_R=0; - - pthread_cond_signal(&Tx_cond); - } -} -#endif - diff --git a/openair1/SIMULATION/ETH_TRANSPORT/defs.h b/openair1/SIMULATION/ETH_TRANSPORT/defs.h index 3b744aa859..5cd961b61a 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/defs.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/defs.h @@ -41,9 +41,6 @@ typedef enum emu_transport_info_e { EMU_TRANSPORT_INFO_ENB, EMU_TRANSPORT_INFO_UE, EMU_TRANSPORT_INFO_RELEASE -#if defined(ENABLE_PGM_TRANSPORT) - ,EMU_TRANSPORT_NACK -#endif } emu_transport_info_t; #define WAIT_PM_TRANSPORT 1 @@ -52,9 +49,6 @@ typedef enum emu_transport_info_e { #define ENB_TRANSPORT 4 #define UE_TRANSPORT 5 #define RELEASE_TRANSPORT 6 -#if defined(ENABLE_PGM_TRANSPORT) -# define NACK_TRANSPORT 7 -#endif #define WAIT_SYNC_TRANSPORT 1 #define SYNCED_TRANSPORT 2 diff --git a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c index 186201cd0b..f71a8ee117 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c @@ -40,49 +40,17 @@ #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" -#include "pgm_link.h" - extern unsigned int Master_list_rx; extern unsigned char NB_INST; //#define DEBUG_CONTROL 1 //#define DEBUG_EMU 1 -#if defined(ENABLE_PGM_TRANSPORT) -extern unsigned int pgm_would_block; -#endif - void emu_transport_sync(void) { LOG_D(EMU, "Entering EMU transport SYNC is primary master %d\n", oai_emulation.info.is_primary_master); -#if defined(ENABLE_PGM_TRANSPORT) - - if (oai_emulation.info.is_primary_master == 0) { - bypass_tx_data(WAIT_SM_TRANSPORT,0,0); - // just wait to recieve the master 0 msg - Master_list_rx = oai_emulation.info.master_list - 1; - bypass_rx_data(0,0,0,1); - } else { - bypass_rx_data(0,0,0,0); - bypass_tx_data(WAIT_PM_TRANSPORT,0,0); - } - - if (oai_emulation.info.master_list != 0) { - bypass_tx_data(SYNC_TRANSPORT,0,0); - bypass_rx_data(0,0,0,0); - - // i received the sync from all secondary masters - if (emu_rx_status == SYNCED_TRANSPORT) { - emu_tx_status = SYNCED_TRANSPORT; - } - - LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n"); - } - -#else - if (oai_emulation.info.is_primary_master == 0) { retry: bypass_tx_data(WAIT_SM_TRANSPORT,0,0); @@ -115,8 +83,6 @@ retry2: LOG_D(EMU,"TX secondary master SYNC_TRANSPORT state \n"); } -#endif - LOG_D(EMU, "Leaving EMU transport SYNC is primary master %d\n", oai_emulation.info.is_primary_master); } @@ -154,9 +120,6 @@ void emu_transport(unsigned int frame, unsigned int last_slot, } } -#if defined(ENABLE_PGM_TRANSPORT) - pgm_would_block = 0; -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT, VCD_FUNCTION_OUT); } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/extern.h b/openair1/SIMULATION/ETH_TRANSPORT/extern.h index fafa7009f5..c01b5584e2 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/extern.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/extern.h @@ -31,11 +31,7 @@ #ifndef __BYPASS_SESSION_LAYER_EXTERN_H__ # define __BYPASS_SESSION_LAYER_EXTERN_H__ -#ifndef USER_MODE -#include -#else #include -#endif //RTAI_ENABLED extern unsigned char Emulation_status; extern unsigned char emu_tx_status; diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c index f32823f3bb..1ba724976f 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c @@ -54,9 +54,7 @@ #include "socket.h" #include "multicast_link.h" -#ifdef USER_MODE -# include "UTIL/LOG/log.h" -#endif //USER_MODE +#include "UTIL/LOG/log.h" extern unsigned short Master_id; @@ -316,9 +314,7 @@ void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), LOG_I(EMU, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n", (multicast_if == NULL) ? "not specified" : multicast_if, multicast_group, rx_handler); -#if !defined(ENABLE_PGM_TRANSPORT) multicast_link_init (); -#endif #if ! defined(ENABLE_NEW_MULTICAST) LOG_D(EMU, "[MULTICAST] multicast link start thread\n"); diff --git a/openair1/SIMULATION/ETH_TRANSPORT/pgm_link.c b/openair1/SIMULATION/ETH_TRANSPORT/pgm_link.c deleted file mode 100644 index 61bf940660..0000000000 --- a/openair1/SIMULATION/ETH_TRANSPORT/pgm_link.c +++ /dev/null @@ -1,417 +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 pgm_link.c - * \brief implementation a warpper for openpgm for reliable multicast transmission - * \author Navid Nikaein and S. Roux - * \date 2013 - 2014 - * \version 1.0 - * \company Eurecom - * \email: navid.nikaein@eurecom.fr - */ - -#include -#include -#include -#include -#include - -#include - -#if defined(ENABLE_PGM_TRANSPORT) - -#include - -#include "assertions.h" - -#include "pgm_link.h" -#include "multicast_link.h" - -#include "UTIL/OCG/OCG.h" -#include "UTIL/OCG/OCG_extern.h" - -#include "UTIL/LOG/log.h" - -// #define ENABLE_PGM_DEBUG - -typedef struct { - pgm_sock_t *sock; - uint16_t port; - uint8_t rx_buffer[40000]; -} pgm_multicast_group_t; - -pgm_multicast_group_t pgm_multicast_group[MULTICAST_LINK_NUM_GROUPS]; - -static -int pgm_create_socket(int index, const char *if_addr); - -unsigned int pgm_would_block = 1; - -#if defined(ENABLE_PGM_DEBUG) -static void -log_handler ( - const int log_level, - const char* message, - void* closure -) -{ - printf("%s\n", message); -} -#endif - -int pgm_oai_init(char *if_addr) -{ - pgm_error_t* pgm_err = NULL; - - memset(pgm_multicast_group, 0, - MULTICAST_LINK_NUM_GROUPS * sizeof(pgm_multicast_group_t)); - -#if defined(ENABLE_PGM_DEBUG) - pgm_messages_init(); - pgm_min_log_level = PGM_LOG_LEVEL_DEBUG; - pgm_log_mask = 0xFFF; - - pgm_log_set_handler(log_handler, NULL); -#endif - - if (!pgm_init(&pgm_err)) { - LOG_E(EMU, "Unable to start PGM engine: %s\n", pgm_err->message); - pgm_error_free (pgm_err); - exit(EXIT_FAILURE); - } - - return pgm_create_socket(oai_emulation.info.multicast_group, if_addr); -} - -int pgm_recv_msg(int group, uint8_t *buffer, uint32_t length, - unsigned int frame, unsigned int next_slot) -{ - size_t num_bytes = 0; - int status = 0; - pgm_error_t* pgm_err = NULL; - struct pgm_sockaddr_t from; - socklen_t fromlen = sizeof(from); - uint32_t timeout = 0; - int flags = 0; - - if (pgm_would_block == 0) { - flags = MSG_DONTWAIT; - } - - DevCheck((group <= MULTICAST_LINK_NUM_GROUPS) && (group >= 0), - group, MULTICAST_LINK_NUM_GROUPS, 0); - -#ifdef DEBUG_EMU - LOG_I(EMU, "[PGM] Entering recv function for group %d\n", group); -#endif - - do { - status = pgm_recvfrom(pgm_multicast_group[group].sock, - buffer, - length, - flags, - &num_bytes, - &from, - &fromlen, - &pgm_err); - - if (PGM_IO_STATUS_NORMAL == status) { -#ifdef DEBUG_EMU - LOG_D(EMU, "[PGM] Received %d bytes for group %d\n", num_bytes, group); -#endif - return num_bytes; - } else if (PGM_IO_STATUS_TIMER_PENDING == status) { - if (pgm_would_block == 0) { - /* We sleep for 50 usec */ - usleep(50); - - timeout ++; - - if (timeout == (1000000 / 50)) { - LOG_W(EMU, "[PGM] A packet has been lost -> ask for retransmit\n"); - /* If we do not receive a packet after 10000usec - * -> send a NACK */ - bypass_tx_nack(frame, next_slot); - timeout = 0; - } - } - } else if (PGM_IO_STATUS_RESET == status) { - LOG_W(EMU, "[PGM] Got session reset\n"); - } else { -#ifdef DEBUG_EMU - LOG_D(EMU, "[PGM] Got status %d\n", status); -#endif - - if (pgm_err) { - LOG_E(EMU, "[PGM] recvform failed: %s", pgm_err->message); - pgm_error_free (pgm_err); - pgm_err = NULL; - } - } - } while(status != PGM_IO_STATUS_NORMAL); - - return -1; -} - -int pgm_link_send_msg(int group, uint8_t *data, uint32_t len) -{ - int status; - size_t bytes_written = 0; - - do { - status = pgm_send(pgm_multicast_group[group].sock, data, len, &bytes_written); - } while(status == PGM_IO_STATUS_WOULD_BLOCK); - - if (status != PGM_IO_STATUS_NORMAL) { - return -1; - } - - return bytes_written; -} - -static -int pgm_create_socket(int index, const char *if_addr) -{ - struct pgm_addrinfo_t* res = NULL; - pgm_error_t* pgm_err = NULL; - sa_family_t sa_family = AF_INET; - int udp_encap_port = 46014 + index; - int max_tpdu = 1500; - int sqns = 100; - int port = 0; - struct pgm_sockaddr_t addr; - int blocking = 1; - int multicast_loop = 0; - int multicast_hops = 0; - int dscp, i; - - port = udp_encap_port; - - /* Use PGM */ - udp_encap_port = 0; - - LOG_D(EMU, "[PGM] Preparing socket for group %d and address %s\n", - index, if_addr); - - if (!pgm_getaddrinfo(if_addr, NULL, &res, &pgm_err)) { - LOG_E(EMU, "Parsing network parameter: %s\n", pgm_err->message); - goto err_abort; - } - - if (udp_encap_port) { - LOG_I(EMU, "[PGM] Creating PGM/UDP socket for encapsulated port %d\n", - udp_encap_port); - - if (!pgm_socket (&pgm_multicast_group[index].sock, sa_family, - SOCK_SEQPACKET, IPPROTO_UDP, &pgm_err)) { - LOG_E(EMU, "[PGM] Socket: %s\n", pgm_err->message); - goto err_abort; - } - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_UDP_ENCAP_UCAST_PORT, &udp_encap_port, - sizeof(udp_encap_port)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_UDP_ENCAP_MCAST_PORT, &udp_encap_port, - sizeof(udp_encap_port)); - } else { - LOG_I(EMU, "[PGM] Creating PGM/IP socket\n"); - - if (!pgm_socket(&pgm_multicast_group[index].sock, sa_family, - SOCK_SEQPACKET, IPPROTO_PGM, &pgm_err)) { - LOG_E(EMU, "Creating PGM/IP socket: %s\n", pgm_err->message); - goto err_abort; - } - } - - { - /* Use RFC 2113 tagging for PGM Router Assist */ - const int no_router_assist = 0; - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_IP_ROUTER_ALERT, &no_router_assist, - sizeof(no_router_assist)); - } - - // pgm_drop_superuser(); - - { - /* set PGM parameters */ - const int recv_only = 0, - passive = 0, - peer_expiry = pgm_secs (300), - spmr_expiry = pgm_msecs (250), - nak_bo_ivl = pgm_msecs (10), - nak_rpt_ivl = pgm_secs (2), - nak_rdata_ivl = pgm_secs (2), - nak_data_retries = 50, - nak_ncf_retries = 50, - ambient_spm = pgm_secs(30); - const int heartbeat_spm[] = { - pgm_msecs (100), - pgm_msecs (100), - pgm_msecs (100), - pgm_msecs (100), - pgm_msecs (1300), - pgm_secs (7), - pgm_secs (16), - pgm_secs (25), - pgm_secs (30) - }; - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_RECV_ONLY, &recv_only, sizeof(recv_only)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_PASSIVE, &passive, sizeof(passive)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_MTU, &max_tpdu, sizeof(max_tpdu)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_RXW_SQNS, &sqns, sizeof(sqns)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_PEER_EXPIRY, &peer_expiry, sizeof(peer_expiry)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_SPMR_EXPIRY, &spmr_expiry, sizeof(spmr_expiry)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_NAK_BO_IVL, &nak_bo_ivl, sizeof(nak_bo_ivl)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_NAK_RPT_IVL, &nak_rpt_ivl, sizeof(nak_rpt_ivl)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_NAK_RDATA_IVL, &nak_rdata_ivl, sizeof(nak_rdata_ivl)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_NAK_DATA_RETRIES, &nak_data_retries, sizeof(nak_data_retries)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_NAK_NCF_RETRIES, &nak_ncf_retries, sizeof(nak_ncf_retries)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_AMBIENT_SPM, &ambient_spm, sizeof(ambient_spm)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_HEARTBEAT_SPM, &heartbeat_spm, sizeof(heartbeat_spm)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_TXW_SQNS, &sqns, sizeof(sqns)); - } - - /* create global session identifier */ - memset (&addr, 0, sizeof(addr)); - /* sa_port should be in host byte order */ - addr.sa_port = port; - addr.sa_addr.sport = DEFAULT_DATA_SOURCE_PORT + index; - - if (!pgm_gsi_create_from_hostname(&addr.sa_addr.gsi, &pgm_err)) { - LOG_E(EMU, "[PGM] Creating GSI: %s\n", pgm_err->message); - goto err_abort; - } - - LOG_D(EMU, "[PGM] Created GSI %s\n", pgm_tsi_print(&addr.sa_addr)); - - /* assign socket to specified address */ - { - struct pgm_interface_req_t if_req; - memset (&if_req, 0, sizeof(if_req)); - if_req.ir_interface = res->ai_recv_addrs[0].gsr_interface; - if_req.ir_scope_id = 0; - - if (AF_INET6 == sa_family) { - struct sockaddr_in6 sa6; - memcpy (&sa6, &res->ai_recv_addrs[0].gsr_group, sizeof(sa6)); - if_req.ir_scope_id = sa6.sin6_scope_id; - } - - if (!pgm_bind3(pgm_multicast_group[index].sock, &addr, sizeof(addr), - &if_req, sizeof(if_req), /* tx interface */ - &if_req, sizeof(if_req), /* rx interface */ - &pgm_err)) { - LOG_E(EMU, "[PGM] Error: %s\n", pgm_err->message); - goto err_abort; - } - } - - /* join IP multicast groups */ - { - struct group_req req; - struct sockaddr_in addr_in; - - memset(&req, 0, sizeof(req)); - - /* Interface index */ - req.gr_interface = res->ai_recv_addrs[0].gsr_interface; - - addr_in.sin_family = AF_INET; - addr_in.sin_port = htons(port); - - for (i = 0; i < MULTICAST_LINK_NUM_GROUPS; i++) { - addr_in.sin_addr.s_addr = inet_addr(multicast_group_list[i]); - memcpy(&req.gr_group, &addr_in, sizeof(addr_in)); - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_JOIN_GROUP, &req, - sizeof(struct group_req)); - } - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_SEND_GROUP, &req, - sizeof(struct group_req)); - } - - pgm_freeaddrinfo(res); - res = NULL; - - /* set IP parameters */ - multicast_hops = 64; - dscp = 0x2e << 2; /* Expedited Forwarding PHB for network elements, no ECN. */ - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_MULTICAST_LOOP, &multicast_loop, sizeof(multicast_loop)); - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, - PGM_MULTICAST_HOPS, &multicast_hops, sizeof(multicast_hops)); - - if (AF_INET6 != sa_family) - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, PGM_TOS, - &dscp, sizeof(dscp)); - - pgm_setsockopt(pgm_multicast_group[index].sock, IPPROTO_PGM, PGM_NOBLOCK, - &blocking, sizeof(blocking)); - - if (!pgm_connect(pgm_multicast_group[index].sock, &pgm_err)) { - LOG_E(EMU, "[PGM] Connecting socket: %s\n", pgm_err->message); - goto err_abort; - } - - return 0; - -err_abort: - - if (NULL != pgm_multicast_group[index].sock) { - pgm_close(pgm_multicast_group[index].sock, FALSE); - pgm_multicast_group[index].sock = NULL; - } - - if (NULL != res) { - pgm_freeaddrinfo(res); - res = NULL; - } - - if (NULL != pgm_err) { - pgm_error_free(pgm_err); - pgm_err = NULL; - } - - exit(EXIT_FAILURE); -} - -#endif diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index 6a693085c9..25b3265757 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -39,14 +39,6 @@ int bypass_rx_data(unsigned int frame, unsigned int last_slot, unsigned int next_slot, uint8_t is_master); void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, unsigned int next_slot, uint8_t is_master); -#ifndef USER_MODE -int multicast_link_write_sock (int groupP, char *dataP, unsigned int sizeP); -int bypass_tx_handler(unsigned int fifo, int rw); -int bypass_rx_handler(unsigned int fifo, int rw); -#else -void bypass_rx_handler(unsigned int Num_bytes,char *Rx_buffer); -#endif - void bypass_tx_data (emu_transport_info_t Type, unsigned int frame, unsigned int next_slot); void emulation_tx_rx(void); diff --git a/openair1/SIMULATION/ETH_TRANSPORT/socket.c b/openair1/SIMULATION/ETH_TRANSPORT/socket.c index e288dcb378..2b28a66170 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/socket.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/socket.c @@ -41,9 +41,7 @@ //#include "openair_defs.h" #include "socket.h" -#ifdef USER_MODE #define msg printf -#endif //------------------------------------------------------------------------------ void socket_setnonblocking (int sockP) diff --git a/openair1/SIMULATION/ETH_TRANSPORT/vars.h b/openair1/SIMULATION/ETH_TRANSPORT/vars.h index 0ec38a8e90..f49678642e 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/vars.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/vars.h @@ -28,11 +28,7 @@ * \email: navid.nikaein@eurecom.fr */ -#ifndef USER_MODE -#include -#else #include -#endif #include "defs.h" #ifndef __BYPASS_SESSION_LAYER_VARS_H__ diff --git a/openair1/SIMULATION/LTE_PHY/Makefile b/openair1/SIMULATION/LTE_PHY/Makefile deleted file mode 100644 index 713bfba370..0000000000 --- a/openair1/SIMULATION/LTE_PHY/Makefile +++ /dev/null @@ -1,202 +0,0 @@ -include $(OPENAIR_DIR)/common/utils/Makefile.inc - -COMMON_UTILS_DIR = $(OPENAIR_DIR)/common/utils -TOP_DIR = $(OPENAIR1_DIR) -OPENAIR1_TOP = $(OPENAIR1_DIR) -OPENAIR2_TOP = $(OPENAIR2_DIR) -OPENAIR3 = $(OPENAIR3_DIR) - -CFLAGS += -DMAX_NUM_CCs=1 -Wall -DPHYSIM -DNODE_RG -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DPHY_CONTEXT=1 -DMALLOC_CHECK_=1 -DENABLE_VCD_FIFO -DLOG_NO_THREAD # -Wno-packed-bitfield-compat - -# enable C99 mode -CFLAGS += -std=gnu99 - -# DCI Debug -# CFLAGS += -DDEBUG_DCI_ENCODING -# TODO: only for framegen -#CFLAGS += -DOPENAIR2 -#CFLAGS += -DDEBUG_PHY_PROC -#CFLAGS += -DDEBUG_GROUPHOP - -ifdef OMP -CFLAGS += -DOMP -fopenmp -endif -ifdef LLR8 -CFLAGS += -DLLR8 -endif -CFLAGS += -DNEW_FFT - -LFLAGS = -lm -lblas -lxml2 -lrt -lpthread $(LFDS_DIR)/bin/liblfds611.a - -ifdef GPIB -LFLAGS += -lgpib -endif - -CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH #-DIFFT_FPGA -DIFFT_FPGA_UE -#CFLAGS += -DTBS_FIX -CFLAGS += -DCELLULAR - -ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES - -ifdef EMOS -CFLAGS += -DEMOS -endif - -ifdef DEBUG_PHY -CFLAGS += -DDEBUG_PHY -endif - -ifdef MeNBMUE -CFLAGS += -DMeNBMUE -endif - -ifdef MU_RECEIVER -CFLAGS += -DMU_RECEIVER -endif - -ifdef ZBF_ENABLED -CFLAGS += -DNULL_SHAPE_BF_ENABLED -endif - -ifdef RANDOM_BF -CFLAGS += -DRANDOM_BF -endif - -ifdef PBS_SIM -CFLAGS += -DPBS_SIM -endif - -ifdef XFORMS -CFLAGS += -DXFORMS -LFLAGS += -lforms -endif - -ifdef SMBV -CFLAGS += -DSMBV -endif - -ifdef PERFECT_CE -CFLAGS += -DPERFECT_CE -endif - -ifdef BIT8_TX -CFLAGS += -DBIT8_TX -endif - -CFLAGS += -DNO_RRM -DOPENAIR1 -DPHY_ABSTRACTION #-DOPENAIR2 - -CFLAGS += -I/usr/include/X11 -I/usr/X11R6/include - -ifdef RTAI -CFLAGS += -DRTAI_ENABLED -D__IN_RTAI__ $(shell rtai-config --lxrt-cflags) -LFLAGS += $(shell rtai-config --lxrt-ldflags) -llxrt -endif - -include $(COMMON_UTILS_DIR)/Makefile.inc -include $(TOP_DIR)/PHY/Makefile.inc -include $(TOP_DIR)/SCHED/Makefile.inc -include $(TOP_DIR)/SIMULATION/Makefile.inc -include $(OPENAIR2_DIR)/LAYER2/Makefile.inc -include $(OPENAIR2_DIR)/UTIL/Makefile.inc -include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc - -#LOG_OBJS += $(LOG_DIR)/vcd_signal_dumper.o - -CFLAGS += $(L2_incl) -I$(ASN1_MSG_INC) -I$(TOP_DIR) -I$(OPENAIR2_DIR) -I$(OPENAIR3) $(UTIL_incl) $(UTILS_incl) -# EXTRA_CFLAGS = - -#STATS_OBJS += $(TOP_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER/cbmimo1_proc.o - -#LAYER2_OBJ += $(OPENAIR2_DIR)/LAYER2/MAC/rar_tools.o -#LAYER2_OBJ = $(OPENAIR2_DIR)/LAYER2/MAC/lte_transport_init.o - -OBJ = $(PHY_OBJS) $(SIMULATION_OBJS) $(TOOLS_OBJS) $(SCHED_OBJS) $(LAYER2_OBJ) $(LOG_OBJS) $(ITTI_DIR)/backtrace.o -ifdef GPIB -OBJ += LTE_Configuration.o -endif -#OBJ2 = $(PHY_OBJS) $(SIMULATION_OBJS) $(TOOLS_OBJS) - -ifdef XFORMS -OBJ += $(OPENAIR1_DIR)/PHY/TOOLS/lte_phy_scope.o -endif - -ifdef STATIC -LFLAGS += -static -L/usr/lib/libblas -endif - -all: dlsim pbchsim pdcchsim ulsim pucchsim prachsim mbmssim scansim - -$(LFDS_DIR)/bin/liblfds611.a: - $(MAKE) -C $(LFDS_DIR) -f makefile.linux - -test: $(SIMULATION_OBJS) $(TOOLS_OBJS) $(TOP_DIR)/PHY/INIT/lte_init.o test.c - $(CC) test.c -I$(TOP_DIR) -o test $(CFLAGS) $(SIMULATION_OBJS) $(TOOLS_OBJS) -lm - -OBJ += $(LIST_OBJ) -OBJ += $(MEM_OBJ) -$(OBJ) : %.o : %.c - @echo Compiling $< ... - @$(CC) -c $(CFLAGS) -o $@ $< - -dlsim : $(OBJ) dlsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling dlsim.c ..." - @$(CC) dlsim.c -o dlsim $(CFLAGS) $(OBJ) $(LFLAGS) - -dlsim2 : $(OBJ) dlsim2.c - @echo "Compiling dlsim2.c ..." - @$(CC) dlsim2.c -o dlsim2 $(CFLAGS) $(OBJ) $(LFLAGS) - -framegen: $(OBJ) framegen.c - @echo "Compiling framegen.c" - @$(CC) framegen.c -o framegen $(CFLAGS) $(OBJ) $(LFLAGS) - -pbchsim : $(OBJ) pbchsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling pbchsim.c" - @$(CC) pbchsim.c -o pbchsim $(CFLAGS) $(OBJ) $(LFLAGS) - -scansim : $(OBJ) scansim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling scansim.c" - @$(CC) scansim.c -o scansim $(CFLAGS) $(OBJ) $(LFLAGS) - -mbmssim : $(OBJ) mbmssim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling mbmssim.c" - @$(CC) mbmssim.c -o mbmssim $(CFLAGS) $(OBJ) $(LFLAGS) - -pdcchsim : $(OBJ) pdcchsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling pdcchsim.c" - @$(CC) pdcchsim.c -o pdcchsim $(CFLAGS) $(OBJ) $(LFLAGS) - -pucchsim : $(OBJ) pucchsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling pucchsim.c" - @$(CC) pucchsim.c -o pucchsim $(CFLAGS) $(OBJ) $(LFLAGS) - -prachsim : $(OBJ) prachsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling prachsim.c" - @$(CC) prachsim.c -o prachsim $(CFLAGS) $(OBJ) $(LFLAGS) - -ulsim : $(OBJ) ulsim.c $(LFDS_DIR)/bin/liblfds611.a #ulsim_form.c - @echo "Compiling [ulsim.c]" - @$(CC) ulsim.c -o ulsim $(CFLAGS) $(OBJ) $(LFLAGS) - -syncsim : $(OBJ) syncsim.c $(LFDS_DIR)/bin/liblfds611.a - @echo "Compiling syncsim.c" - @$(CC) syncsim.c -o syncsim $(CFLAGS) $(OBJ) $(LFLAGS) - -clean : - rm -f $(OBJ) - rm -f *.o - -cleanall : clean - rm -f dlsim pbchsim pdcchsim ulsim pucchsim mbmssim prachsim - rm -f *.exe* - -showflags : - @echo $(CFLAGS) - @echo $(LFLAGS) - -showobj: - @echo $(SCHED_OBJS) - -cppcheck: - @echo "cppcheck ..." - cppcheck $(INCLUDES) ${OBJ:.o=.c} ${OAISIM_OBJS,.o=.c} ${ASN1_RRC_MSG_OBJS1,.o=.c} diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index 773ec57a3e..fbe75fed16 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -31,9 +31,6 @@ #include "PHY/types.h" #include "PHY/defs.h" #include "PHY/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c index e240f88ce6..d1e25da5c3 100644 --- a/openair1/SIMULATION/LTE_PHY/pbchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c @@ -32,9 +32,6 @@ #include "PHY/defs.h" #include "PHY/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" @@ -91,9 +88,6 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0; int8_t interf1=-21,interf2=-21; LTE_DL_FRAME_PARMS *frame_parms; -#ifdef EMOS - fifo_dump_emos emos_dump; -#endif FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 71e2f88172..ef0e221491 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -28,9 +28,6 @@ #include "PHY/defs.h" #include "PHY/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index cab2ecb8fb..58f89bd65b 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -27,9 +27,6 @@ #include "PHY/types.h" #include "PHY/defs.h" #include "PHY/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" @@ -76,10 +73,6 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0; // int8_t interf1=-19,interf2=-19; LTE_DL_FRAME_PARMS *frame_parms; -#ifdef EMOS - fifo_dump_emos emos_dump; -#endif - SCM_t channel_model=Rayleigh1; diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index 1e5f47e59e..d49367c4db 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -27,9 +27,6 @@ #include "PHY/types.h" #include "PHY/defs.h" #include "PHY/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" @@ -77,9 +74,6 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0; LTE_DL_FRAME_PARMS *frame_parms; -#ifdef EMOS - fifo_dump_emos emos_dump; -#endif SCM_t channel_model=Rayleigh1_corr; diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c index 94bc991e3f..69aee01b32 100644 --- a/openair1/SIMULATION/LTE_PHY/scansim.c +++ b/openair1/SIMULATION/LTE_PHY/scansim.c @@ -33,9 +33,6 @@ #include "PHY/vars.h" #include "MAC_INTERFACE/vars.h" -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" @@ -91,9 +88,6 @@ int main(int argc, char **argv) uint32_t nsymb,tx_lev,tx_lev1,tx_lev2; uint8_t extended_prefix_flag=0; LTE_DL_FRAME_PARMS *frame_parms; -#ifdef EMOS - fifo_dump_emos emos_dump; -#endif FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index acad27ca11..e491944ccf 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -30,11 +30,6 @@ #include #include -#ifdef RTAI_ENABLED -#include -#include -#endif - #include "SIMULATION/TOOLS/defs.h" #include "SIMULATION/RF/defs.h" #include "PHY/types.h" @@ -44,9 +39,6 @@ #ifdef IFFT_FPGA #include "PHY/LTE_REFSIG/mod_table.h" #endif -#ifdef EMOS -#include "SCHED/phy_procedures_emos.h" -#endif #include "SCHED/defs.h" #include "SCHED/vars.h" #include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h" @@ -381,9 +373,6 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0,frame_type=1; int8_t interf1=-21,interf2=-21; LTE_DL_FRAME_PARMS *frame_parms; -#ifdef EMOS - fifo_dump_emos emos_dump; -#endif FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; @@ -430,13 +419,6 @@ int main(int argc, char **argv) int rx_offset_mod; -#ifdef RTAI_ENABLED - int period; - RTIME expected; - RT_TASK *task; -#define PERIOD 1000000000 -#endif - logInit(); number_of_cards = 1; @@ -694,23 +676,6 @@ int main(int argc, char **argv) } } -#ifdef RTAI_ENABLED - - if (!(task = rt_task_init_schmod(nam2num("SYNCSIM"), 0, 0, 0, SCHED_FIFO, 0xF))) { - printf("CANNOT INIT MASTER TASK\n"); - exit(1); - } - - rt_set_periodic_mode(); - - period = start_rt_timer(nano2count(PERIOD)); - - mlockall(MCL_CURRENT | MCL_FUTURE); - - rt_make_hard_real_time(); - rt_task_make_periodic(task, expected = rt_get_time() + 10*period, period); -#endif - #ifdef XFORMS if (do_forms==1) { @@ -1374,11 +1339,6 @@ int main(int argc, char **argv) for (trial=0; trial1) sigma2_dB = atoi(argv[1]); diff --git a/openair1/SIMULATION/RF/Makefile b/openair1/SIMULATION/RF/Makefile index 5b713b1d94..c6c03ad8d5 100644 --- a/openair1/SIMULATION/RF/Makefile +++ b/openair1/SIMULATION/RF/Makefile @@ -1,6 +1,6 @@ include $(OPENAIR_DIR)/common/utils/Makefile.inc OBJS = rf.o ../../PHY/TOOLS/file_output.o ../TOOLS/rangen_double.o -CFLAGS += -DRF_MAIN -DUSER_MODE -DDEBUG_PHY +CFLAGS += -DRF_MAIN -DDEBUG_PHY all: $(OBJS) gcc -o rf $(OBJS) -lm diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 5168a64ef4..0fc01a8d31 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -19,12 +19,10 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include #include #include #include -#endif #include "defs.h" diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index a86be23aec..0be7952da7 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -19,18 +19,8 @@ * contact@openairinterface.org */ -#ifdef USER_MODE #include #include -#else -#include -#include -#endif -#ifdef RTAI_ENABLED -#include -#include -#define time(x) (unsigned int)(rt_get_time_ns()) -#endif unsigned int s0, s1, s2, b; @@ -55,21 +45,14 @@ unsigned int taus(void) void set_taus_seed(unsigned int seed_init) { -#ifdef USER_MODE struct drand48_data buffer; unsigned long result = 0; -#endif if (seed_init == 0) { s0 = (unsigned int)time(NULL); s1 = (unsigned int)time(NULL); s2 = (unsigned int)time(NULL); } else { -#ifndef USER_MODE - s0 = (unsigned int)0x1e23d852; - s1 = (unsigned int)0x81f38a1c; - s2 = (unsigned int)0xfe1a133e; -#else /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ srand48_r((long int)seed_init, &buffer); mrand48_r(&buffer, (long int *)&result); @@ -78,7 +61,6 @@ void set_taus_seed(unsigned int seed_init) s1 = result; mrand48_r(&buffer, (long int *)&result); s2 = result; -#endif } } #endif @@ -87,10 +69,8 @@ void set_taus_seed(unsigned int seed_init) void set_taus_seed(unsigned int seed_init) { -#ifdef USER_MODE struct drand48_data buffer; unsigned long result = 0; -#endif s0 = (unsigned int)0x1e23d852; s1 = (unsigned int)0x81f38a1c; s2 = (unsigned int)0xfe1a133e; @@ -102,11 +82,6 @@ void set_taus_seed(unsigned int seed_init) s1 = (unsigned int)time(NULL); s2 = (unsigned int)time(NULL); } else { -#ifndef USER_MODE - s0 = (unsigned int)0x1e23d852; - s1 = (unsigned int)0x81f38a1c; - s2 = (unsigned int)0xfe1a133e; -#else // Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ srand48_r((long int)seed_init, &buffer); mrand48_r(&buffer, (long int *)&result); @@ -115,7 +90,6 @@ void set_taus_seed(unsigned int seed_init) s1 = result; mrand48_r(&buffer, (long int *)&result); s2 = result; -#endif } } #endif diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index 8df0970ba0..3a73000e50 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -244,9 +244,7 @@ typedef struct { LCHAN_DESC Lchan_desc[2]; /*!< \brief Logical Channel QoS Descriptor (MAC component) */ uint8_t L3_info_type; uint8_t L3_info[16]; - //#ifndef CELLULAR unsigned short UE_eNB_index; - //#endif } __attribute__ ((__packed__)) MAC_CONFIG_REQ; #define MAC_CONFIG_REQ_SIZE sizeof(MAC_CONFIG_REQ) @@ -314,18 +312,12 @@ typedef struct { #ifndef OPENAIR2_IN -#ifndef CELLULAR -//#include "L3_rrc_defs.h" -#endif - typedef struct { //RRC_INTERFACE_FUNCTIONS unsigned int Frame_index; unsigned short UE_index[NB_MODULES_MAX][NB_SIG_CNX_UE]; uint8_t eNB_id[NB_MODULES_MAX][NB_CNX_UE]; -#ifndef CELLULAR // L2_ID UE_id[NB_MODULES_MAX][NB_CNX_CH]; uint8_t UE_id[NB_MODULES_MAX][NB_CNX_CH][5]; -#endif void (*openair_rrc_top_init)(void); char (*openair_rrc_eNB_init)(uint8_t ); char (*openair_rrc_UE_init)(uint8_t, uint8_t); diff --git a/openair2/COMMON/openair_defs.h b/openair2/COMMON/openair_defs.h index 908f8f9813..4d8d50606c 100644 --- a/openair2/COMMON/openair_defs.h +++ b/openair2/COMMON/openair_defs.h @@ -22,12 +22,6 @@ #ifndef __openair_DEFS_H__ #define __openair_DEFS_H__ -#ifndef USER_MODE -#include -#endif //USER_MODE - - -#ifdef USER_MODE #include #include #if !defined (msg) @@ -49,44 +43,7 @@ #define PAGE_MASK 0xfffff000 #define virt_to_phys(x) (x) -#else // USER_MODE -#include -#define msg rt_printk - -#ifdef BIGPHYSAREA - -#define bigmalloc(x) (bigphys_malloc(x)) -#define bigmalloc16(x) (bigphys_malloc(x)) - -#define malloc16(x) (bigphys_malloc(x)) -#define free16(y,x) - -#define bigfree(y,x) - -#else // BIGPHYSAREA - -#define bigmalloc(x) (dma_alloc_coherent(pdev[0],(x),&dummy_dma_ptr,0)) -#define bigmalloc16(x) (dma_alloc_coherent(pdev[0],(x),&dummy_dma_ptr,0)) -#define bigfree(y,x) (dma_free_coherent(pdev[0],(x),(void *)(y),dummy_dma_ptr)) -#define malloc16(x) (kmalloc(x,GFP_KERNEL)) -#define free16(y,x) (kfree(y)) - -#endif // BIGPHYSAREA - - -#ifdef CBMIMO1 -#define openair_get_mbox() (*(unsigned int *)mbox) -#else //CBMIMO1 -#define openair_get_mbox() (*(unsigned int *)PHY_vars->mbox>>1) -#endif //CBMIMO1 - - -#endif // USERMODE - -// #define bzero(s,n) (memset((s),0,(n))) - #define cmax(a,b) ((a>b) ? (a) : (b)) #define cmin(a,b) ((a -//typedef int8_t s8; /* 8 bit signed integer */ -//typedef int16_t s16; /* 16 bit signed integer */ -//typedef int32_t s32; /* 32 bit signed integer */ -//typedef int64_t s64; /* 64 bit signed integer */ - -//typedef uint8_t u8; /* 8 bit unsigned integer */ -//typedef uint16_t u16; /* 16 bit unsigned integer */ -//typedef uint32_t u32; /* 32 bit unsigned integer */ -//typedef uint64_t u64; /* 64 bit unsigned integer */ -//#else -//#include -//#endif -#endif /*__openair_TYPES_H__ */ diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 533c5eaa2b..f4004bdbf9 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -43,7 +43,6 @@ #define NL_MAX_PAYLOAD 9000 /* this should cover the max mtu size*/ #endif -#ifdef USER_MODE #ifdef LARGE_SCALE # define NB_MODULES_MAX 128 # define NB_NODE_MAX 128 @@ -51,11 +50,6 @@ # define NB_MODULES_MAX 32 # define NB_NODE_MAX 32 #endif -#else -# define NB_MODULES_MAX 1 -# define NB_NODE_MAX 1 -#endif //PHY_EMUL - #ifdef JUMBO_FRAME # define MAX_IP_PACKET_SIZE 10000 // 9000 @@ -132,9 +126,7 @@ #define UNUSED_PARAM_MBMS_SESSION_ID 0 #define UNUSED_PARAM_MBMS_SERVICE_ID 0 -#ifdef USER_MODE #define printk printf -#endif #define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 1ea2550adc..17ce7fba2f 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -30,7 +30,7 @@ #ifndef __PLATFORM_TYPES_H__ # define __PLATFORM_TYPES_H__ -#ifdef USER_MODE +#if !defined(NAS_NETLINK) #include #endif @@ -275,29 +275,5 @@ typedef struct protocol_ctxt_s { (CTXT_Pp)->module_id, \ (CTXT_Pp)->rnti -#ifdef OAI_EMU -#define CHECK_CTXT_ARGS(CTXT_Pp) \ - if ((CTXT_Pp)->enb_flag) {\ - AssertFatal (((CTXT_Pp)->module_id >= oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),\ - "eNB module id is too low (%u/%d/%d)!\n",\ - (CTXT_Pp)->module_id,\ - oai_emulation.info.first_enb_local,\ - oai_emulation.info.nb_enb_local);\ - AssertFatal (((CTXT_Pp)->module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.nb_enb_local > 0),\ - "eNB module id is too high (%u/%d)!\n",\ - (CTXT_Pp)->module_id,\ - oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);\ - } else {\ - AssertFatal ((CTXT_Pp)->module_id < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),\ - "UE module id is too high (%u/%d)!\n",\ - (CTXT_Pp)->module_id,\ - oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);\ - AssertFatal ((CTXT_Pp)->module_id >= oai_emulation.info.first_ue_local,\ - "UE module id is too low (%u/%d)!\n",\ - (CTXT_Pp)->module_id,\ - oai_emulation.info.first_ue_local);\ - } -#else #define CHECK_CTXT_ARGS(CTXT_Pp) #endif -#endif diff --git a/openair2/COMMON/rtos_header.h b/openair2/COMMON/rtos_header.h index 63bc57d942..05fc33463d 100644 --- a/openair2/COMMON/rtos_header.h +++ b/openair2/COMMON/rtos_header.h @@ -20,45 +20,13 @@ */ #ifndef _RTOS_HEADER_H_ -# define _RTOS_HEADER_H_ -# if defined(RTAI) && !defined(USER_MODE) -// CONVERSION BETWEEN POSIX PTHREAD AND RTAI FUNCTIONS -/* -# define pthread_mutex_init pthread_mutex_init_rt -# define pthread_mutexattr_init pthread_mutexattr_init_rt -# define pthread_mutex_lock pthread_mutex_lock_rt -# define pthread_mutex_unlock pthread_mutex_unlock_rt -# define pthread_mutex_destroy pthread_mutex_destroy_rt -# define pthread_cond_init pthread_cond_init_rt -# define pthread_cond_wait pthread_cond_wait_rt -# define pthread_cond_signal pthread_cond_signal_rt -# define pthread_cond_destroy pthread_cond_destroy_rt -# define pthread_attr_init pthread_attr_init_rt -# define pthread_attr_setschedparam pthread_attr_setschedparam_rt -# define pthread_create pthread_create_rt -# define pthread_cancel pthread_cancel_rt -# define pthread_delete_np pthread_cancel_rt -# define pthread_attr_setstacksize pthread_attr_setstacksize_rt -# define pthread_self rt_whoami -*/ -# include -# include -# include -# include -# include -# ifdef CONFIG_PROC_FS -# include -# endif -# else -# ifdef USER_MODE -# include -# include -# include -# include -# include -# include -# define rtf_get read -# define rtf_put write -# endif -# endif +#define _RTOS_HEADER_H_ +#include +#include +#include +#include +#include +#include +#define rtf_get read +#define rtf_put write #endif diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index a163b031c9..ca404ddc23 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -36,10 +36,6 @@ #include "common/ran_context.h" #include "log.h" -#if defined(OAI_EMU) -# include "OCG.h" -# include "OCG_extern.h" -#endif #if defined(ENABLE_ITTI) # include "intertask_interface.h" @@ -215,9 +211,6 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, uint32_t register_enb_pending = 0; for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { -# if defined(OAI_EMU) - if (oai_emulation.info.cli_start_enb[enb_id] == 1) -# endif { s1ap_register_enb_req_t *s1ap_register_eNB; @@ -304,25 +297,16 @@ void *eNB_app_task(void *args_p) itti_mark_task_ready (TASK_ENB_APP); + LOG_I(PHY, "%s() Task ready initialise structures\n", __FUNCTION__); + RCconfig_L1(); RCconfig_macrlc(); + LOG_I(PHY, "%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst); + if (RC.nb_L1_inst>0) AssertFatal(l1_north_init_eNB()==0,"could not initialize L1 north interface\n"); - # if defined(ENABLE_ITTI) -# if defined(OAI_EMU) - enb_nb = oai_emulation.info.nb_enb_local; - enb_id_start = oai_emulation.info.first_enb_local; - enb_id_end = oai_emulation.info.first_enb_local + enb_nb; - - AssertFatal (enb_id_end <= NUMBER_OF_eNB_MAX, - "Last eNB index is greater or equal to maximum eNB index (%d/%d)!", - enb_id_end, NUMBER_OF_eNB_MAX); -# endif - # endif - - AssertFatal (enb_nb <= RC.nb_inst, "Number of eNB is greater than eNB defined in configuration file (%d/%d)!", enb_nb, RC.nb_inst); @@ -330,9 +314,11 @@ void *eNB_app_task(void *args_p) LOG_I(ENB_APP,"Allocating eNB_RRC_INST for %d instances\n",RC.nb_inst); RC.rrc = (eNB_RRC_INST **)malloc(RC.nb_inst*sizeof(eNB_RRC_INST *)); + LOG_I(PHY, "%s() RC.nb_inst:%d RC.rrc:%p\n", __FUNCTION__, RC.nb_inst, RC.rrc); for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { RC.rrc[enb_id] = (eNB_RRC_INST*)malloc(sizeof(eNB_RRC_INST)); + LOG_I(PHY, "%s() Creating RRC instance RC.rrc[%d]:%p (%d of %d)\n", __FUNCTION__, enb_id, RC.rrc[enb_id], enb_id+1, enb_id_end); memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST)); configure_rrc(enb_id); } @@ -396,16 +382,6 @@ void *eNB_app_task(void *args_p) msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); -# if defined(OAI_EMU) - - /* Also inform all NAS UE tasks */ - for (instance = NB_eNB_INST + oai_emulation.info.first_ue_local; - instance < (NB_eNB_INST + oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local); instance ++) { - msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, instance, msg_init_p); - } - -# endif } else { uint32_t not_associated = enb_nb - registered_enb; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 8d1756d685..09e00a8f6b 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -36,10 +36,6 @@ #include "enb_config.h" #include "UTIL/OTG/otg.h" #include "UTIL/OTG/otg_externs.h" -#if defined(OAI_EMU) -# include "OCG.h" -# include "OCG_extern.h" -#endif #if defined(ENABLE_ITTI) # include "intertask_interface.h" # if defined(ENABLE_USE_MME) @@ -50,15 +46,16 @@ #include "sctp_default_values.h" #include "SystemInformationBlockType2.h" #include "LAYER2/MAC/extern.h" +#include "LAYER2/MAC/proto.h" #include "PHY/extern.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "nfapi_vnf.h" +#include "nfapi_pnf.h" + #include "enb_paramdef.h" #include "common/config/config_userapi.h" - -int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc); -int RCconfig_S1(MessageDef *msg_p, uint32_t i); - +extern uint16_t sf_ahead; static int enb_check_band_frequencies(char* lib_config_file_name_pP, int ind, @@ -102,11 +99,6 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP, } - - - - - /* --------------------------------------------------------*/ /* from here function to use configuration module */ void RCconfig_RU(void) { @@ -124,7 +116,6 @@ void RCconfig_RU(void) { if ( RUParamList.numelt > 0) { - RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*)); @@ -139,6 +130,8 @@ void RCconfig_RU(void) { memset((void*)RC.ru[j],0,sizeof(RU_t)); RC.ru[j]->idx = j; + printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); + RC.ru[j]->if_timing = synch_to_ext_device; if (RC.nb_L1_inst >0) RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; @@ -237,48 +230,47 @@ void RCconfig_RU(void) { } -void RCconfig_L1() { +void RCconfig_L1(void) { int i,j; paramdef_t L1_Params[] = L1PARAMS_DESC; paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0}; - config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); - if (L1_ParamList.numelt > 0) { + if (RC.eNB == NULL) { + RC.eNB = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB**)); + LOG_I(PHY,"RC.eNB = %p\n",RC.eNB); + memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB**)); + RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); + } - if (RC.eNB == NULL) { - RC.eNB = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); - LOG_I(PHY,"RC.eNB = %p\n",RC.eNB); - memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***)); - RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); - } + config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL); + if (L1_ParamList.numelt > 0) { for (j = 0; j < RC.nb_L1_inst; j++) { RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); - if (RC.eNB[j] == NULL) { - RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB*)); LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); - memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB*)); } - for (i=0;iMod_id = j; - RC.eNB[j][i]->CC_id = i; - } + if (RC.eNB[j][i] == NULL) { + RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB)); + memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB)); + LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]); + RC.eNB[j][i]->Mod_id = j; + RC.eNB[j][i]->CC_id = i; + } } if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + sf_ahead = 4; // Need 4 subframe gap between RX and TX } else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { - RC.eNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + RC.eNB[j][0]->eth_params_n.local_if_name = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); RC.eNB[j][0]->eth_params_n.my_addr = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); RC.eNB[j][0]->eth_params_n.remote_addr = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); RC.eNB[j][0]->eth_params_n.my_portc = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); @@ -286,8 +278,25 @@ void RCconfig_L1() { RC.eNB[j][0]->eth_params_n.my_portd = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); RC.eNB[j][0]->eth_params_n.remote_portd = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); RC.eNB[j][0]->eth_params_n.transp_preference = ETH_UDP_MODE; + + sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + + RC.nb_macrlc_inst = 1; // This is used by mac_top_init_eNB() + + // This is used by init_eNB_afterRU() + RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int)); + RC.nb_CC[0]=1; + + RC.nb_inst =1; // DJP - feptx_prec uses num_eNB but phy_init_RU uses nb_inst + + LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_inst=1 this is because phy_init_RU() uses that to index and not RC.num_eNB - why the 2 similar variables?\n", __FUNCTION__); + LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]); + LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst); + + mac_top_init_eNB(); + + configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd); } - else { // other midhaul } }// j=0..num_inst @@ -295,6 +304,30 @@ void RCconfig_L1() { l1_north_init_eNB(); } else { LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found"); + + // DJP need to create some structures for VNF + + j = 0; + + RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); // DJP - 1 lot then??? + + RC.nb_L1_CC[j]=1; // DJP - hmmm + + if (RC.eNB[j] == NULL) { + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**)); + LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); + memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***)); + } + + for (i=0;iMod_id = j; + RC.eNB[j][i]->CC_id = i; + } + } } } @@ -307,7 +340,6 @@ void RCconfig_macrlc() { config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); - if ( MacRLC_ParamList.numelt > 0) { RC.nb_macrlc_inst=MacRLC_ParamList.numelt; @@ -342,6 +374,12 @@ void RCconfig_macrlc() { RC.mac[j]->eth_params_s.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); RC.mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + + sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 + + printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); + configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc); + printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); } else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } @@ -424,7 +462,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t rach_powerRampingStep = 0; int32_t rach_preambleInitialReceivedTargetPower = 0; int32_t rach_preambleTransMax = 0; - int32_t rach_raResponseWindowSize = 0; + int32_t rach_raResponseWindowSize = 10; int32_t rach_macContentionResolutionTimer = 0; int32_t rach_maxHARQ_Msg3Tx = 0; int32_t pcch_defaultPagingCycle = 0; diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 764c762f6a..1aa3a85636 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -58,6 +58,12 @@ #endif extern RAN_CONTEXT_t RC; +extern int l2_init_eNB(void); +extern void mac_top_init_eNB(void); +extern void mac_init_cell_params(int Mod_idP,int CC_idP); +extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); + +extern uint8_t nfapi_mode; /* sec 5.9, 36.321: MAC Reset Procedure */ void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) @@ -212,51 +218,115 @@ int32_t get_uldl_offset(int eutra_bandP) return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); } -uint32_t bw_table[6] = - { 6 * 180, 15 * 180, 25 * 180, 50 * 180, 75 * 180, 100 * 180 }; +uint32_t bw_table[6] = {6*180,15*180,25*180,50*180,75*180,100*180}; -void -config_mib(int Mod_idP, - int CC_idP, - int eutra_bandP, - int dl_BandwidthP, - PHICH_Config_t * phich_configP, - int Nid_cellP, - int NcpP, - int p_eNBP, - uint32_t dl_CarrierFreqP, - uint32_t ul_CarrierFreqP, uint32_t pbch_repetitionP) -{ +void config_mib(int Mod_idP, + int CC_idP, + int eutra_bandP, + int dl_BandwidthP, + PHICH_Config_t *phich_configP, + int Nid_cellP, + int NcpP, + int p_eNBP, + uint32_t dl_CarrierFreqP, + uint32_t ul_CarrierFreqP, + uint32_t pbch_repetitionP) { - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB - cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; - cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; + cfg->num_tlv=0; + + cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB + cfg->subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; + cfg->num_tlv++; - LOG_I(MAC, "Ncp %d,p_eNB %d\n", NcpP, p_eNBP); + cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; + cfg->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + cfg->num_tlv++; - cfg->rf_config.dl_channel_bandwidth.value = dl_BandwidthP; - cfg->rf_config.ul_channel_bandwidth.value = dl_BandwidthP; - cfg->rf_config.tx_antenna_ports.value = p_eNBP; - cfg->rf_config.rx_antenna_ports.value = 2; + cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; + cfg->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + cfg->num_tlv++; + + cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); + cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + cfg->num_tlv++; +LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); - cfg->nfapi_config.earfcn.value = - to_earfcn(eutra_bandP, dl_CarrierFreqP, - bw_table[dl_BandwidthP] / 100); - cfg->nfapi_config.rf_bands.number_rf_bands = 1; - cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; - cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; - cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; - cfg->phich_config.phich_power_offset.value = 6000; // 0dB + cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); + cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + cfg->num_tlv++; - cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB - cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB - cfg->sch_config.physical_cell_id.value = Nid_cellP; + cfg->rf_config.tx_antenna_ports.value = p_eNBP; + cfg->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + cfg->num_tlv++; + + cfg->rf_config.rx_antenna_ports.value = 2; + cfg->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + cfg->num_tlv++; + + cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); + cfg->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + cfg->num_tlv++; + + cfg->nfapi_config.rf_bands.number_rf_bands = 1; + cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; + cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + cfg->num_tlv++; + + cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; + cfg->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + cfg->num_tlv++; + + cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; + cfg->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + cfg->num_tlv++; + + cfg->phich_config.phich_power_offset.value = 6000; // 0dB + cfg->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + cfg->num_tlv++; + + cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB + cfg->sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + cfg->num_tlv++; + + cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB + cfg->sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + cfg->num_tlv++; + + cfg->sch_config.physical_cell_id.value = Nid_cellP; + cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + cfg->num_tlv++; #ifdef Rel14 - cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; -#endif + cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; + cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; + cfg->num_tlv++; +#endif + + LOG_I(MAC, + "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" +#ifdef Rel14 + " PBCH repetition %d" +#endif + "\n" + ,__FUNCTION__ + ,cfg->num_tlv + ,cfg->rf_config.dl_channel_bandwidth.value + ,cfg->rf_config.ul_channel_bandwidth.value + ,NcpP,p_eNBP + ,cfg->nfapi_config.earfcn.value + ,cfg->nfapi_config.rf_bands.rf_band[0] + ,cfg->phich_config.phich_resource.value + ,cfg->phich_config.phich_duration.value + ,cfg->phich_config.phich_power_offset.value + ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.physical_cell_id.value +#ifdef Rel14 + ,cfg->emtc_config.pbch_repetitions_enable_r13.value +#endif + ); } void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP) @@ -264,18 +334,25 @@ void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP) nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - if (tdd_ConfigP) { //TDD - cfg->subframe_config.duplex_mode.value = 0; - cfg->tdd_frame_structure_config.subframe_assignment.value = - tdd_ConfigP->subframeAssignment; - cfg->tdd_frame_structure_config.special_subframe_patterns.value = - tdd_ConfigP->specialSubframePatterns; - } else { // FDD - cfg->subframe_config.duplex_mode.value = 1; - // Note no half-duplex here - } + if (tdd_ConfigP) { //TDD + cfg->subframe_config.duplex_mode.value = 0; + cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + cfg->num_tlv++; + cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment; + cfg->tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; + cfg->num_tlv++; + cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns; + cfg->tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; + cfg->num_tlv++; + } + else { // FDD + cfg->subframe_config.duplex_mode.value = 1; + cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + cfg->num_tlv++; + // Note no half-duplex here + } } int power_off_dB[6] = { 78, 118, 140, 170, 188, 200 }; @@ -287,248 +364,326 @@ config_sib2(int Mod_idP, #ifdef Rel14 RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP, #endif - ARFCN_ValueEUTRA_t * ul_CArrierFreqP, - long *ul_BandwidthP, - AdditionalSpectrumEmission_t * - additionalSpectrumEmissionP, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) -{ + ARFCN_ValueEUTRA_t *ul_CArrierFreqP, + long *ul_BandwidthP, + AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, + struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; + nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - cfg->subframe_config.pb.value = - radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; - cfg->rf_config.reference_signal_power.value = - radioResourceConfigCommonP->pdsch_ConfigCommon. - referenceSignalPower; - cfg->nfapi_config.max_transmit_power.value = - cfg->rf_config.reference_signal_power.value + - power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; + cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; + cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; + cfg->num_tlv++; - cfg->prach_config.configuration_index.value = - radioResourceConfigCommonP->prach_Config. - prach_ConfigInfo.prach_ConfigIndex; - cfg->prach_config.root_sequence_index.value = - radioResourceConfigCommonP->prach_Config.rootSequenceIndex; - cfg->prach_config.zero_correlation_zone_configuration.value = - radioResourceConfigCommonP->prach_Config. - prach_ConfigInfo.zeroCorrelationZoneConfig; - cfg->prach_config.high_speed_flag.value = - radioResourceConfigCommonP->prach_Config.prach_ConfigInfo. - highSpeedFlag; - cfg->prach_config.frequency_offset.value = - radioResourceConfigCommonP->prach_Config. - prach_ConfigInfo.prach_FreqOffset; + cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; + cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; + cfg->num_tlv++; - cfg->pusch_config.hopping_mode.value = - radioResourceConfigCommonP->pusch_ConfigCommon. - pusch_ConfigBasic.hoppingMode; - cfg->pusch_config.number_of_subbands.value = - radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic. - n_SB; - cfg->pusch_config.hopping_offset.value = - radioResourceConfigCommonP->pusch_ConfigCommon. - pusch_ConfigBasic.pusch_HoppingOffset; + cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; + cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; + cfg->num_tlv++; + + cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; + cfg->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + + cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; + cfg->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; + + cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + cfg->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + cfg->num_tlv++; + + cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + cfg->num_tlv++; + + cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset; + cfg->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; + cfg->pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; + cfg->num_tlv++; - cfg->pucch_config.delta_pucch_shift.value = - radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; - cfg->pucch_config.n_cqi_rb.value = - radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; - cfg->pucch_config.n_an_cs.value = - radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; - cfg->pucch_config.n1_pucch_an.value = - radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; + cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; + cfg->pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; + cfg->num_tlv++; - if (radioResourceConfigCommonP-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == - true) - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; - else if (radioResourceConfigCommonP-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - sequenceHoppingEnabled == true) - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; - else // No hopping - cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; + cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; + cfg->pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; + cfg->num_tlv++; - cfg->uplink_reference_signal_config.group_assignment.value = - radioResourceConfigCommonP-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = - radioResourceConfigCommonP-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; + cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; + cfg->pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; + cfg->num_tlv++; - // how to enable/disable SRS? - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present == - SoundingRS_UL_ConfigCommon_PR_setup) { - cfg->srs_config.bandwidth_configuration.value = - radioResourceConfigCommonP->soundingRS_UL_ConfigCommon. - choice.setup.srs_BandwidthConfig; - cfg->srs_config.srs_subframe_configuration.value = - radioResourceConfigCommonP->soundingRS_UL_ConfigCommon. - choice.setup.srs_SubframeConfig; - cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = - radioResourceConfigCommonP->soundingRS_UL_ConfigCommon. - choice.setup.ackNackSRS_SimultaneousTransmission; + cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; + cfg->pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; + cfg->num_tlv++; - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon. - choice.setup.srs_MaxUpPts) - cfg->srs_config.max_up_pts.value = 1; - else - cfg->srs_config.max_up_pts.value = 0; + cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; + cfg->pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; + cfg->num_tlv++; + + cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; + cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; + cfg->num_tlv++; + + if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) + { + cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; + } + else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) + { + cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; + } + else // No hopping + { + cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; + } + cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + cfg->num_tlv++; + + cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; + cfg->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + cfg->num_tlv++; + + cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; + cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + cfg->num_tlv++; + + + // how to enable/disable SRS? + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { + cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; + cfg->num_tlv++; + + cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + cfg->srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; + cfg->num_tlv++; + + cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; + cfg->num_tlv++; + + + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { + cfg->srs_config.max_up_pts.value = 1; } + else { + cfg->srs_config.max_up_pts.value = 0; + } + cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + cfg->num_tlv++; + } + #ifdef Rel14 - if (RC.mac[Mod_idP]->common_channels[CC_idP].mib-> - message.schedulingInfoSIB1_BR_r13 > 0) { - AssertFatal(radioResourceConfigCommon_BRP != NULL, - "radioResource rou is missing\n"); - AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, - "ext4 is missing\n"); - cfg->emtc_config.prach_catm_root_sequence_index.value = - radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; - cfg->emtc_config.prach_catm_zero_correlation_zone_configuration. - value = - radioResourceConfigCommon_BRP->prach_Config. - prach_ConfigInfo.zeroCorrelationZoneConfig; - cfg->emtc_config.prach_catm_high_speed_flag.value = - radioResourceConfigCommon_BRP->prach_Config. - prach_ConfigInfo.highSpeedFlag; + if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13>0) { + AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n"); + AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n"); + cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; + cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; - struct PRACH_ConfigSIB_v1310 *ext4_prach = - radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + cfg->num_tlv++; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = - &ext4_prach->prach_ParametersListCE_r13; + cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; + cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; + cfg->num_tlv++; + + struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; - PRACH_ParametersCE_r13_t *p; - cfg->emtc_config.prach_ce_level_0_enable.value = 0; - cfg->emtc_config.prach_ce_level_1_enable.value = 0; - cfg->emtc_config.prach_ce_level_2_enable.value = 0; - cfg->emtc_config.prach_ce_level_3_enable.value = 0; - switch (prach_ParametersListCE_r13->list.count) { - case 4: - p = prach_ParametersListCE_r13->list.array[3]; - cfg->emtc_config.prach_ce_level_3_enable.value = 1; - cfg->emtc_config.prach_ce_level_3_configuration_index.value = - p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_3_frequency_offset.value = - p->prach_FreqOffset_r13; - cfg-> - emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt. - value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) - cfg-> - emtc_config.prach_ce_level_3_starting_subframe_periodicity. - value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_3_hopping_enable.value = - p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_3_hopping_offset.value = - cfg->rf_config.ul_channel_bandwidth.value - 6; - case 3: - p = prach_ParametersListCE_r13->list.array[2]; - cfg->emtc_config.prach_ce_level_2_enable.value = 1; - cfg->emtc_config.prach_ce_level_2_configuration_index.value = - p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_2_frequency_offset.value = - p->prach_FreqOffset_r13; - cfg-> - emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt. - value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) - cfg-> - emtc_config.prach_ce_level_2_starting_subframe_periodicity. - value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_2_hopping_enable.value = - p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_2_hopping_offset.value = - cfg->rf_config.ul_channel_bandwidth.value - 6; - case 2: - p = prach_ParametersListCE_r13->list.array[1]; - cfg->emtc_config.prach_ce_level_1_enable.value = 1; - cfg->emtc_config.prach_ce_level_1_configuration_index.value = - p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_1_frequency_offset.value = - p->prach_FreqOffset_r13; - cfg-> - emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt. - value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) - cfg-> - emtc_config.prach_ce_level_1_starting_subframe_periodicity. - value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_1_hopping_enable.value = - p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_1_hopping_offset.value = - cfg->rf_config.ul_channel_bandwidth.value - 6; - case 1: - p = prach_ParametersListCE_r13->list.array[0]; - cfg->emtc_config.prach_ce_level_0_enable.value = 1; - cfg->emtc_config.prach_ce_level_0_configuration_index.value = - p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_0_frequency_offset.value = - p->prach_FreqOffset_r13; - cfg-> - emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt. - value = p->numRepetitionPerPreambleAttempt_r13; - if (p->prach_StartingSubframe_r13) - cfg-> - emtc_config.prach_ce_level_0_starting_subframe_periodicity. - value = *p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_0_hopping_enable.value = - p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_0_hopping_offset.value = - cfg->rf_config.ul_channel_bandwidth.value - 6; - } + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = - radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; - if ((ext4_freqHoppingParameters) - && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)) - { - switch - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13-> - present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodea.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13-> - choice.interval_FDD_r13; - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodea.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13-> - choice.interval_TDD_r13; - break; - } - } - if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)) - { - switch - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodeb.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - choice.interval_FDD_r13; - break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: - cfg->emtc_config. - pucch_interval_ulhoppingconfigcommonmodeb.value = - ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13-> - choice.interval_TDD_r13; - break; - } - } + PRACH_ParametersCE_r13_t *p; + cfg->emtc_config.prach_ce_level_0_enable.value=0; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_1_enable.value=0; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_2_enable.value=0; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_3_enable.value=0; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + + switch (prach_ParametersListCE_r13->list.count) { + case 4: + p=prach_ParametersListCE_r13->list.array[3]; + cfg->emtc_config.prach_ce_level_3_enable.value = 1; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + + cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + + case 3: + p=prach_ParametersListCE_r13->list.array[2]; + cfg->emtc_config.prach_ce_level_2_enable.value = 1; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + + cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + + case 2: + p=prach_ParametersListCE_r13->list.array[1]; + cfg->emtc_config.prach_ce_level_1_enable.value = 1; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + + cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + cfg->num_tlv++; + + case 1: + p=prach_ParametersListCE_r13->list.array[0]; + cfg->emtc_config.prach_ce_level_0_enable.value = 1; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + cfg->num_tlv++; + + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = *p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } + + cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + + cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value-6; + cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + cfg->num_tlv++; } + + struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; + if ((ext4_freqHoppingParameters) && + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ + switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; + } + } + if ((ext4_freqHoppingParameters) && + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ + switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; + case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; + } + } + } #endif } @@ -597,66 +752,67 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, SystemInformationBlockType1_v1310_IEs_t * sib1_v13ext #endif - ) -{ + ) { + + int i; - int i; + int UE_id = -1; + eNB_MAC_INST *eNB = RC.mac[Mod_idP]; + UE_list_t *UE_list= &eNB->UE_list; - int UE_id = -1; - eNB_MAC_INST *eNB = RC.mac[Mod_idP]; - UE_list_t *UE_list = &eNB->UE_list; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); + LOG_E(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib); + if (mib != NULL) { + if (RC.mac == NULL) + l2_init_eNB(); - if (mib != NULL) { - if (RC.mac == NULL) - l2_init_eNB(); + mac_top_init_eNB(); - mac_top_init_eNB(); + RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib; + RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; + RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB; + RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp; + RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; + RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq; - RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib; - RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; - RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB; - RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp; - RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; - RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = - dl_CarrierFreq; + LOG_I(MAC, + "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", + Mod_idP, + CC_idP, + eutra_band, + to_prb((int)mib->message.dl_Bandwidth), + physCellId, + p_eNB, + dl_CarrierFreq, + (int)mib->message.phich_Config.phich_Resource, + (int)mib->message.phich_Config.phich_Duration); - LOG_I(MAC, - "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", - Mod_idP, - CC_idP, - eutra_band, - to_prb((int) mib->message.dl_Bandwidth), - physCellId, - p_eNB, - dl_CarrierFreq, - (int) mib->message.phich_Config.phich_Resource, - (int) mib->message.phich_Config.phich_Duration); - - config_mib(Mod_idP, CC_idP, - eutra_band, - mib->message.dl_Bandwidth, - &mib->message.phich_Config, - physCellId, Ncp, p_eNB, dl_CarrierFreq, ul_CarrierFreq + config_mib(Mod_idP,CC_idP, + eutra_band, + mib->message.dl_Bandwidth, + &mib->message.phich_Config, + physCellId, + Ncp, + p_eNB, + dl_CarrierFreq, + ul_CarrierFreq #ifdef Rel14 , pbch_repetition #endif - ); + ); - mac_init_cell_params(Mod_idP, CC_idP); - } - if (schedulingInfoList != NULL) { - RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config; - RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = - schedulingInfoList; - config_sib1(Mod_idP, CC_idP, tdd_Config); + mac_init_cell_params(Mod_idP,CC_idP); + + if (schedulingInfoList!=NULL) { + RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config; + RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; + config_sib1(Mod_idP,CC_idP,tdd_Config); } #ifdef Rel14 if (sib1_v13ext != NULL) { - RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; + RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; } #endif if (radioResourceConfigCommon != NULL) { @@ -719,53 +875,52 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, NULL, ul_Bandwidth, additionalSpectrumEmission, mbsfn_SubframeConfigList); - } - // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup - if (logicalChannelConfig != NULL) { // check for eMTC specific things - UE_id = find_UE_id(Mod_idP, rntiP); + } // mib != NULL - if (UE_id == -1) { - LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); - } else { - if (logicalChannelConfig) - UE_list-> - UE_template[CC_idP][UE_id].lcgidmap - [logicalChannelIdentity] = - *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup; - else - UE_list-> - UE_template[CC_idP][UE_id].lcgidmap - [logicalChannelIdentity] = 0; - } + // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup + if (logicalChannelConfig != NULL) { // check for eMTC specific things + UE_id = find_UE_id(Mod_idP, rntiP); + + if (UE_id == -1) { + LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, + __LINE__, __FUNCTION__); + } else { + if (logicalChannelConfig) + UE_list-> + UE_template[CC_idP][UE_id].lcgidmap + [logicalChannelIdentity] = + *logicalChannelConfig-> + ul_SpecificParameters->logicalChannelGroup; + else + UE_list-> + UE_template[CC_idP][UE_id].lcgidmap + [logicalChannelIdentity] = 0; } + } - if (physicalConfigDedicated != NULL) { - UE_id = find_UE_id(Mod_idP, rntiP); + if (physicalConfigDedicated != NULL) { + UE_id = find_UE_id(Mod_idP, rntiP); - if (UE_id == -1) - LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); - else - UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated = - physicalConfigDedicated; - } + if (UE_id == -1) + LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); + else + UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated = physicalConfigDedicated; + } #if defined(Rel10) || defined(Rel14) - if (sCellToAddMod_r10 != NULL) { - UE_id = find_UE_id(Mod_idP, rntiP); - if (UE_id == -1) - LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, - __LINE__, __FUNCTION__); - else + if (sCellToAddMod_r10 != NULL) { + UE_id = find_UE_id(Mod_idP, rntiP); + if (UE_id == -1) + LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, + __LINE__, __FUNCTION__); + else config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); - } + } #endif @@ -795,25 +950,18 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } #if defined(Rel10) || defined(Rel14) - if (mbsfn_AreaInfoList != NULL) { - // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time - LOG_I(MAC, "[eNB %d][CONFIG] Received %d MBSFN Area Info\n", - Mod_idP, mbsfn_AreaInfoList->list.count); - RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = - mbsfn_AreaInfoList->list.count; - - for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) { - RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i] = - mbsfn_AreaInfoList->list.array[i]; - LOG_I(MAC, - "[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", - Mod_idP, i, - RC.mac[Mod_idP]->common_channels[0]. - mbsfn_AreaInfo[i]->mcch_Config_r9. - mcch_RepetitionPeriod_r9); - // config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); - } + if (mbsfn_AreaInfoList != NULL) { + // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time + LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); + RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; + + for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { + RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; + LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP,i, + RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + // config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } + } if (pmch_InfoList != NULL) { @@ -849,21 +997,32 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } #endif - if (radioResourceConfigCommon != NULL) { - AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL, - "if_inst->phy_config_request is null\n"); - PHY_Config_t phycfg; - phycfg.Mod_id = Mod_idP; - phycfg.CC_id = CC_idP; - phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); - if (RC.mac[Mod_idP]->if_inst->PHY_config_req) - RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + // if in nFAPI mode + if ( + (nfapi_mode == 1 || nfapi_mode == 2) && + (RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) + ) { + while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { + // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + usleep(100 * 1000); + printf("Waiting for PHY_config_req\n"); + } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); - return (0); + if (radioResourceConfigCommon != NULL) { + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + } + + return(0); } int diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index f6c598976e..884efc4433 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -39,15 +39,9 @@ -#ifdef USER_MODE #include #include #include -#endif - -//#include "COMMON/openair_defs.h" - - #include "PHY/defs.h" #include "PHY/LTE_TRANSPORT/defs.h" @@ -109,9 +103,7 @@ //#define MCH_PAYLOAD_SIZE_MAX 16384// this value is using in case mcs and TBS index are high #endif -#ifdef USER_MODE #define printk printf -#endif //USER_MODE /*!\brief Maximum number of logical channl group IDs */ #define MAX_NUM_LCGID 4 diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index a69a721568..b307db29b7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -145,7 +145,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { - // Prorgram SRS + // Program SRS ul_req->srs_present = 1; nfapi_ul_config_request_pdu_t * ul_config_pdu = @@ -161,6 +161,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) 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); @@ -196,6 +197,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->number_of_pdus++; } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) @@ -269,9 +271,11 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) 2 + (uint8_t) (2 + sizeof (nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_cqi_pdu. ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; ul_config_pdu->uci_cqi_pdu. cqi_information.cqi_information_rel8. pucch_index = @@ -285,6 +289,7 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) get_tmode(module_idP, CC_id, UE_id), cqi_ReportPeriodic); ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; #if defined(Rel10) || defined(Rel14) // PUT rel10-13 UCI options here @@ -305,9 +310,11 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) 2 + (uint8_t) (2 + sizeof (nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_cqi_pdu. ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; ul_config_pdu->uci_cqi_pdu. cqi_information.cqi_information_rel8. pucch_index = @@ -319,6 +326,7 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; } } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { @@ -332,7 +340,8 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_t *ul_req; + nfapi_ul_config_request_body_t *ul_req_body; int CC_id; int UE_id; SchedulingRequestConfig_t *SRconfig; @@ -349,8 +358,8 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (RC.mac[module_idP]->UE_list.active[UE_id] != TRUE) continue; - ul_req = - &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + ul_req = &RC.mac[module_idP]->UL_req[CC_id]; + ul_req_body = &ul_req->ul_config_request_body; // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet if (mac_eNB_get_rrc_status @@ -397,28 +406,18 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) skip_ue = 0; is_harq = 0; // check that there is no existing UL grant for ULSCH which overrides the SR - for (i = 0; i < ul_req->number_of_pdus; i++) { - if (((ul_req->ul_config_pdu_list[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) - || (ul_req->ul_config_pdu_list[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) - || (ul_req->ul_config_pdu_list[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) - || (ul_req->ul_config_pdu_list[i].pdu_type == - NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) - && (ul_req->ul_config_pdu_list[i]. - ulsch_pdu.ulsch_pdu_rel8.rnti == - UE_list->UE_template[CC_id][UE_id].rnti)) { + for (i = 0; i < ul_req_body->number_of_pdus; i++) { + if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && + (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { skip_ue = 1; break; } /* if there is already an HARQ pdu, convert to SR_HARQ */ - else if ((ul_req->ul_config_pdu_list[i].pdu_type == - NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) - && (ul_req->ul_config_pdu_list[i]. - uci_harq_pdu.ue_information. - ue_information_rel8.rnti == - UE_list->UE_template[CC_id][UE_id].rnti)) { + else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { is_harq = 1; break; } @@ -428,10 +427,7 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (skip_ue == 1) continue; - LOG_D(MAC, - "Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n", - frameP, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].rnti); + LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); // check Rel10 or Rel8 SR #if defined(Rel10) || defined(Rel14) @@ -443,49 +439,48 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) && (UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated-> ext2->schedulingRequestConfig_v1020)) { + sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; sr.sr_information_rel10.number_of_pucch_resources = 1; sr.sr_information_rel10.pucch_index_p1 = *UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated-> ext2-> schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; + LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); } else #endif { + sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; sr.sr_information_rel8.pucch_index = UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated-> schedulingRequestConfig->choice.setup. sr_PUCCH_ResourceIndex; + LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); } /* if there is already an HARQ pdu, convert to SR_HARQ */ if (is_harq) { - nfapi_ul_config_harq_information h = - ul_req->ul_config_pdu_list[i].uci_harq_pdu. - harq_information; - ul_req->ul_config_pdu_list[i].pdu_type = - NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu. - sr_information = sr; - ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu. - harq_information = h; + nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; + ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; + ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; } else { - ul_req->ul_config_pdu_list[ul_req->number_of_pdus]. - pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; - ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus].uci_sr_pdu. - ue_information.ue_information_rel8.rnti = - UE_list->UE_template[CC_id][UE_id].rnti; - ul_req->ul_config_pdu_list[ul_req-> - number_of_pdus].uci_sr_pdu. - sr_information = sr; - ul_req->number_of_pdus++; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; + ul_req_body->number_of_pdus++; } /* if (is_harq) */ + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) } // for (CC_id=0; CC_idpdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = @@ -533,6 +529,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; DL_req[CC_id].dl_config_request_body.number_dci++; DL_req[CC_id].dl_config_request_body.number_pdu++; + DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; LOG_D(MAC, "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", UE_id, rnti, @@ -579,55 +576,59 @@ clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0]; nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; - eNB->pdu_index[CC_idP] = 0; - DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; - DL_req[CC_idP].dl_config_request_body.number_dci = 0; - DL_req[CC_idP].dl_config_request_body.number_pdu = 0; - DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; - DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; - HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = - subframeP + (frameP << 4); - HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; + if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF + + DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; + DL_req[CC_idP].dl_config_request_body.number_dci = 0; + DL_req[CC_idP].dl_config_request_body.number_pdu = 0; + DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; + DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; + + HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); + HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; - UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now - UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now - - - TX_req[CC_idP].tx_request_body.number_of_pdus = 0; + UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; + UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now + UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now + TX_req[CC_idP].tx_request_body.number_of_pdus = 0; + } } void copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { int CC_id; - eNB_MAC_INST *eNB; - nfapi_ul_config_request_body_t *ul_req_tmp; - nfapi_ul_config_request_body_t *ul_req; - - eNB = RC.mac[module_idP]; + eNB_MAC_INST *mac = RC.mac[module_idP]; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - ul_req_tmp = - &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body; - ul_req = &eNB->UL_req[CC_id].ul_config_request_body; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; + nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; + nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; - eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - ul_req->number_of_pdus = ul_req_tmp->number_of_pdus; - ul_req_tmp->number_of_pdus = 0; + *ul_req = *ul_req_tmp; - memcpy((void *) ul_req->ul_config_pdu_list, - (void *) ul_req_tmp->ul_config_pdu_list, - ul_req->number_of_pdus * - sizeof(nfapi_ul_config_request_pdu_t)); + // Restore the pointer + ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; - } + ul_req->sfn_sf = (frameP<<4) + subframeP; + + ul_req_tmp->ul_config_request_body.number_of_pdus = 0; + + if (ul_req->ul_config_request_body.number_of_pdus>0) + { + LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); + } + + memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, + (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, + ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + } } void @@ -730,12 +731,17 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, pdcp_remove_UE(&ctxt); } for (int ii=0; iiulsch[ii]; + LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii]; if((ulsch != NULL) && (ulsch->rnti == rnti)){ LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); clean_eNb_ulsch(ulsch); - break; + } + } + for (int ii=0; iidlsch[ii][0]; + if((dlsch != NULL) && (dlsch->rnti == rnti)){ + LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); + clean_eNb_dlsch(dlsch); } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 83c184c0c2..3fd7504a8e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -65,6 +65,37 @@ #include "T.h" +extern uint8_t nfapi_mode; +extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); + +void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) +{ + *frameP = (*frameP + ((*subframeP + offset) / 10)) % 1024; + + *subframeP = ((*subframeP + offset) % 10); +} + +uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset) +{ + add_subframe(&frameP, &subframeP, offset); + return frameP<<4|subframeP; +} + +void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) +{ + if (*subframeP < offset) + { + *frameP = (*frameP+1024-1)%1024; + } + *subframeP = (*subframeP+10-offset)%10; +} + +uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset) +{ + subtract_subframe(&frameP, &subframeP, offset); + return frameP<<4|subframeP; +} + void add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, sub_frame_t subframeP) @@ -73,15 +104,15 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, COMMON_channels_t *cc = &mac->common_channels[CC_id]; uint8_t j; nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; nfapi_ul_config_request_body_t *ul_req_body; - nfapi_hi_dci0_request_body_t *hi_dci0_req; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; uint8_t rvseq[4] = { 0, 2, 3, 1 }; - hi_dci0_req = &mac->HI_DCI0_req[CC_id].hi_dci0_request_body; ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; ul_req_body = &ul_req->ul_config_request_body; AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", @@ -108,6 +139,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb(cc, @@ -132,6 +164,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb); // Re13 fields + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13. @@ -141,6 +174,9 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; } // if (ra->rach_resource_type>0) { else #endif @@ -163,6 +199,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = @@ -187,24 +224,41 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; // save UL scheduling information for preprocessor for (j = 0; j < ra->msg3_nb_rb; j++) cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; + LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round); if (ra->msg3_round != 0) { // program HI too - hi_dci0_pdu = - &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + - hi_dci0_req->number_of_hi]; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req->number_of_hi++; + hi_dci0_req_body->number_of_hi++; + + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + + hi_dci0_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + if (nfapi_mode) { + oai_nfapi_hi_dci0_req(hi_dci0_req); + hi_dci0_req_body->number_of_hi=0; + } + + LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi); + // save UL scheduling information for preprocessor for (j = 0; j < ra->msg3_nb_rb; j++) cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; @@ -251,6 +305,8 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, uint16_t absSF = (10 * frameP) + subframeP; uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; + LOG_D(MAC,"absSF:%d absSF_Msg2:%d ra->rach_resource_type:%d\n",absSF,absSF_Msg2,ra->rach_resource_type); + if (absSF > absSF_Msg2) return; // we're not ready yet, need to be to start == @@ -325,6 +381,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = @@ -397,8 +454,11 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, number_of_tx_antenna_ports = 1; ra->msg2_mpdcch_repetition_cnt++; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; ra->Msg2_subframe = (ra->Msg2_subframe + 9) % 10; + mac->DL_req[CC_idP].sfn_sf = sfnsf_add_subframe(ra->Msg2_frame, ra->Msg2_subframe, 4); // nFAPI is runnning at TX SFN/SF - ie 4 ahead + mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST; } //repetition_count==0 && SF condition met if (ra->msg2_mpdcch_repetition_cnt > 0) { // we're in a stream of repetitions LOG_D(MAC, @@ -427,6 +487,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", module_idP, frameP, subframeP); ra->state = WAITMSG3; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; @@ -435,6 +496,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; @@ -472,11 +534,13 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP]. sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> startSymbolBR_r13; // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message @@ -486,6 +550,11 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, 0; dl_req->number_pdu++; + mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP; + mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + LOG_D(MAC,"DL_CONFIG SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP); + // Program UL processing for Msg3, same as regular LTE get_Msg3alloc(&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe); @@ -494,6 +563,8 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, cc[CC_idP].RAR_pdu.payload, ra->rach_resource_type - 1); // DL request + mac->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> @@ -538,6 +609,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = @@ -577,6 +649,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; @@ -612,6 +685,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP; // Program UL processing for Msg3 get_Msg3alloc(&cc[CC_idP], subframeP, frameP, @@ -626,6 +700,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); add_msg3(module_idP, CC_idP, ra, frameP, subframeP); ra->state = WAITMSG3; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; @@ -652,7 +727,6 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, } // Msg2 frame/subframe condition } // else BL/CE } - void generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, RA_t * ra) @@ -667,17 +741,19 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, uint16_t msg4_post_padding; uint16_t msg4_header; - uint8_t *vrb_map; - int first_rb; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - UE_list_t *UE_list = &mac->UE_list; - nfapi_dl_config_request_body_t *dl_req; - nfapi_ul_config_request_body_t *ul_req; - uint8_t lcid; - uint8_t offset; + uint8_t *vrb_map; + int first_rb; + int N_RB_DL; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + UE_list_t *UE_list=&mac->UE_list; + nfapi_dl_config_request_t *dl_req; + nfapi_dl_config_request_body_t *dl_req_body; + nfapi_ul_config_request_body_t *ul_req_body; + nfapi_ul_config_request_t *ul_req; + uint8_t lcid; + uint8_t offset; #ifdef Rel14 @@ -764,8 +840,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, vrb_map = cc[CC_idP].vrb_map; - dl_req = &mac->DL_req[CC_idP].dl_config_request_body; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_req = &mac->DL_req[CC_idP]; + dl_req_body = &dl_req->dl_config_request_body; + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); UE_id = find_UE_id(module_idP, ra->rnti); @@ -778,7 +855,6 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, else ra->harq_pid = ((frameP * 10) + subframeP) & 7; - // Get RRCConnectionSetup for Piggyback rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case @@ -827,6 +903,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = @@ -899,7 +976,11 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13. number_of_tx_antenna_ports = 1; ra->msg4_mpdcch_repetition_cnt++; - dl_req->number_pdu++; + dl_req_body->number_pdu++; + dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + dl_req->sfn_sf = (ra->Msg4_frame<<4)+ra->Msg4_subframe; + dl_req->header.message_id = NFAPI_DL_CONFIG_REQUEST; } //repetition_count==0 && SF condition met else if (ra->msg4_mpdcch_repetition_cnt > 0) { // we're in a stream of repetitions @@ -929,12 +1010,13 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "Msg4 generation not finished for BL/CE UE\n"); dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti; @@ -969,11 +1051,13 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP]. sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13-> startSymbolBR_r13; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message @@ -981,9 +1065,14 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, initial_transmission_sf_io = (10 * frameP) + subframeP; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; - dl_req->number_pdu++; + dl_req_body->number_pdu++; + dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP; + mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST; + ra->state = WAITMSG4ACK; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP); lcid = 0; @@ -1026,6 +1115,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; + mac->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST; + TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac-> TX_req @@ -1046,19 +1138,19 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, int ackNAK_absSF = absSF + reps + 4; AssertFatal(reps > 2, "Have to handle programming of ACK when PDSCH repetitions is > 2\n"); - ul_req = - &mac->UL_req_tmp[CC_idP][ackNAK_absSF % - 10].ul_config_request_body; - ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + ul_req = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; + ul_req_body = &ul_req->ul_config_request_body; + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this ul_config_pdu->uci_harq_pdu. ue_information.ue_information_rel8.rnti = ra->rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; ul_config_pdu->uci_harq_pdu. ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; @@ -1070,8 +1162,17 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, ul_config_pdu->uci_harq_pdu. ue_information.ue_information_rel13.repetition_number = 0; + + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + + ul_req->sfn_sf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4); + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + + LOG_D(MAC,"UL_req_tmp[CC_idP:%d][ackNAK_absSF mod 10:%d] ra->Msg3_frame:%d ra->Msg3_subframe:%d + 4 sfn_sf:%d\n", CC_idP, ackNAK_absSF%10, ra->Msg3_frame, ra->Msg3_subframe, NFAPI_SFNSF2DEC(ul_req->sfn_sf)); + // Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that if (cc[CC_idP].tdd_Config == NULL) { // FDD case + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; ul_config_pdu->uci_harq_pdu. harq_information.harq_information_rel8_fdd. n_pucch_1_0 = @@ -1085,7 +1186,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal(1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); } - ul_req->number_of_pdus++; + 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? */ ), @@ -1166,9 +1267,10 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, 1, // ndi 0, // rv 0); // vrb_flag + 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->number_pdu, + frameP, subframeP, dl_req_body->number_pdu, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process, @@ -1185,10 +1287,11 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, (module_idP, CC_idP, 1, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. aggregation_level, ra->rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; + dl_req_body->number_dci++; + dl_req_body->number_pdu++; ra->state = WAITMSG4ACK; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP); // increment Absolute subframe by 8 for Msg4 retransmission LOG_D(MAC, @@ -1247,7 +1350,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); // DLSCH Config - fill_nfapi_dlsch_config(mac, dl_req, ra->msg4_TBsize, mac->pdu_index[CC_idP], ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D + 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 0, // virtual_resource_block_assignment_flag : localized getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB 2, // modulation: QPSK @@ -1268,9 +1371,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, 1); // num_bf_vector LOG_D(MAC, "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n", - dl_req->number_pdu, mac->pdu_index[CC_idP]); + dl_req_body->number_pdu, mac->pdu_index[CC_idP]); - // DL request + // Tx request mac->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, (frameP * 10) + subframeP, @@ -1282,6 +1385,8 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, [0]); mac->pdu_index[CC_idP]++; + dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf; + LOG_D(MAC, "Filling UCI ACK/NAK information, cce_idx %d\n", dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); // Program PUCCH1a for ACK/NAK @@ -1339,7 +1444,8 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, int N_RB_DL; nfapi_dl_config_request_pdu_t *dl_config_pdu; UE_list_t *UE_list = &mac->UE_list; - nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_t *dl_req; + nfapi_dl_config_request_body_t *dl_req_body; int round; /* @@ -1385,8 +1491,9 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, round = UE_list->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_config_request_body; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + dl_req = &mac->DL_req[CC_idP]; + dl_req_body = &dl_req->dl_config_request_body; + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); LOG_D(MAC, @@ -1408,6 +1515,8 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, //ra->wait_ack_Msg4++; // we have to schedule a retransmission + dl_req->sfn_sf = frameP<<4 | subframeP; + first_rb = 0; vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; @@ -1429,14 +1538,16 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, (module_idP, CC_idP, 1, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. aggregation_level, ra->rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; + dl_req_body->number_dci++; + dl_req_body->number_pdu++; + dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; LOG_D(MAC, "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", ra->rnti, round, frameP, subframeP); // DLSCH Config - fill_nfapi_dlsch_config(mac, dl_req, ra->msg4_TBsize, + //DJP - fix this pdu_index = -1 + fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, -1 /* retransmission, no pdu_index */ , ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D @@ -1498,6 +1609,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n", module_idP, CC_idP, frameP, subframeP); ra->state = IDLE; + 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]. @@ -1529,6 +1641,8 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ra = (RA_t *) & cc[CC_id].ra[i]; + //LOG_D(MAC,"RA[state:%d]\n",ra->state); + if (ra->state == MSG2) generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); else if (ra->state == MSG4) @@ -1574,7 +1688,7 @@ initiate_ra_proc(module_id_t module_idP, prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } - LOG_I(MAC, + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, subframeP, preamble_index); #ifdef Rel14 @@ -1583,6 +1697,10 @@ initiate_ra_proc(module_id_t module_idP, module_idP, CC_id, frameP, subframeP, rach_resource_type); #endif + uint16_t msg2_frame = frameP; + uint16_t msg2_subframe = subframeP; + int offset; + if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) { LOG_E(MAC, @@ -1610,9 +1728,22 @@ initiate_ra_proc(module_id_t module_idP, ra[i].msg2_mpdcch_repetition_cnt = 0; ra[i].msg4_mpdcch_repetition_cnt = 0; #endif - ra[i].Msg2_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra[i].Msg2_subframe = (subframeP + 4) % 10; - /* TODO: find better procedure to allocate RNTI */ + + // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes + if (nfapi_mode) + offset = 7; + else + offset = 5; + + add_subframe(&msg2_frame, &msg2_subframe, offset); + + ra[i].Msg2_frame = msg2_frame; + ra[i].Msg2_subframe = msg2_subframe; + + LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,subframeP,offset); + + ra[i].Msg2_subframe = (subframeP + offset) % 10; + /* TODO: find better procedure to allocate RNTI */ do { #if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode static int drnti[NUMBER_OF_UE_MAX] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 71be9f9b9d..5b0fc58bb7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -100,6 +100,7 @@ schedule_SIB1_BR(module_id_t module_idP, int n_NB = 0; int TBS; int k = 0, rvidx; + uint16_t sfn_sf = frameP<<4|subframeP; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -236,6 +237,7 @@ schedule_SIB1_BR(module_id_t module_idP, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = TBS; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; @@ -265,14 +267,17 @@ schedule_SIB1_BR(module_id_t module_idP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request TX_req = @@ -284,9 +289,10 @@ schedule_SIB1_BR(module_id_t module_idP, TX_req->num_segments = 1; TX_req->segments[0].segment_length = bcch_sdu_length; TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[0].payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - - + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; if (opt_enabled == 1) { trace_pdu(1, @@ -306,10 +312,7 @@ schedule_SIB1_BR(module_id_t module_idP, "[eNB] Frame %d : Scheduling BCCH-BR 0->DLSCH (FDD) for CC_id %d SIB1-BR %d bytes\n", frameP, CC_id, bcch_sdu_length); } - } - - return; } int si_WindowLength_BR_r13tab @@ -324,7 +327,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int8_t bcch_sdu_length; int CC_id; eNB_MAC_INST *eNB = RC.mac[module_idP]; @@ -338,6 +340,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, int i; int rvidx; int absSF = (frameP * 10) + subframeP; + uint16_t sfn_sf = frameP << 4 | subframeP; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -472,6 +475,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13 >> 3; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = @@ -513,11 +517,13 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8. num_bf_vector = 1; // Rel10 fields (for PDSCH starting symbol) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10. pdsch_start = cc[CC_id]. sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR dl_config_pdu->dlsch_pdu. @@ -526,6 +532,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Program TX Request TX_req = @@ -541,6 +548,9 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, cc->BCCH_BR_pdu[i + 1].payload; eNB->TX_req[CC_id].tx_request_body. number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; if (opt_enabled == 1) { trace_pdu(1, @@ -583,26 +593,26 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) nfapi_tx_request_pdu_t *TX_req; int mib_sdu_length; int CC_id; + nfapi_dl_config_request_t *dl_config_request; nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; AssertFatal(subframeP == 0, "Subframe must be 0\n"); AssertFatal((frameP & 3) == 0, "Frame must be a multiple of 4\n"); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + dl_config_request = &eNB->DL_req[CC_id]; + dl_req = &dl_config_request->dl_config_request_body; cc = &eNB->common_channels[CC_id]; mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 1, module_idP, 0); // not used in this case - LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", - frameP, subframeP, mib_sdu_length); + LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); if (mib_sdu_length > 0) { - LOG_D(MAC, - "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", - frameP, subframeP, dl_req->number_pdu, mib_sdu_length); + LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); if ((frameP & 1023) < 40) LOG_D(MAC, @@ -617,14 +627,18 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE, dl_config_pdu->pdu_size = 2 + sizeof(nfapi_dl_config_bch_pdu); + dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; dl_config_pdu->bch_pdu.bch_pdu_rel8.length = mib_sdu_length; dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power = 6000; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_req->number_pdu++; - LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", - dl_req->number_pdu, &dl_req->number_pdu); + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + + LOG_D(MAC, "eNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); // DL request TX_req = @@ -633,9 +647,12 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) TX_req->pdu_length = 3; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 0; + TX_req->segments[0].segment_length = 3; TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; } } } @@ -655,9 +672,11 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) uint8_t *vrb_map; int first_rb = -1; int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_dl_config_request_t *dl_config_request; + nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; + uint16_t sfn_sf = frameP << 4 | subframeP; start_meas(&eNB->schedule_si); @@ -669,15 +688,14 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) cc = &eNB->common_channels[CC_id]; vrb_map = (void *) &cc->vrb_map; N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + dl_config_request = &eNB->DL_req[CC_id]; dl_req = &eNB->DL_req[CC_id].dl_config_request_body; bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case if (bcch_sdu_length > 0) { - LOG_D(MAC, - "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", - module_idP, frameP, CC_id, bcch_sdu_length); + LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); // Allocate 4 PRBs in a random location /* @@ -742,6 +760,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. @@ -761,21 +780,13 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - - // Rel10 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_request->sfn_sf = sfn_sf; if (!CCE_allocation_infeasible (module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.aggregation_level, SI_RNTI)) { - LOG_D(MAC, - "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", - frameP, subframeP); + LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); dl_req->number_dci++; dl_req->number_pdu++; dl_config_pdu = @@ -788,6 +799,8 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = bcch_sdu_length; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized @@ -825,6 +838,18 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + + dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_request->sfn_sf = sfn_sf; + // Program TX Request TX_req = &eNB->TX_req[CC_id]. @@ -837,6 +862,9 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) TX_req->segments[0].segment_data = cc->BCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_id].sfn_sf = sfn_sf; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; } else { LOG_E(MAC, @@ -860,9 +888,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) "[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); } else { - LOG_D(MAC, - "[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", - frameP, CC_id, bcch_sdu_length, mcs); + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for CC_id %d SI %d bytes (mcs %d, rb 3)\n", frameP, CC_id, bcch_sdu_length, mcs); } @@ -881,6 +907,5 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) schedule_SI_BR(module_idP, frameP, subframeP); #endif - stop_meas(&eNB->schedule_si); - return; + stop_meas(&eNB->schedule_si); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 13c63124eb..eac6658464 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -63,6 +63,7 @@ //#define DEBUG_eNB_SCHEDULER 1 extern RAN_CONTEXT_t RC; +extern uint8_t nfapi_mode; //------------------------------------------------------------------------------ void @@ -71,6 +72,7 @@ add_ue_dlsch_info(module_id_t module_idP, int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) //------------------------------------------------------------------------------ { + //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); @@ -712,8 +714,12 @@ schedule_ue_spec(module_id_t module_idP, 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); */ - eNB_UE_stats->dlsch_mcs1 = - cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + if (nfapi_mode) { + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + else { + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); @@ -813,6 +819,8 @@ schedule_ue_spec(module_id_t module_idP, 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]; @@ -823,6 +831,7 @@ schedule_ue_spec(module_id_t module_idP, 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. @@ -878,6 +887,10 @@ schedule_ue_spec(module_id_t module_idP, 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 */ @@ -1341,7 +1354,6 @@ schedule_ue_spec(module_id_t module_idP, UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); } - if (opt_enabled == 1) { trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index fa462561af..17bd5398d9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1013,6 +1013,7 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, else return (7 + Ltab[cc->mib->message.dl_Bandwidth]); } + AssertFatal(1 == 0, "Shouldn't get here : cqi_ReportPeriodic->present %d\n", cqi_ReportPeriodic->choice. @@ -1035,6 +1036,8 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = + NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = @@ -1129,6 +1132,7 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, &ul_config_pdu->ulsch_harq_pdu.harq_information; ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet LOG_D(MAC, @@ -1159,6 +1163,7 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, * Those two types are not compatible. 'initial_transmission_parameters' is not at the * place in both. */ + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet break; @@ -1358,6 +1363,7 @@ fill_nfapi_harq_information(module_id_t module_idP, "physicalConfigDedicated for rnti %x is null\n", rntiP); #endif + harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; harq_information->harq_information_rel11.num_ant_ports = 1; switch (get_tmode(module_idP, CC_idP, UE_id)) { @@ -1386,12 +1392,14 @@ fill_nfapi_harq_information(module_id_t module_idP, harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon. n1PUCCH_AN + cce_idxP; harq_information-> harq_information_rel10_tdd.number_of_pucch_resources = 1; } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; harq_information-> harq_information_rel9_fdd.number_of_pucch_resources = 1; harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK @@ -1419,6 +1427,7 @@ fill_nfapi_harq_information(module_id_t module_idP, } else { harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling } + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; harq_information->harq_information_rel10_tdd.harq_size = 2; harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon. @@ -1426,6 +1435,7 @@ fill_nfapi_harq_information(module_id_t module_idP, harq_information-> harq_information_rel10_tdd.number_of_pucch_resources = 1; } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; harq_information-> harq_information_rel9_fdd.number_of_pucch_resources = 1; harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b @@ -1447,16 +1457,17 @@ fill_nfapi_uci_acknak(module_id_t module_idP, COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; int ackNAK_absSF = get_pucch1_absSF(cc, absSFP); - nfapi_ul_config_request_body_t *ul_req = - &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; + nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; + nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; nfapi_ul_config_request_pdu_t *ul_config_pdu = - &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; @@ -1473,7 +1484,11 @@ fill_nfapi_uci_acknak(module_id_t module_idP, ul_config_pdu->uci_harq_pdu. harq_information.harq_information_rel9_fdd.n_pucch_1_0); - ul_req->number_of_pdus++; + ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->sfn_sf = (ackNAK_absSF/10) << 4 | ackNAK_absSF%10; return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } @@ -1513,6 +1528,7 @@ fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; @@ -1567,6 +1583,7 @@ fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body, TX_req->num_segments = 1; TX_req->segments[0].segment_length = pdu_length; TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; tx_req_body->number_of_pdus++; return (((absSF / 10) << 4) + (absSF % 10)); @@ -1601,6 +1618,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = @@ -1635,6 +1653,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; ul_config_pdu->ulsch_cqi_ri_pdu. cqi_ri_information.cqi_ri_information_rel9.report_type = 1; ul_config_pdu->ulsch_cqi_ri_pdu. @@ -1700,6 +1719,7 @@ fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * { // Re13 fields + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = total_number_of_repetitions; @@ -2010,8 +2030,7 @@ get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt) LOG_W(MAC, "unsupported DCI format %d\n", dci_fmt); } - LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", - 1 << aggregation, cqi, bw_index, dci_fmt); + LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 1 << aggregation, cqi, bw_index, dci_fmt); return 1 << aggregation; } @@ -3109,9 +3128,9 @@ allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; LOG_D(MAC, - "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", - subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, - HI_DCI0_req->number_of_dci); + "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", + subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, + HI_DCI0_req->number_of_dci); DL_req->number_pdcch_ofdm_symbols = 1; try_again: @@ -3569,6 +3588,7 @@ CCE_allocation_infeasible(int module_idP, "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", subframe, rnti); } else { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = @@ -3596,6 +3616,7 @@ CCE_allocation_infeasible(int module_idP, subframe, rnti); } else { hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; @@ -3681,6 +3702,8 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, uint8_t harq_pid = ((10 * frameP) + subframeP + 10236) & 7; + LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); + switch (harq_indication_fdd->mode) { case 0: // Format 1a/b (10.1.2.1) AssertFatal(numCC == 1, @@ -3689,8 +3712,8 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port // single ACK/NAK bit AssertFatal(num_ack_nak == 1, - "num_ack_nak %d > 1 for 1 CC and single-layer transmission\n", - num_ack_nak); + "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", + num_ack_nak,frameP,subframeP); AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", harq_pid, UE_id, rnti); @@ -4389,6 +4412,8 @@ cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, if (UE_id >= 0) { + LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); + if (ul_cqi_information->channel == 0) { // PUCCH // extract pucch csi information before changing RI information diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 281e9a298c..b520b3e003 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -62,6 +62,14 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); +extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); +extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset); +extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); +extern uint8_t nfapi_mode; + +extern uint8_t nfapi_mode; + // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, @@ -182,7 +190,7 @@ rx_sdu(const module_id_t enb_mod_idP, maxHARQ_Msg3Tx); LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, current_rnti, RA_id, ul_cqi); @@ -208,10 +216,8 @@ rx_sdu(const module_id_t enb_mod_idP, first_rb_ul[harq_pid]; ra[RA_id].msg3_round++; // prepare handling of retransmission - ra[RA_id].Msg3_frame += - ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0); - ra[RA_id].Msg3_subframe = - (ra[RA_id].Msg3_subframe + 8) % 10; + ra[RA_id].Msg3_frame = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024; + ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10; add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); } @@ -787,18 +793,22 @@ rx_sdu(const module_id_t enb_mod_idP, LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_body_t *hi_dci0_req = - &mac->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + - hi_dci0_req->number_of_hi]; + &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; - hi_dci0_req->number_of_hi++; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */ if ((num_sdu == 0) && (num_ce == 0)) { @@ -1052,7 +1062,6 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, // Msg3 is using 1 PRB so we need to increase first_rb accordingly // not sure about the break (can there be more than 1 active RA procedure?) - for (i = 0; i < NB_RA_PROC_MAX; i++) { if ((cc->ra[i].state == WAITMSG3) && (cc->ra[i].Msg3_subframe == sched_subframe)) { @@ -1144,19 +1153,19 @@ schedule_ulsch_rnti(module_id_t module_idP, if (sched_subframeP < subframeP) sched_frame++; - nfapi_hi_dci0_request_body_t *hi_dci0_req = - &mac->HI_DCI0_req[CC_id].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - nfapi_ul_config_request_body_t *ul_req_tmp = - &mac->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; + nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; + nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; - LOG_D(MAC, "entering ulsch preprocesor\n"); + //LOG_D(MAC, "entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor(module_idP, frameP, subframeP, first_rb); - LOG_D(MAC, "exiting ulsch preprocesor\n"); + //LOG_D(MAC, "exiting ulsch preprocesor\n"); - mac->HI_DCI0_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; // loop over all active UEs for (UE_id = UE_list->head_ul; UE_id >= 0; @@ -1285,7 +1294,11 @@ schedule_ulsch_rnti(module_id_t module_idP, if (status < RRC_CONNECTED) cqi_req = 0; else if (UE_sched_ctrl->cqi_req_timer > 30) { - cqi_req = 1; + if (nfapi_mode) { + cqi_req = 0; + } else { + cqi_req = 1; + } UE_sched_ctrl->cqi_req_timer = 0; } else cqi_req = 0; @@ -1418,20 +1431,13 @@ schedule_ulsch_rnti(module_id_t module_idP, // save it for a potential retransmission UE_template->cshift[harq_pid] = cshift; - hi_dci0_pdu = - &hi_dci0_req->hi_dci0_pdu_list[mac->HI_DCI0_req - [CC_id]. - hi_dci0_request_body. - number_of_dci + - mac->HI_DCI0_req - [CC_id]. - hi_dci0_request_body. - number_of_hi]; + 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 = @@ -1458,8 +1464,13 @@ schedule_ulsch_rnti(module_id_t module_idP, hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - mac->HI_DCI0_req[CC_id].hi_dci0_request_body. - number_of_dci++; + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + + hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", @@ -1467,7 +1478,7 @@ schedule_ulsch_rnti(module_id_t module_idP, sched_frame, sched_subframeP); // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id], // resource_block_start rb_table[rb_table_index], // number_of_resource_blocks UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms 0, // frequency_hopping_enabled_flag @@ -1485,23 +1496,30 @@ schedule_ulsch_rnti(module_id_t module_idP, [rb_table_index])); #ifdef Rel14 if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions 1, //repetition_number (frameP * 10) + subframeP); } #endif - ul_req_tmp->number_of_pdus++; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->number_of_pdus++; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; mac->ul_handle++; + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; + + add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED); - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", - module_idP, CC_id, frameP, subframeP, UE_id); + //LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); + LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); // increment first rb for next UE allocation first_rb[CC_id] += rb_table[rb_table_index]; @@ -1515,23 +1533,24 @@ schedule_ulsch_rnti(module_id_t module_idP, // fill in NAK information - hi_dci0_pdu = - &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req-> - number_of_dci + - hi_dci0_req-> - number_of_hi]; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = UE_template->first_rb_ul[harq_pid]; hi_dci0_pdu->hi_pdu.hi_pdu_rel8. cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req->number_of_hi++; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); + hi_dci0_req->sfn_sf = frameP<<4|subframeP; + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + LOG_D(MAC, "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, round %d)\n", module_idP, harq_pid, rnti, CC_id, frameP, @@ -1544,7 +1563,7 @@ schedule_ulsch_rnti(module_id_t module_idP, "[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); - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms 0, // frequency_hopping_enabled_flag @@ -1559,16 +1578,23 @@ schedule_ulsch_rnti(module_id_t module_idP, TBS_UL[harq_pid]); #ifdef Rel14 if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions 1, //repetition_number (frameP * 10) + subframeP); } #endif - ul_req_tmp->number_of_pdus++; + 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); } /* else if (round > 0) { //we schedule a retransmission diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/extern.h index 790f89d2c7..90b5864ba1 100644 --- a/openair2/LAYER2/MAC/extern.h +++ b/openair2/LAYER2/MAC/extern.h @@ -32,10 +32,6 @@ #ifndef __MAC_EXTERN_H__ #define __MAC_EXTERN_H__ - -#ifdef USER_MODE -//#include "stdio.h" -#endif //USER_MODE #include "PHY/defs.h" #include "defs.h" diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 534f603dfd..2ad3e6a038 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -47,6 +47,7 @@ #include "common/ran_context.h" extern RAN_CONTEXT_t RC; +extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR { @@ -118,7 +119,7 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, } -void mac_top_init_eNB() +void mac_top_init_eNB(void) { module_id_t i, j; @@ -247,10 +248,6 @@ int rlcmac_init_global_param(void) void mac_top_cleanup(void) { -#ifndef USER_MODE - pdcp_module_cleanup(); -#endif - if (NB_UE_INST > 0) { free(UE_mac_inst); } @@ -275,7 +272,7 @@ l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, return (1); } -int l2_init_eNB() +int l2_init_eNB(void) { diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index f5980d60d3..49cdbb1769 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -59,12 +59,6 @@ //#define ICIC 0 -/* - #ifndef USER_MODE - #define msg debug_msg - #endif -*/ - /* this function checks that get_eNB_UE_stats returns * a non-NULL pointer for all the active CCs of an UE */ diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 5b73a76312..7a9b811d0e 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -71,11 +71,6 @@ extern uint8_t usim_test; -/* -#ifndef USER_MODE -#define msg debug_msg -#endif - */ mapping BSR_names[] = { {"NONE", 0}, {"SHORT BSR", 1}, diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h index 01ece20d48..6c950fb841 100644 --- a/openair2/LAYER2/MAC/vars.h +++ b/openair2/LAYER2/MAC/vars.h @@ -32,9 +32,6 @@ #ifndef __MAC_VARS_H__ #define __MAC_VARS_H__ -#ifdef USER_MODE -//#include "stdio.h" -#endif //USER_MODE #include "PHY/defs.h" #include "defs.h" #include "COMMON/mac_rrc_primitives.h" diff --git a/openair2/LAYER2/Makefile.inc b/openair2/LAYER2/Makefile.inc index c0e4df5617..2f5cea7555 100644 --- a/openair2/LAYER2/Makefile.inc +++ b/openair2/LAYER2/Makefile.inc @@ -54,10 +54,6 @@ SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_reassembly.c SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_receiver.c SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_dar.c -ifeq ($(OPENAIR_EMU),1) -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_very_simple_test.c -endif - SOURCES_L2 += $(RLC_DIR)/rlc_mac.c SOURCES_L2 += $(RLC_DIR)/rlc.c SOURCES_L2 += $(RLC_DIR)/rlc_rrc.c diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 894abeb100..7023defc43 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -30,9 +30,6 @@ #define PDCP_C //#define DEBUG_PDCP_FIFO_FLUSH_SDU -#ifndef USER_MODE -#include -#endif #include "assertions.h" #include "hashtable.h" #include "pdcp.h" @@ -64,9 +61,7 @@ # include "gtpv1u.h" #endif -#ifndef OAI_EMU extern int otg_enabled; -#endif #include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -441,11 +436,6 @@ pdcp_data_ind( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP); - -#endif #ifdef PDCP_MSG_PRINT int i=0; LOG_F(PDCP,"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); @@ -693,49 +683,6 @@ pdcp_data_ind( payload_offset=0; } -#if defined(USER_MODE) && defined(OAI_EMU) - - if (oai_emulation.info.otg_enabled == 1) { - //unsigned int dst_instance; - int ctime; - - if ((pdcp_p->rlc_mode == RLC_MODE_AM)&&(MBMS_flagP==0) ) { - pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; - } - -#if defined(DEBUG_PDCP_PAYLOAD) - rlc_util_print_hex_octets(PDCP, - (unsigned char*)&sdu_buffer_pP->data[payload_offset], - sdu_buffer_sizeP - payload_offset); -#endif - - ctime = oai_emulation.info.time_ms; // avg current simulation time in ms : we may get the exact time through OCG? - if (MBMS_flagP == 0){ - LOG_D(PDCP, - PROTOCOL_PDCP_CTXT_FMT"Check received buffer : (dst %d)\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), - ctxt_pP->instance); - } - if (otg_rx_pkt( - ctxt_pP->instance, - ctime, - (const char*)(&sdu_buffer_pP->data[payload_offset]), - sdu_buffer_sizeP - payload_offset ) == 0 ) { - free_mem_block(sdu_buffer_pP, __func__); - - if (ctxt_pP->enb_flag) { - stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_ind); - } else { - stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_ind); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; - } - } - -#else - if (otg_enabled==1) { LOG_D(OTG,"Discarding received packed\n"); free_mem_block(sdu_buffer_pP, __func__); @@ -750,9 +697,6 @@ pdcp_data_ind( return TRUE; } -#endif - - // XXX Decompression would be done at this point /* @@ -811,22 +755,15 @@ pdcp_data_ind( // set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here if (ctxt_pP->enb_flag == ENB_FLAG_NO) { ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id; -#if defined(OAI_EMU) - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local; -#else -# if defined(ENABLE_USE_MME) +#if defined(ENABLE_USE_MME) /* for the UE compiled in S1 mode, we need 1 here * for the UE compiled in noS1 mode, we need 0 * TODO: be sure of this */ ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; -# endif #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); -#if defined(OAI_EMU) - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id - oai_emulation.info.first_enb_local; -#endif } #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU static uint32_t pdcp_inst = 0; @@ -998,11 +935,6 @@ pdcp_run ( itti_send_msg_to_task(TASK_MAC_ENB, 3, msg_resp_p); } # endif -#endif - -#if defined(USER_MODE) && defined(OAI_EMU) - pdcp_fifo_read_input_sdus_from_otg(ctxt_pP); - #endif // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 452343b967..eb060e8535 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -33,14 +33,11 @@ #define PDCP_DEBUG 1 //#define DEBUG_PDCP_FIFO_FLUSH_SDU -#ifndef OAI_EMU extern int otg_enabled; -#endif #include "pdcp.h" #include "pdcp_primitives.h" -#ifdef USER_MODE #include #include #include @@ -48,9 +45,6 @@ extern int otg_enabled; #include #define rtf_put write #define rtf_get read -#else -#include -#endif //USER_MODE #include "../MAC/extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" @@ -92,6 +86,8 @@ extern Packet_OTG_List_t *otg_pdcp_buffer; # include "gtpv1u_eNB_defs.h" #endif +extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP); + /* Prevent de-queueing the same PDCP SDU from the queue twice * by multiple threads. This has happened in TDD when thread-odd * is flushing a PDCP SDU after UE_RX() processing; whereas @@ -166,11 +162,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) threadname, ctxt_pP->frame, ctxt_pP->subframe, ((pdcp_data_ind_header_t*) sdu_p->data)->inst, ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); -#else -#if ! defined(OAI_EMU) - /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ -// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; -#endif #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) @@ -551,29 +542,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); #endif -#ifdef OAI_EMU - - // overwrite function input parameters, because only one netlink socket for all instances - if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_YES; - ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pdcp_read_header_g.rb_id % maxDRB; - } else { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_NO; - ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; - ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pdcp_read_header_g.rb_id % maxDRB; - } - - CHECK_CTXT_ARGS(&ctxt); - AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); - /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \ - pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : - pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ -#else // OAI_EMU /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ // pdcp_read_header_g.inst = 0; //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" @@ -594,9 +562,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } - -#endif - if (ctxt.enb_flag) { if (rab_id != 0) { rab_id = rab_id % maxDRB; @@ -808,121 +773,8 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) module_id_t dst_id; // dst for otg rb_id_t rb_id; unsigned int pkt_size=0; -#if defined(USER_MODE) && defined(OAI_EMU) - module_id_t src_id; - static unsigned int pkt_cnt_enb=0, pkt_cnt_ue=0; - - Packet_otg_elt_t *otg_pkt_info=NULL; - int result; - uint8_t pdcp_mode, is_ue=0; -#endif protocol_ctxt_t ctxt; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. -#if defined(USER_MODE) && defined(OAI_EMU) - - if (oai_emulation.info.otg_enabled ==1 ) { - // module_id is source id - while ((otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[ctxt_pP->instance]))) != NULL) { - LOG_I(OTG,"Mod_id %d Frame %d Got a packet (%p), HEAD of otg_pdcp_buffer[%d] is %p and Nb elements is %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - otg_pkt_info, - ctxt_pP->instance, - pkt_list_get_head(&(otg_pdcp_buffer[ctxt_pP->instance])), - otg_pdcp_buffer[ctxt_pP->instance].nb_elements); - //otg_pkt_info = pkt_list_remove_head(&(otg_pdcp_buffer[module_id])); - dst_id = (otg_pkt_info->otg_pkt).dst_id; // type is module_id_t - src_id = (otg_pkt_info->otg_pkt).module_id; // type is module_id_t - rb_id = (otg_pkt_info->otg_pkt).rb_id; - is_ue = (otg_pkt_info->otg_pkt).is_ue; - pdcp_mode = (otg_pkt_info->otg_pkt).mode; - // LOG_I(PDCP,"pdcp_fifo, pdcp mode is= %d\n",pdcp_mode); - - // generate traffic if the ue is rrc reconfigured state - // if (mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id ) > 2 /*RRC_CONNECTED*/) { // not needed: this test is already done in update_otg_enb - otg_pkt = (unsigned char*) (otg_pkt_info->otg_pkt).sdu_buffer; - pkt_size = (otg_pkt_info->otg_pkt).sdu_buffer_size; - - if (otg_pkt != NULL) { - if (is_ue == 0 ) { - PROTOCOL_CTXT_SET_BY_MODULE_ID( - &ctxt, - src_id, - ENB_FLAG_YES, - oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id], - ctxt_pP->frame, - ctxt_pP->subframe, - src_id); - - LOG_D(OTG,"[eNB %d] Frame %d sending packet %d from module %d on rab id %d (src %d, dst %d/%x) pkt size %d for pdcp mode %d\n", - ctxt.module_id, - ctxt.frame, - pkt_cnt_enb++, - src_id, - rb_id, - src_id, - dst_id, - oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id], - pkt_size, - pdcp_mode); - result = pdcp_data_req(&ctxt, - SRB_FLAG_NO, - rb_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pkt_size, - otg_pkt, - pdcp_mode); - if (result != TRUE) { - LOG_W(OTG,"PDCP data request failed!\n"); - } - } else { - //rb_id= eNB_index * MAX_NUM_RB + DTCH; - - - LOG_D(OTG,"[UE %d] Frame %d: sending packet %d from module %d on rab id %d (src %d/%x, dst %d) pkt size %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - pkt_cnt_ue++, - ctxt_pP->module_id, - rb_id, - src_id, - pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id], // [src_id] - dst_id, - pkt_size); - PROTOCOL_CTXT_SET_BY_MODULE_ID( - &ctxt, - ctxt_pP->module_id, //src_id, - ENB_FLAG_NO, - pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id],// [src_id] - ctxt_pP->frame, - ctxt_pP->subframe, - dst_id); - - result = pdcp_data_req( &ctxt, - SRB_FLAG_NO, - rb_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pkt_size, - otg_pkt, - PDCP_TRANSMISSION_MODE_DATA); - if (result != TRUE) { - LOG_W(OTG,"PDCP data request failed!\n"); - } - } - - free(otg_pkt); - otg_pkt = NULL; - } - - // } //else LOG_D(OTG,"ctxt_pP->frame %d enb %d-> ue %d link not yet established state %d \n", ctxt_pP->frame, eNB_index,dst_id - NB_eNB_INST, mac_get_rrc_status(module_id, ctxt_pP->enb_flag, dst_id - NB_eNB_INST)); - - } - } - -#else - if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic unsigned int ctime=0; ctime = ctxt_pP->frame * 100; @@ -971,6 +823,4 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) } } } - -#endif } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c index eddd42c34b..0df8e59e6d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c @@ -101,13 +101,8 @@ pdcp_netlink_init( struct sched_param sched_param; reset_meas(&ip_pdcp_stats_tmp); -#if defined(USER_MODE) && defined(OAI_EMU) - nb_inst_enb = oai_emulation.info.nb_enb_local; - nb_inst_ue = oai_emulation.info.nb_ue_local; -#else nb_inst_enb = 1; nb_inst_ue = 1; -#endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) nb_inst_enb = 0; @@ -259,24 +254,7 @@ void *pdcp_netlink_thread_fct(void *arg) } } else { pdcp_thread_read_state = 0; - -#ifdef OAI_EMU - - // LG: new_data_p->pdcp_read_header.inst will contain in fact a module id - if (new_data_p->pdcp_read_header.inst >= oai_emulation.info.nb_enb_local) { - module_id = new_data_p->pdcp_read_header.inst - - oai_emulation.info.nb_enb_local + - + oai_emulation.info.first_ue_local; - eNB_flag = 0; - } else { - module_id = new_data_p->pdcp_read_header.inst - + oai_emulation.info.first_enb_local; - eNB_flag = 1; - } - -#else module_id = 0; -#endif new_data_p->data = malloc(sizeof(uint8_t) * new_data_p->pdcp_read_header.data_size); /* Copy the data */ memcpy(new_data_p->data, NLMSG_DATA(nas_nlh_rx), new_data_p->pdcp_read_header.data_size); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c index 0200ffdbf8..0b6be93d59 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_thread.c @@ -110,9 +110,7 @@ int init_pdcp_thread(void) p.sched_priority = OPENAIR_THREAD_PRIORITY; pthread_attr_setschedparam (&pdcp_thread_attr, &p); -#ifndef RTAI_ISNT_POSIX pthread_attr_setschedpolicy (&pdcp_thread_attr, SCHED_FIFO); -#endif pthread_mutex_init(&pdcp_mutex,NULL); pthread_cond_init(&pdcp_cond,NULL); 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 131d56e1f8..5130bde38b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -73,10 +73,6 @@ # include "RLC-Config.h" //# include "rlc_am_test.h" -#ifdef USER_MODE -//# include "rlc_am_very_simple_test.h" -#endif - #define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]" #define PROTOCOL_RLC_AM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index f6dd0c5809..01a635656e 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -21,9 +21,7 @@ #define RLC_AM_MODULE 1 #define RLC_AM_INIT_C 1 -#ifdef USER_MODE #include -#endif //----------------------------------------------------------------------------- #include "rlc_am.h" #include "LAYER2/MAC/extern.h" diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index addc949d35..d0b5b52395 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -268,11 +268,9 @@ rlc_am_reassemble_pdu( //} break; -#if USER_MODE default: assert(0 != 0); -#endif } } else { switch (pdu_info->fi) { @@ -382,19 +380,13 @@ rlc_am_reassemble_pdu( if (pdu_info->hidden_size > 0) { // normally should always be > 0 but just for help debug // data is already ok, done by last loop above rlc_am_reassembly (ctxt_pP, rlc_pP, &pdu_info->payload[j], pdu_info->hidden_size); - } else { -#if USER_MODE - //assert (5!=5); -#endif } //rlc_pP->reassembly_missing_sn_detected = 0; break; -#if USER_MODE default: assert(1 != 1); -#endif } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index afce72b455..c16e897bb6 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -22,9 +22,7 @@ #define RLC_AM_MODULE 1 #define RLC_AM_SEGMENT_C 1 //----------------------------------------------------------------------------- -#if USER_MODE #include -#endif //----------------------------------------------------------------------------- #include "platform_types.h" //----------------------------------------------------------------------------- @@ -468,9 +466,7 @@ void rlc_am_segment_10 ( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); -#if USER_MODE assert(1!=1); -#endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size; pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index a6c340a165..147fd44d07 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -36,9 +36,7 @@ # include "list.h" # include "mem_block.h" # include "rlc_am_constants.h" -//#ifdef USER_MODE # include "mac_rlc_primitives.h" -//#endif //USER_MODE # include "mac_primitives.h" # include "rlc_primitives.h" /** diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_windows.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_windows.c index f0cacc2874..7a3005334e 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_windows.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_windows.c @@ -22,9 +22,7 @@ #define RLC_AM_MODULE 1 #define RLC_AM_WINDOWS_C 1 //----------------------------------------------------------------------------- -#if USER_MODE #include -#endif //----------------------------------------------------------------------------- #include "platform_types.h" //----------------------------------------------------------------------------- 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 2e1629f8c8..7bd0da83a9 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -682,10 +682,6 @@ rlc_um_data_req (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP, mem_block_t { rlc_um_entity_t *rlc_p = (rlc_um_entity_t *) rlc_pP; -#if ! USER_MODE - unsigned long int rlc_um_time_us; - int min, sec, usec; -#endif #if TRACE_RLC_UM_PDU #if ENABLE_ITTI MessageDef *msg_p; 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 c7754f587a..abf4f8ad6e 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -64,9 +64,6 @@ # include "rlc_um_receiver.h" # include "rlc_um_segment.h" # include "rlc_um_test.h" -#ifdef USER_MODE -//# include "rlc_um_very_simple_test.h" -#endif #define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] %s()" #define PROTOCOL_RLC_UM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c index 468a7d062a..91e1ba66d1 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_reassembly.c @@ -23,9 +23,7 @@ #define RLC_UM_REASSEMBLY_C 1 #include "platform_types.h" //----------------------------------------------------------------------------- -#if USER_MODE #include -#endif #if ENABLE_ITTI # include "platform_types.h" # include "intertask_interface.h" diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c index 4d4362251e..f9af7c1cc2 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c @@ -25,9 +25,7 @@ #include "platform_types.h" #include "platform_constants.h" //----------------------------------------------------------------------------- -#if USER_MODE #include -#endif #include "assertions.h" #include "msc.h" #include "list.h" @@ -367,10 +365,8 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); #endif -#if USER_MODE #if !EXMIMO assert(1!=1); -#endif #endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); // reduce the size of the PDU @@ -754,9 +750,7 @@ rlc_um_segment_5 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP) sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); #endif -#if USER_MODE assert(1!=1); -#endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); // reduce the size of the PDU continue_fill_pdu_with_sdu = 0; diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_structs.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_structs.h index a5425cb8a0..7ab9798a38 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_structs.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_structs.h @@ -36,9 +36,7 @@ # include "rlc_um_constants.h" # include "mac_primitives.h" # include "rlc_primitives.h" -//#ifdef USER_MODE # include "mac_rlc_primitives.h" -//#endif //USER_MODE //----------------------- /** * @addtogroup _rlc_um_impl_ diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index d70d85f2d5..d27d46ff42 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -135,11 +135,6 @@ rlc_op_status_t rlc_stat_req ( hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP) - -#endif AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); @@ -346,11 +341,6 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, #else AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP); #endif -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP) - -#endif #if T_TRACER if (ctxt_pP->enb_flag) diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 7c1ebab2be..b38da4dd5b 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -663,10 +663,6 @@ public_rlc(rlc_op_status_t rlc_stat_req ( public_rlc(int rlc_module_init(void);) /** @} */ -#ifndef USER_MODE -#define assert(x) ((x)?msg("rlc assertion fails\n"):0) -#endif - #define RLC_FG_COLOR_BLACK "\e[0;30m" #define RLC_FG_COLOR_RED "\e[0;31m" diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index d49393d959..5e5f0161da 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -157,13 +157,6 @@ tbs_size_t mac_rlc_data_req( AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n", channel_idP, NB_RB_MAX); } -#ifdef OAI_EMU - CHECK_CTXT_ARGS(&ctxt); - //printf("MBMS_flagP %d, MBMS_FLAG_NO %d \n",MBMS_flagP, MBMS_FLAG_NO); - // AssertFatal (MBMS_flagP == MBMS_FLAG_NO ," MBMS FLAG SHOULD NOT BE SET IN mac_rlc_data_req in UE\n"); - -#endif - if (MBMS_flagP) { if (enb_flagP) { mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP]; @@ -256,18 +249,6 @@ void mac_rlc_data_ind ( } #endif // DEBUG_MAC_INTERFACE -#ifdef OAI_EMU - - if (MBMS_flagP) - AssertFatal (channel_idP < RLC_MAX_MBMS_LC, "channel id is too high (%u/%d)!\n", - channel_idP, RLC_MAX_MBMS_LC); - else - AssertFatal (channel_idP < NB_RB_MAX, "channel id is too high (%u/%d)!\n", - channel_idP, NB_RB_MAX); - - CHECK_CTXT_ARGS(&ctxt); - -#endif #if T_TRACER if (enb_flagP) @@ -347,31 +328,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind( memset (&mac_rlc_status_resp, 0, sizeof(mac_rlc_status_resp_t)); memset (&tx_status , 0, sizeof(struct mac_status_ind)); -#ifdef OAI_EMU - - if (MBMS_flagP) - AssertFatal (channel_idP < RLC_MAX_MBMS_LC, - "%s channel id is too high (%u/%d) enb module id %u ue %u!\n", - (enb_flagP) ? "eNB" : "UE", - channel_idP, - RLC_MAX_MBMS_LC, - module_idP, - rntiP); - else - AssertFatal (channel_idP < NB_RB_MAX, - "%s channel id is too high (%u/%d) enb module id %u ue %u!\n", - (enb_flagP) ? "eNB" : "UE", - channel_idP, - NB_RB_MAX, - module_idP, - rntiP); - - CHECK_CTXT_ARGS(&ctxt); - -#endif - - - if (MBMS_flagP) { if (enb_flagP) { mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP]; diff --git a/openair2/LAYER2/RLC/rlc_primitives.h b/openair2/LAYER2/RLC/rlc_primitives.h index 8d679ab9aa..eb7b9ae005 100644 --- a/openair2/LAYER2/RLC/rlc_primitives.h +++ b/openair2/LAYER2/RLC/rlc_primitives.h @@ -31,10 +31,8 @@ #ifndef __RLC_PRIMITIVES_H__ # define __RLC_PRIMITIVES_H__ -# ifdef USER_MODE -# include -# include -# endif +# include +# include # include "platform_types.h" # include "platform_constants.h" # include "mem_block.h" diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 68f5971bf1..dee6ba7000 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -33,9 +33,6 @@ #include "rlc_um.h" #include "rlc_tm.h" #include "UTIL/LOG/log.h" -#ifdef OAI_EMU -#include "UTIL/OCG/OCG_vars.h" -#endif #include "RLC-Config.h" #include "DRB-ToAddMod.h" #include "DRB-ToAddModList.h" @@ -88,12 +85,6 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ ASN1 \n", PROTOCOL_CTXT_ARGS(ctxt_pP)); -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP) - -#endif - if (srb2add_listP != NULL) { for (cnt=0; cntlist.count; cnt++) { rb_id = srb2add_listP->list.array[cnt]->srb_Identity; @@ -489,10 +480,6 @@ rlc_op_status_t rrc_rlc_remove_rlc ( rlc_union_t *rlc_union_p = NULL; #if defined(Rel10) || defined(Rel14) rlc_mbms_id_t *mbms_id_p = NULL; -#endif -#ifdef OAI_EMU - CHECK_CTXT_ARGS(ctxt_pP) - #endif /* for no gcc warnings */ @@ -597,12 +584,6 @@ rlc_union_t* rrc_rlc_add_rlc ( logical_chan_id_t lcid = 0; #endif -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP) - -#endif - if (MBMS_flagP == FALSE) { AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); @@ -706,11 +687,6 @@ rlc_op_status_t rrc_rlc_config_req ( PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); -#ifdef OAI_EMU - - CHECK_CTXT_ARGS(ctxt_pP) - -#endif AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); switch (actionP) { diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index a5a8135fed..a3e8e2164a 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -29,21 +29,7 @@ # @ingroup _openair2 */ -#ifdef USER_MODE -# include -#else -#include -#include -#include - -# ifndef PRIu64 -# if __WORDSIZE == 64 -# define PRIu64 "lu" -# else -# define PRIu64 "llu" -# endif -# endif -#endif +#include #include "LAYER2/RLC/rlc.h" #include "LAYER2/MAC/defs.h" @@ -410,11 +396,7 @@ int dump_eNB_l2_stats(char *buffer, int length) } #ifdef PROC -#ifndef USER_MODE -static int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) -#else int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) -#endif { int len = 0,fg,Overhead, Sign; @@ -697,36 +679,4 @@ int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) return len; } -#ifndef USER_MODE -static struct proc_dir_entry *proc_openair2_root; -/* - * Initialize the module and add the /proc file. - */ -int add_openair2_stats() -{ - struct proc_dir_entry *pde; - - proc_openair2_root = proc_mkdir("openair2",0); - // pde = proc_create_entry("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root); - pde = proc_create_data("lchan_stats", S_IFREG | S_IRUGO, proc_openair2_root, NULL,openair2_stats_read); - - if (!pde) { - printk("[OPENAIR][ERROR] can't create proc entry !\n"); - } - - return 0; -} -/* - * Unregister the file when the module is closed. - */ -void remove_openair_stats() -{ - - if (proc_openair2_root) { - printk("[OPENAIR][CLEANUP] Removing openair proc entry\n"); - remove_proc_entry("lchan_stats", proc_openair2_root); - - } -} -#endif #endif diff --git a/openair2/LAYER2/register.c b/openair2/LAYER2/register.c deleted file mode 100644 index 964666875a..0000000000 --- a/openair2/LAYER2/register.c +++ /dev/null @@ -1,81 +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 - */ - -/*________________________rrc_register.c________________________ - - Authors : Hicham Anouar, Raymond Knopp - Company : EURECOM - Emails : anouar@eurecom.fr, knopp@eurecom.fr -________________________________________________________________*/ - - -#ifndef USER_MODE -#define __NO_VERSION__ -#else -#include -#include - -#include -#endif - -#include "COMMON/openair_types.h" -#include "MAC/extern.h" - -#include - -#ifndef USER_MODE - -//-----------------------------------------------------------------------------------------------------------// -MAC_RLC_XFACE* mac_rrc_register(RRC_XFACE* RRC_xface) -{ - //-----------------------------------------------------------------------------------------------------------// - if(Is_rrc_registered) { - msg("[OPENAIR][MAC][RRC_REGISTER] RRC interface already registered, aborting ...\n"); - return NULL; - } else { - msg("[OPENAIR][MAC][RRC_REGISTER] Registering RRC Interface, Mac_rlc_xface=%p\n",Mac_rlc_xface); - Rrc_xface=RRC_xface; - Is_rrc_registered=1; - return Mac_rlc_xface; - } -} - -//-----------------------------------------------------------------------------------------------------------// -int mac_rrc_unregister(RRC_XFACE *RRC_xface) -{ - //-----------------------------------------------------------------------------------------------------------// - if (Rrc_xface == RRC_xface) { - msg("[OPENAIR][MAC XFACE][RRC_UNREGISTER] Unregistering RRC interface\n"); - Rrc_xface=NULL; - Is_rrc_registered=0; - return(0); - } else { - msg("[OPENAIR][MAC XFACE][RRC_UNREGISTER] Not the right interface descriptor pointer!!!, aborting ...\n"); - return (-1); - } - -} - -EXPORT_SYMBOL(mac_rrc_register); -EXPORT_SYMBOL(mac_rrc_unregister); -#endif //USER_MODE - - diff --git a/openair2/Makefile b/openair2/Makefile deleted file mode 100755 index 2fbeb193a6..0000000000 --- a/openair2/Makefile +++ /dev/null @@ -1,254 +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 -# */ - -#################################################### -# USER SPACE CODE GENERATION -#################################################### - -#--------------------------------------------------- -# -#--------------------------------------------------- - - -#LM_LICENSE_FILE= -#export LM_LICENSE_FILE -include $(OPENAIR_DIR)/common/utils/Makefile.inc - -KERNEL_NAME:=$(shell uname -r) -NUM_CORES=$(shell getconf _NPROCESSORS_CONF) - -export SET_UM=$(shell if grep --silent User\ Mode\ Linux /proc/cpuinfo ; then echo "ARCH=um" ; else echo ""; fi) - -#SUBDIRS_openair_USERRF = $(MAIN_RT_DIR) $(CONFIG_DIR) - -#openair_USERRFDIR = openair_RFOBJS -#openair_USERRFLIBS = $(addsuffix /${openair_USERRFDIR}/Lib.a, ${SUBDIRS_openair_USERRF}) -#openair_USERRFOBJS = $(addsuffix /${openair_USERRFDIR}/*.o, ${SUBDIRS_openair_USERRF}) -#openair_USERRFDEPS = $(addsuffix /${openair_USERRFDIR}/*.d, ${SUBDIRS_openair_USERRF}) - -mac_sim_no_netlink: - ( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim MASTER=1) - -mac_sim: - ( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim MASTER=1 NETLINK=1 NO_RRM=1) - -mac_sim_rrm: - ( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_rrm MASTER=1 NETLINK=1) - -mac_sim_mt_cellular: - ( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_mt CELLULAR=1 NO_RRM=1) - -mac_sim_rg_cellular: - ( cd SIMULATION/USER_TOOLS/LAYER2_SIM && make mac_sim_rg MASTER=1 CELLULAR=1 NO_RRM=1) - -openair_layer2_emul.ko: - (cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` NO_RRM=1 PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 PHYEMUL=1 && mv openair_l2.ko openair_layer2.ko) - -openair_layer2_emul_rrm.ko: - (cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 PHYEMUL=1 && mv openair_l2.ko openair_layer2.ko) - - -openair_layer2.ko: - (cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` NO_RRM=1 PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2.ko) - -openair_layer2_rrm.ko: - (cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2.ko) - -openair_layer2_2615.ko: - (cd LAYER2 && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 MASTER=1 OPEN_AIR=1 OPENAIR1=1 && mv openair_l2.ko openair_layer2_2615.ko) - - -openair_rrc.ko: - (cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 NO_RRM=1 && mv openair_rrc.ko openair_RRC.ko) - -openair_rrc_rrm.ko: - (cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 && mv openair_rrc.ko openair_RRC.ko) - - -openair_rrc_2615.ko: - (cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 && mv openair_rrc.ko openair_RRC_2615.ko) - -openair_rrc_emul.ko: - (cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 PHYEMUL=1 NO_RRM=1) - -openair_rrc_emul_rrm.ko: - (cd RRC/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 PHYEMUL=1) - - -openair_emul.ko: - (cd SIMULATION/PHY_EMULATION/DEVICE_DRIVER/ && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1 NO_RRM=1) - -openair_emul_rrm.ko: - (cd SIMULATION/PHY_EMULATION/DEVICE_DRIVER/ && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` PCTARGET=1 RTAI=1 OPEN_AIR=1 MASTER=1) - - - -create_device: - rm -f /dev/openair0 - mknod /dev/openair0 c 127 0 - chmod a+rw /dev/openair0 - - -install_emul: - make devs - make fifos - (insmod SIMULATION/PHY_EMULATION/DEVICE_DRIVER/openair_emul.ko) - (insmod LAYER2/openair_layer2.ko) - (insmod RRC/MESH/openair_rrc.ko) - (insmod NETWORK_DRIVER/MESH/nasmesh.ko) - -remove_emul: - rmmod nasmesh - sleep 1 - rmmod openair_rrc - sleep 1 - rmmod openair_l2 - sleep 1 - rmmod openair_emul - - -clean_nasmesh: - (cd NETWORK_DRIVER/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` clean) - -nasmesh_address_fix.ko: - (cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) V=1 ADDRESS_FIX=1 -C $(KERNEL_DIR)/build M=`pwd`) - -nasmesh.ko: - (cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) V=1 -C $(KERNEL_DIR)/build M=`pwd`) - -# automatically detect the linux header files for driver compilation -nasmesh_netlink.ko: - (cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -naslite_netlink_ether.ko: - (cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -oai_nw_ether.ko: - (cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -oai_nw_drv.ko: - (cd NETWORK_DRIVER/LITE && $(MAKE) -j$(NUM_CORES) $(SET_UM) OAI_NW_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -nasmesh_netlink_address_fix.ko: - (cd NETWORK_DRIVER/MESH && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 ADDRESS_FIX=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - - -nasmesh_netlink_loopback.ko: - (cd NETWORK_DRIVER/MESH && $(MAKE) $(SET_UM) PDCP_USE_NETLINK=1 LOOPBACK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -# drivers cellular version -nascellmt_netlink.ko: - (cd NAS/DRIVER/CELLULAR/NASMT && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -nascellmt_clean.ko: - (cd NAS/DRIVER/CELLULAR/NASMT && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` clean) - -nascellrg_netlink.ko: - (cd NAS/DRIVER/CELLULAR/NASRG && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - -nascellrg_clean.ko: - (cd NAS/DRIVER/CELLULAR/NASRG && $(MAKE) -j$(NUM_CORES) $(SET_UM) NAS_DRIVER_TYPE_ETHERNET=1 PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` clean) - -# Driver for UE using LTE core network (MME, S+P-GW) -ue_ip.ko: - (cd NETWORK_DRIVER/UE_IP && $(MAKE) -j$(NUM_CORES) $(SET_UM) PDCP_USE_NETLINK=1 OAI_NW_DRIVER_USE_NETLINK=1 V=1 -C $(KERNEL_DIR)/build M=`pwd` modules) - - -rt_emul: - (cd SIMULATION/USER_TOOLS/RT_EMUL_LAUNCHER && $(MAKE)) - -bypass_phy: - (cd SIMULATION/PHY_EMULATION/TRANSPORT/KERNEL_INTERFACE && $(MAKE)) - -rb_tool: - (cd NETWORK_DRIVER/MESH/RB_TOOL && $(MAKE)) - - -fifos: - @for i in `seq 0 64`;\ - do \ - have_rtfX=`ls /dev/ |grep -c rtf$$i`;\ - if [ "$$have_rtfX" -eq 0 ] ;then \ - mknod -m 666 /dev/rtf$$i c 150 $$i; \ - fi;\ - done - -# cp arch/openair_CardBus_MIMO1/device_driver/openair_rf.ko $(KERNEL_DIR)/openair/ -# depmod -aq - -devs: - if ! test -a /dev/openair0;\ - then \ - mknod /dev/openair0 c 127 0;\ - chmod a+rw /dev/openair0;\ - fi; - -load_sounder_ue: install_cbmimo1_ublaze - insmod mac/chansounder/openair_chansounder_ue.ko - -load_sounder_nodeb: install_platon - (cd openair_rf && ./openair_rf_platon 1917600 0 ../arch/platon/rbt_files/DAQ_B.rbt 30p 15p 10p 25p && ./openair_rf_platon 1917600 0 ../arch/platon/rbt_files/daq_platon_11_2005.rbt 30p 15p 10p 25p) - - -stop_sounder: - rmmod openair_chansounder - rmmod openair_rf - -stop_sounder_nodeb: - (cd openair_rf && ./openair_rf_platon 1907600 4) - rmmod openair_chansounder - rmmod openair_rf - - -emul_rt: - (cd SIMULATION/USER_TOOLS/RT_EMUL_LAUNCHER && $(MAKE)) - -clean: - (cd NETWORK_DRIVER/MESH && $(MAKE) clean) - (cd NETWORK_DRIVER/LITE && $(MAKE) clean) - rm -rf NETWORK_DRIVER/MESH/RB_TOOL/rb_tool - rm -rf NETWORK_DRIVER/LITE/RB_TOOL/rb_tool - -cleanall: - find -name *.o -delete -print - find -name *.ko -delete -print - find -name *~ -delete -print - find -name *.bak -delete -print - rm -rf NETWORK_DRIVER/MESH/RB_TOOL/rb_tool - rm -rf NETWORK_DRIVER/LITE/RB_TOOL/rb_tool - - -cleansvn: - rm -rf `find -name *.svn* -print` ; \ - find -name *.svn* -delete -print - -tgz: - mkdir /tmp/openair2_tmp; \ - $(MAKE) cleanall; \ - cp -r . /tmp/openair2_tmp; \ - (cd /tmp/openair2_tmp && $(MAKE) cleansvn && cd .. && tar czfv openair2.tgz openair2_tmp) ; \ - cp /tmp/openair2.tgz . ;\ - rm -rf /tmp/openair2_tmp - -print: - @echo $(IS_KERNEL_OPENAIRINTERFACE) - @echo $(KERNEL_DIR) - @echo $(IS_LINUX) diff --git a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/Makefile b/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/Makefile deleted file mode 100755 index 427a9fad51..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# Lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - -# You can modify the below as well, but probably -# won't need to. - -#CC = egcs - -#UPDIR := $(shell /bin/pwd) -#GRAAL_DIR =$(UPDIR)/.. -#RRC_DIR =$(UPDIR)/../../../AS/L3/RRC - -CELL_UPDIR := $(shell /bin/pwd) -NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASMT -RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR -EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_MT - -CFLAGS = -Wall -g -I$(NAS_DIR) -I$(RRC_DIR) - -COMPILE = $(CC) $(CFLAGS) -c - -OBJS = nascell_ioctl.o - -EXECUTABLE = gioctl - -# "all" is the default target. Simply make it point to myprogram. - -all: $(EXECUTABLE) - -# Define the components of the program, and how to link them together. -# These components are defined as dependencies; that is, they must be -# made up-to-date before the code is linked. - -$(EXECUTABLE): $(OBJS) - $(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJS) - -# Add any special rules here. - -# Specify that all .o files depend on .c files, and indicate how -# the .c files are converted (compiled) to the .o files. - -%.o: %.c - $(COMPILE) -o $@ $< - -clean: - -rm $(OBJS) $(EXECUTABLE) diff --git a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.c b/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.c deleted file mode 100644 index 0b520ed151..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/CTL_TOOL/nascell_ioctl.c +++ /dev/null @@ -1,859 +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 "nascell_ioctl.h" -#include "rrc_nas_primitives.h" -//#include "rrc_qos.h" -//#include "graal_local.h" -#include "nasmt_constant.h" -#include "nasmt_iocontrol.h" -#define USHRT_MAX 255 -//--------------------------------------------------------------------------- -void print_error(int status) -{ - //--------------------------------------------------------------------------- - switch(status) { - case -NAS_ERROR_NOMEMORY: - printf(" The memory is low\n"); - break; - - case -NAS_ERROR_NORB: - printf(" The radio bearer is not identified\n"); - break; - - case -NAS_ERROR_NOTMT: - printf(" The entity must be a mobile\n"); - break; - - case -NAS_ERROR_NOTRG: - printf(" The entity must be an access router\n"); - break; - - case -NAS_ERROR_NOTIDLE: - printf(" The selected connection or radio bearer must be IDLE\n"); - break; - - case -NAS_ERROR_NOTCONNECTED: - printf(" The selected connection or radio bearer must be CONNECTED\n"); - break; - - case -NAS_ERROR_NOTCORRECTLCR: - printf(" The LCR value is not correct\n"); - break; - - case -NAS_ERROR_NOTCORRECTDIR: - printf(" The DIR value is not correct\n"); - break; - - case -NAS_ERROR_NOTCORRECTDSCP: - printf(" The DSCP value is not correct\n"); - break; - - case -NAS_ERROR_NOTCORRECTVERSION: - printf(" The version value is not correct\n"); - break; - - case -NAS_ERROR_NOTCORRECTRABI: - printf(" The rab_id value is not correct\n"); - break; - - case -NAS_ERROR_ALREADYEXIST: - printf(" Some components must not be duplicated\n"); - break; - - default: - printf(" Unknown error cause %d\n", status); - } -} - -//--------------------------------------------------------------------------- -void print_state(uint8_t state) -{ - //--------------------------------------------------------------------------- - switch(state) { - case NAS_IDLE: - printf("NAS_IDLE\n"); - return; - - // case NAS_STATE_CONNECTED:printf("NAS_STATE_CONNECTED\n");return; - // case NAS_STATE_ESTABLISHMENT_REQUEST:printf("NAS_STATE_ESTABLISHMENT_REQUEST\n");return; - // case NAS_STATE_ESTABLISHMENT_FAILURE:printf("NAS_STATE_ESTABLISHMENT_FAILURE\n");return; - // case NAS_STATE_RELEASE_FAILURE:printf("NAS_STATE_RELEASE_FAILURE\n");return; - case NAS_CX_FACH: - printf("NAS_CX_FACH\n"); - return; - - case NAS_CX_DCH: - printf("NAS_CX_DCH\n"); - return; - - case NAS_CX_RECEIVED: - printf("NAS_CX_RECEIVED\n"); - return; - - case NAS_CX_CONNECTING: - printf("NAS_CX_CONNECTING\n"); - return; - - case NAS_CX_RELEASING: - printf("NAS_CX_RELEASING\n"); - return; - - case NAS_CX_CONNECTING_FAILURE: - printf("NAS_CX_CONNECTING_FAILURE\n"); - return; - - case NAS_CX_RELEASING_FAILURE: - printf("NAS_CX_RELEASING_FAILURE\n"); - return; - - case NAS_RB_ESTABLISHING: - printf("NAS_RB_ESTABLISHING\n"); - return; - - case NAS_RB_RELEASING: - printf("NAS_RB_RELEASING\n"); - return; - - default: - printf(" Unknown state\n"); - } -} - -//--------------------------------------------------------------------------- -void print_usage_class() -{ - //--------------------------------------------------------------------------- - printf("Usage: gioctl class add {send |receive} -f {qos |del|ctl|dc} -cr [-dscp ] [-ip {6|4} ] [-p {tcp|udp|icmp4|icmp6} ]\n"); - printf("Usage: gioctl class del {send |receive} -cr [-dscp ] \n"); - printf("Usage: gioctl class list {send |receive} [-dscp ]\n"); -} -//--------------------------------------------------------------------------- -void print_usage_cx() -{ - //--------------------------------------------------------------------------- - printf("Usage: gioctl cx add \n"); - printf("Usage: gioctl cx del \n"); - printf("Usage: gioctl cx list\n"); -} -//--------------------------------------------------------------------------- -void print_usage_rb() -{ - //--------------------------------------------------------------------------- - printf("Usage: gioctl rb add \n"); - printf("Usage: gioctl rb list \n"); -} - -//--------------------------------------------------------------------------- -int main(int argc, char *argv[]) -{ - //--------------------------------------------------------------------------- - struct nas_ioctl gifr; - int err, fd; - - // Invalid number of arguments - if (argc<2) { - printf("Usage: gioctl statistic\n"); - print_usage_cx(); - print_usage_rb(); - print_usage_class(); - return -1; - } - - // Get an UDP IPv6 socket ?? - fd=socket(AF_INET6, SOCK_DGRAM, 0); - - if (fd<0) { - printf("Error opening socket\n"); - return 0; - } - - strcpy(gifr.name, "oai0"); - printf("Socket opened successfully\n"); - - /***************************/ - if (strcmp(argv[1], "statistic")==0) { - struct nas_msg_statistic_reply *msgrep; - gifr.type=NAS_MSG_STATISTIC_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)); - msgrep=(struct nas_msg_statistic_reply *)(gifr.msg); - printf(" Statistics requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets); - printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes); - printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors); - printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped); - return 0; - } - - /***************************/ - if (strcmp(argv[1], "cx")==0) { - if (argc<3) { - print_usage_cx(); - return -1; - } - - /***/ - // printf("Usage: gioctl cx add \n"); - if (strcmp(argv[2], "add")==0) { - struct nas_msg_cx_establishment_request *msgreq; - struct nas_msg_cx_establishment_reply *msgrep; - - if (argc<5) { - print_usage_cx(); - return -1; - } - - gifr.type=NAS_MSG_CX_ESTABLISHMENT_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); - msgreq->cellid=strtoul(argv[4], NULL, 0); - // - printf(" Connection establishment requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - perror("Connection establishment IOCTL error\n"); - return -1; - } - - if (msgrep->status<0) { - printf(" Connexion establishment failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - // printf("Usage: gioctl cx del \n"); - if (strcmp(argv[2], "del")==0) { - struct nas_msg_cx_release_request *msgreq; - struct nas_msg_cx_release_reply *msgrep; - - if (argc<4) { - print_usage_cx(); - return -1; - } - - gifr.type=NAS_MSG_CX_RELEASE_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); - // - printf(" Connexion release requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - if (msgrep->status<0) { - printf(" Connexion release failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - // printf("Usage: gioctl cx list\n"); - if (strcmp(argv[2], "list")==0) { - uint8_t *msgrep; - uint8_t i; - struct nas_msg_cx_list_reply *list; - uint8_t lcr; - gifr.type=NAS_MSG_CX_LIST_REQUEST; - gifr.msg=(char *)malloc(NAS_LIST_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1); - msgrep=(uint8_t *)(gifr.msg); - // - printf(" Connexion list requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - printf("Lcr\t\tCellId\tIID4\tIID6\t\t\tnrb\tnsclass\tState\n"); - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - - for(lcr=0; lcr \n"); - if (strcmp(argv[2], "add")==0) { - struct nas_msg_rb_establishment_request *msgreq; - struct nas_msg_rb_establishment_reply *msgrep; - - if (argc<6) { - print_usage_rb(); - return -1; - } - - gifr.type=NAS_MSG_RB_ESTABLISHMENT_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); - msgreq->rab_id=strtoul(argv[4], NULL, 0); - msgreq->qos=strtoul(argv[5], NULL, 0); - // - printf(" Radio bearer establishment requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - if (msgrep->status<0) { - printf(" Radio bearer establishment failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - if (strcmp(argv[2], "del")==0) { - struct nas_msg_rb_release_request *msgreq; - struct nas_msg_rb_release_reply *msgrep; - - if (argc<5) { - print_usage_rb(); - return -1; - } - - gifr.type=NAS_MSG_RB_RELEASE_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)lcr=strtoul(argv[3], NULL, 0); - msgreq->rab_id=strtoul(argv[4], NULL, 0); - // - printf(" Radio Bearer release requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - if (msgrep->status<0) { - printf(" Radio bearer release failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - // printf("Usage: gioctl rb list \n"); - if (strcmp(argv[2], "list")==0) { - uint8_t *msgrep; - uint8_t rbi; - struct nas_msg_rb_list_reply *list; - struct nas_msg_rb_list_request *msgreq; - - if (argc<4) { - print_usage_rb(); - return -1; - } - - gifr.type=NAS_MSG_RB_LIST_REQUEST; - gifr.msg=(char *)malloc(NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1); - msgreq=(struct nas_msg_rb_list_request *)(gifr.msg); - msgrep=(uint8_t *)(gifr.msg); - msgreq->lcr=strtoul(argv[3], NULL, 0); - // - printf(" Radio bearer list requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - printf("rab_id\t\tSapi\t\tQoS\t\tState\n"); - list=(struct nas_msg_rb_list_reply *)(msgrep+1); - - for(rbi=0; rbidir=NAS_DIRECTION_SEND; - msgreq->lcr=strtoul(argv[++i], NULL, 0); - ++i; - } else { - if (strcmp(argv[i], "receive")==0) { - msgreq->dir=NAS_DIRECTION_RECEIVE; - ++i; - } else { - print_usage_class(); - return -1; - } - } - - msgreq->classref=USHRT_MAX; - msgreq->dscp=NAS_DSCP_DEFAULT; - msgreq->version=NAS_VERSION_DEFAULT; - msgreq->protocol=NAS_PROTOCOL_DEFAULT; - msgreq->sport=NAS_PORT_DEFAULT; - msgreq->dport=NAS_PORT_DEFAULT; - msgreq->fct=0; - - while (iclassref=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "-dscp")==0) { - msgreq->dscp=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "-f")==0) { - ++i; - - if (strcmp(argv[i], "qos")==0) { - msgreq->fct=NAS_FCT_QOS_SEND; - msgreq->rab_id=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "del")==0) { - msgreq->fct=NAS_FCT_DEL_SEND; - msgreq->rab_id=0; - ++i; - continue; - } - - if (strcmp(argv[i], "ctl")==0) { - msgreq->fct=NAS_FCT_CTL_SEND; - msgreq->rab_id=0; - ++i; - continue; - } - - if (strcmp(argv[i], "dc")==0) { - msgreq->fct=NAS_FCT_DC_SEND; - msgreq->rab_id=0; - ++i; - continue; - } - - print_usage_class(); - return -1; - } - - if (strcmp(argv[i], "-ip")==0) { - ++i; - - if (strcmp(argv[i], "4")==0) { - if (msgreq->version!=NAS_VERSION_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->version=NAS_VERSION_4; - inet_pton(AF_INET, argv[++i], (void *)(&msgreq->saddr)); - msgreq->splen=strtoul(argv[++i], NULL, 0); - inet_pton(AF_INET, argv[++i], (void *)(&msgreq->daddr)); - msgreq->dplen=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "6")==0) { - if (msgreq->version!=NAS_VERSION_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->version=NAS_VERSION_6; - inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->saddr)); - msgreq->splen=strtoul(argv[++i], NULL, 0); - inet_pton(AF_INET6, argv[++i], (void *)(&msgreq->daddr)); - msgreq->dplen=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - print_usage_class(); - return -1; - } - - if (strcmp(argv[i], "-p")==0) { - ++i; - - if (strcmp(argv[i], "tcp")==0) { - if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->protocol=NAS_PROTOCOL_TCP; - msgreq->sport=strtoul(argv[++i], NULL, 0); - msgreq->dport=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "udp")==0) { - if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->protocol=NAS_PROTOCOL_UDP; - msgreq->sport=strtoul(argv[++i], NULL, 0); - msgreq->dport=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "icmp4")==0) { - if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->protocol=NAS_PROTOCOL_ICMP4; - msgreq->sport=strtoul(argv[++i], NULL, 0); - msgreq->dport=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "icmp6")==0) { - if (msgreq->protocol!=NAS_PROTOCOL_DEFAULT) { - print_usage_class(); - return -1; - } - - msgreq->protocol=NAS_PROTOCOL_ICMP6; - msgreq->sport=strtoul(argv[++i], NULL, 0); - msgreq->dport=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - print_usage_class(); - return -1; - } - - print_usage_class(); - return -1; - } - - if ((msgreq->classref==USHRT_MAX)||(msgreq->fct==0)) { - print_usage_class(); - return -1; - } - - printf(" Class add requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - if (msgrep->status<0) { - printf(" Class add failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - if (strcmp(argv[2], "del")==0) { - uint8_t i; - struct nas_msg_class_del_request *msgreq; - struct nas_msg_class_del_reply *msgrep; - gifr.type=NAS_MSG_CLASS_DEL_REQUEST; - gifr.msg=(char *)malloc(sizeof(msgrep)dir=NAS_DIRECTION_SEND; - msgreq->lcr=strtoul(argv[++i], NULL, 0); - ++i; - } else { - if (strcmp(argv[i], "receive")==0) { - msgreq->dir=NAS_DIRECTION_RECEIVE; - ++i; - } else { - print_usage_class(); - return -1; - } - } - - msgreq->classref=USHRT_MAX; - msgreq->dscp=NAS_DSCP_DEFAULT; - - while (iclassref=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - if (strcmp(argv[i], "-dscp")==0) { - msgreq->dscp=strtoul(argv[++i], NULL, 0); - ++i; - continue; - } - - print_usage_class(); - return -1; - } - - if (msgreq->classref==USHRT_MAX) { - print_usage_class(); - return -1; - } - - printf(" Class del requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - if (msgrep->status<0) { - printf(" Class add failure: "); - print_error(msgrep->status); - return -1; - } - - return 0; - } - - /***/ - if (strcmp(argv[2], "list")==0) { - uint8_t *msgrep; - uint8_t cli, i; - struct nas_msg_class_list_reply *list; - struct nas_msg_class_list_request *msgreq; - char addr[45]; - - if (argc<4) { - print_usage_class(); - return -1; - } - - gifr.type=NAS_MSG_CLASS_LIST_REQUEST; - gifr.msg=(char *)malloc(NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1); - - if (gifr.msg==NULL) { - printf(" No memory\n"); - return -1; - } - - msgreq=(struct nas_msg_class_list_request *)(gifr.msg); - msgrep=(uint8_t *)(gifr.msg); - i=3; - - if (strcmp(argv[i], "send")==0) { - msgreq->dir=NAS_DIRECTION_SEND; - msgreq->lcr=strtoul(argv[++i], NULL, 0); - ++i; - } else { - if (strcmp(argv[i], "receive")==0) { - msgreq->dir=NAS_DIRECTION_RECEIVE; - msgreq->lcr=0; - ++i; - } else { - print_usage_class(); - return -1; - } - } - - msgreq->dscp=NAS_DSCP_DEFAULT; - - while (idscp=strtoul(argv[++i], NULL, 0); - } - - printf(" Classifier list requested\n"); - err=ioctl(fd, NASMT_IOCTL_RAL, &gifr); - - // - if (err<0) { - printf("IOCTL error, err=%d\n",err); - return -1; - } - - printf("Lcr\trab_id\tCref\tFct\t(Vers., saddr, daddr)\t\t\t\t(Proto., Sport, Dport)\n"); - list=(struct nas_msg_class_list_reply *)(msgrep+1); - - for(cli=0; clinext_sclassref = NASMT_DEFAULTRAB_CLASSREF; - - for (i = 0; icx->joined_services[i]= -1; - } - - printk("nasmt_ASCTL_init Complete\n"); -} - -//--------------------------------------------------------------------------- -int nasmt_ASCTL_write(int sap, unsigned char *data_buffer, unsigned int data_length) -{ - //--------------------------------------------------------------------------- - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xmit_buffer [NAS_MESSAGE_MAXLEN]; - //MT xmit on DC-SAP only - xmit_buffer[0] = RRC_NAS_DC0_IN; - memcpy (&((char*)xmit_buffer)[1], data_buffer, data_length); - bytes_wrote = nasmt_netlink_send(xmit_buffer,data_length, NASNL_DEST_RRC); -#else - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version - bytes_wrote = rtf_put(sap, data_buffer, data_length); -#endif //PDCP_USE_NETLINK - return bytes_wrote; -} - -//--------------------------------------------------------------------------- -//For demo, add automatically a classifier -//Equivalent to class add send 0 -f qos -cr 0 -void nasmt_ASCTL_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("\nnasmt_ASCTL_start_default_sclass - begin \n"); -#endif - - if (!cx || !rb) { - printk("nasmt_ASCTL_start_default_sclass - input parameter cx or rb is NULL \n"); - return; - } - - // End debug information - // - gc=nasmt_CLASS_add_sclassifier(cx, NAS_DSCP_DEFAULT, gpriv->next_sclassref); - - // gc=nasmt_CLASS_add_sclassifier(cx, 5, 0); - if (gc==NULL) { - printk("nasmt_ASCTL_start_default_sclass - Error - Classifier not added \n"); - return; - } - - gc->fct = nasmt_COMMON_QOS_send; - gc->rab_id =rb->rab_id; - gc->rb= rb; - gc->version = NASMT_DEFAULTRAB_IPVERSION; - gc->protocol= NAS_PROTOCOL_DEFAULT; - gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH; - //gc->daddr.ipv6.s6_addr32[2] = cx->iid6[0]; - //gc->daddr.ipv6.s6_addr32[3] = cx->iid6[1]; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_ASCTL_start_default_sclass - end \n"); - nasmt_TOOL_print_classifier(gc); -#endif -} - -//--------------------------------------------------------------------------- -//For demo, add automatically a classifier -//Equivalent to class add send 0 -f qos -cr 0 -void nasmt_ASCTL_start_sclassifier(struct cx_entity *cx,struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("\nnasmt_ASCTL_start_sclass - begin \n"); -#endif - - if (cx==NULL) { - printk("nasmt_ASCTL_start_sclass - input parameter cx is NULL \n"); - return; - } - - if (rb==NULL) { - printk("nasmt_ASCTL_start_sclass - input parameter rb is NULL \n"); - return; - } - - // End debug information - // - gc=nasmt_CLASS_add_sclassifier(cx, rb->dscp, gpriv->next_sclassref); - - // gc=nasmt_CLASS_add_sclassifier(cx, 5, 0); - if (gc==NULL) { - printk("nasmt_ASCTL_start_sclass - Error - Classifier not added \n"); - return; - } - - gc->fct = nasmt_COMMON_QOS_send; - gc->rab_id =rb->rab_id; - gc->rb= rb; - gc->version = NASMT_DEFAULTRAB_IPVERSION; - gc->protocol= NAS_PROTOCOL_DEFAULT; - gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH; - gc->daddr.ipv6.s6_addr32[2] = cx->iid6[0]; - gc->daddr.ipv6.s6_addr32[3] = cx->iid6[1]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_ASCTL_start_sclass - end \n"); - nasmt_TOOL_print_classifier(gc); -#endif -} - -//--------------------------------------------------------------------------- -void nasmt_ASCTL_timer(unsigned long data) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; - struct cx_entity *cx; - struct rb_entity *rb; - spin_lock(&gpriv->lock); -#ifdef NAS_DEBUG_TIMER - printk("nasmt_ASCTL_timer - begin \n"); -#endif - (gpriv->timer).function=nasmt_ASCTL_timer; - (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; - (gpriv->timer).data=0L; - - for (cxi=0; cxicx+cxi; - - if (cx==NULL) { -#ifdef NAS_DEBUG_TIMER - printk("nasmt_ASCTL_timer - No pointer for connection %d \n", cxi); -#endif - continue; - } - - if (cx->countimer!=NAS_TIMER_IDLE) { -#ifdef NAS_DEBUG_TIMER - printk("nasmt_ASCTL_timer: lcr %u, countimer %u\n", cx->lcr, cx->countimer); -#endif - - if (cx->countimer==0) { - switch (cx->state) { - case NAS_CX_CONNECTING: - case NAS_CX_CONNECTING_FAILURE: - if (cx->retryretry_limit) - nasmt_ASCTL_DC_send_cx_establish_request(cx); - else { - printk("nasmt_ASCTL_timer: Establishment failure\n"); - cx->state=NAS_IDLE; - cx->retry=0; - cx->countimer=NAS_TIMER_IDLE; - } - - break; - - case NAS_CX_RELEASING_FAILURE: - nasmt_ASCTL_DC_send_cx_release_request(cx); - break; - - default: - printk("nasmt_ASCTL_timer: default value\n"); - cx->countimer=NAS_TIMER_IDLE; - } - } else - --cx->countimer; - } - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->countimer!=NAS_TIMER_IDLE) { -#ifdef NAS_DEBUG_TIMER - printk("nasmt_ASCTL_timer : rb countimer %d, rb state %d\n", rb->countimer, rb->state); -#endif - - if (rb->countimer==0) { - switch (rb->state) { - case NAS_RB_DCH: -#ifdef DEMO_3GSM - if (cx->num_rb == 1) { - nasmt_ASCTL_start_default_sclassifier(cx, rb); - } - -#endif - nasmt_ASCTL_start_sclassifier(cx, rb); - rb->countimer=NAS_TIMER_IDLE; - break; - - default: - rb->countimer=NAS_TIMER_IDLE; - } - } else { - --rb->countimer; - printk("nasmt_ASCTL_timer : rb countimer-- %d, rb state %d\n", rb->countimer, rb->state); - } - } - } - } - - add_timer(&gpriv->timer); - spin_unlock(&gpriv->lock); -} - -//--------------------------------------------------------------------------- -// Request the sleep of a connexion -int nasmt_ASCTL_enter_sleep_mode(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t sig_category; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_enter_sleep_mode - begin \n"); -#endif - - if (!cx) { - printk("nasmt_ASCTL_enter_sleep_mode - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - // send peer message to NASRG - sig_category = NAS_CMD_ENTER_SLEEP; - printk("nasmt_ASCTL_enter_sleep_mode - sig_category %u \n", sig_category); - nasmt_ASCTL_DC_send_peer_sig_data_request(cx, sig_category); - cx->state=NAS_CX_RELEASING; - return 0; -} - -//--------------------------------------------------------------------------- -// Request to reactivate a connexion -int nasmt_ASCTL_leave_sleep_mode(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t sig_category; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_leave_sleep_mode - begin \n"); -#endif - - if (!cx) { - printk("nasmt_ASCTL_leave_sleep_mode - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - cx->state=NAS_CX_DCH; - // send peer message to NASRG - sig_category = NAS_CMD_LEAVE_SLEEP; - printk("nasmt_ASCTL_leave_sleep_mode - sig_category %u \n", sig_category); - nasmt_ASCTL_DC_send_peer_sig_data_request(cx, sig_category); - return 0; -} - -/*********************************************** - * Transmit Functions * - ***********************************************/ - -//--------------------------------------------------------------------------- -// Request the establishment of a connexion (DC channel) -int nasmt_ASCTL_DC_send_cx_establish_request(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - struct nas_ue_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_establish - begin \n"); -#endif - - if (!cx) { - printk("nasmt_ASCTL_DC_send_cx_establish - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - - switch (cx->state) { - case NAS_CX_CONNECTING: - case NAS_CX_CONNECTING_FAILURE: - case NAS_IDLE: - p= (struct nas_ue_dc_element *)(gpriv->xbuffer); - p->type = CONN_ESTABLISH_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASConnEstablishReq); - p->nasUEDCPrimitive.conn_establish_req.localConnectionRef = cx->lcr; - p->nasUEDCPrimitive.conn_establish_req.cellId = cx->cellid; -#ifdef NAS_DEBUG_DC - printk ("\nCONN_ESTABLISH_REQ Buffer to Xmit: "); - nasmt_TOOL_print_buffer((char *)p,p->length); -#endif - ++cx->retry; - - //bytes_wrote = rtf_put(cx->sap[GRAAL_DC_INPUT_SAPI], p, p->length); //original version - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - //printk("nasmt_ASCTL_DC_send_cx_establish_request - Wrote %d bytes to RRC NAS_DC_INPUT_SAPI\n", bytes_wrote); - - cx->countimer=gpriv->timer_establishment; - - if (bytes_wrote==p->length) { - cx->state=NAS_CX_CONNECTING; -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_establish - Message sent successfully in DC-FIFO\n"); - printk(" Local Connection reference %u\n", p->nasUEDCPrimitive.conn_establish_req.localConnectionRef); - printk(" Cell Identification %u\n", p->nasUEDCPrimitive.conn_establish_req.cellId); - nasmt_TOOL_print_state(cx->state); -#endif - } else { - cx->state=NAS_CX_CONNECTING_FAILURE; - printk("nasmt_ASCTL_DC_send_cx_establish - Message sent failure in DC-FIFO\n"); - nasmt_TOOL_print_state(cx->state); - } - - return bytes_wrote; - - default: - return -NAS_ERROR_NOTIDLE; -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_establish - NAS_ERROR_NOTIDLE \n"); -#endif - } -} - -//--------------------------------------------------------------------------- -// Request the release of a connexion (DC channel) -int nasmt_ASCTL_DC_send_cx_release_request(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - struct nas_ue_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_release - begin \n"); -#endif - - if (cx==NULL) { - printk("nasmt_ASCTL_DC_send_cx_release - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - switch (cx->state) { - case NAS_CX_RELEASING_FAILURE: - case NAS_CX_DCH: - p= (struct nas_ue_dc_element *)(gpriv->xbuffer); - p->type = CONN_RELEASE_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASConnReleaseReq); - p->nasUEDCPrimitive.conn_release_req.localConnectionRef = cx->lcr; - p->nasUEDCPrimitive.conn_release_req.releaseCause = NAS_CX_RELEASE_UNDEF_CAUSE; - - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - //printk("nasmt_ASCTL_DC_send_cx_release - Wrote %d bytes to RRC NAS_DC_INPUT_SAPI\n", bytes_wrote); - - if (bytes_wrote==p->length) { - cx->state=NAS_IDLE; - cx->iid4=0; - // nasmt_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6); - nasmt_COMMON_flush_rb(cx); - nasmt_CLASS_flush_sclassifier(cx); - -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_release - Message sent successfully in DC-FIFO\n"); - printk(" Local Connection Reference %u\n", p->nasUEDCPrimitive.conn_release_req.localConnectionRef); - printk(" Release Cause %u\n", p->nasUEDCPrimitive.conn_release_req.releaseCause); - nasmt_TOOL_print_state(cx->state); -#endif - } else { - ++cx->retry; - cx->countimer=gpriv->timer_release; - cx->state=NAS_CX_RELEASING_FAILURE; - printk("nasmt_ASCTL_DC_send_cx_release - Message sent failure in DC-FIFO\n"); - nasmt_TOOL_print_state(cx->state); - } - - return bytes_wrote; - - default: - return -NAS_ERROR_NOTCONNECTED; -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_cx_release - NAS_ERROR_NOTCONNECTED \n"); -#endif - } -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (DC SAP) -void nasmt_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - struct nas_ue_dc_element *p; - char data_type = 'A'; - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xbuffer[NAS_MESSAGE_MAXLEN]; - int count=0; -#endif - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_sig_data - begin \n"); -#endif - - if (!skb || !gc || !cx) { - printk("nasmt_ASCTL_DC_send_sig_data - input parameter skb, gc or cx is NULL \n"); - return; - } - - // End debug information - if (cx->state!=NAS_CX_DCH) { - printk("nasmt_ASCTL_DC_send_sig_data - Not connected, so the message is dropped\n"); - ++gpriv->stats.tx_dropped; - return; - } - - p = (struct nas_ue_dc_element *)(gpriv->xbuffer); - p->type = DATA_TRANSFER_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASDataReq); - p->nasUEDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr; - p->nasUEDCPrimitive.data_transfer_req.priority = 3; // TBD - p->nasUEDCPrimitive.data_transfer_req.nasDataLength = (skb->len)+1; //adds category character - - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version -#ifdef PDCP_USE_NETLINK - memcpy(xbuffer,(unsigned char *)p, p->length); - count = p->length; - bytes_wrote = count; -#else - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); -#endif - //printk("nasmt_ASCTL_DC_send_sig_data - Wrote %d bytes to RRC NAS_DC_INPUT_SAPI\n", bytes_wrote); - - if (bytes_wrote!=p->length) { - printk("nasmt_ASCTL_DC_send_sig_data - Header sent failure in DC-FIFO\n"); - return; - } - -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)&data_type, 1); - count += 1; - bytes_wrote = count; -#else - bytes_wrote += nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)&data_type, 1); -#endif - -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)skb->data, skb->len); - count += skb->len; - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], xbuffer, count); -#else - bytes_wrote += nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)skb->data, skb->len); -#endif - - if (bytes_wrote != p->length + skb->len + 1) { - printk("nasmt_ASCTL_DC_send_sig_data - Data sent failure in DC-FIFO\n"); - return; - } - - gpriv->stats.tx_bytes += skb->len; - gpriv->stats.tx_packets ++; -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_sig_data - end \n"); -#endif -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (DC SAP) -void nasmt_ASCTL_DC_send_peer_sig_data_request(struct cx_entity *cx, uint8_t sig_category) -{ - //--------------------------------------------------------------------------- - struct nas_ue_dc_element *p; - uint8_t nasmt_data[10]; - unsigned int nasmt_length; - char data_type = 'Z'; - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xbuffer[NAS_MESSAGE_MAXLEN]; - int count=0; -#endif - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_peer_sig_data - begin \n"); -#endif - - if (!cx) { - printk("nasmt_ASCTL_DC_send_peer_sig_data - input parameter cx is NULL \n"); - return; - } - - // End debug information - - if (cx->state!=NAS_CX_DCH) { - printk("nasmt_ASCTL_DC_send_peer_sig_data: Not connected, so the message is dropped\n"); - return; - } - - // Initialize peer message - nasmt_length = 10; - memset (nasmt_data, 0, nasmt_length); - nasmt_data[0]= sig_category; - // - p = (struct nas_ue_dc_element *)(gpriv->xbuffer); - p->type = DATA_TRANSFER_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASDataReq); - p->nasUEDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr; - p->nasUEDCPrimitive.data_transfer_req.priority = 3; // TBD - p->nasUEDCPrimitive.data_transfer_req.nasDataLength = (nasmt_length)+1; //adds category character - - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version -#ifdef PDCP_USE_NETLINK - memcpy(xbuffer,(unsigned char *)p, p->length); - count = p->length; - bytes_wrote = count; -#else - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); -#endif - //printk("nasmt_ASCTL_DC_send_sig_data - Wrote %d bytes to RRC NAS_DC_INPUT_SAPI\n", bytes_wrote); - - if (bytes_wrote!=p->length) { - printk("nasmt_ASCTL_DC_send_peer_sig_data - Header sent failure in DC-FIFO\n"); - return; - } - -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)&data_type, 1); - count += 1; -#else - bytes_wrote += nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)&data_type, 1); -#endif - -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)nasmt_data, nasmt_length); - count += nasmt_length; - bytes_wrote = nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], xbuffer, count); -#else - bytes_wrote += nasmt_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (char *)nasmt_data, nasmt_length); -#endif - - if (bytes_wrote != p->length + nasmt_length + 1) { - printk("nasmt_ASCTL_DC_send_peer_sig_data - Data sent failure in DC-FIFO\n"); - return; - } - -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_send_peer_sig_data - end \n"); -#endif -} - -/*************************************************************************** - Reception side - ***************************************************************************/ -//--------------------------------------------------------------------------- -// Decode CONN_ESTABLISH_RESP message from RRC -void nasmt_ASCTL_DC_decode_cx_establish_resp(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - - uint8_t sig_category; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_cx_establish - begin \n"); -#endif - - if (!cx || !p) { - printk("nasmt_ASCTL_DC_decode_cx_establish - input parameter cx or p is NULL \n"); - return; - } - - // End debug information - cx->retry=0; - - if (p->nasUEDCPrimitive.conn_establish_resp.status == TERMINATED) { - cx->state=NAS_CX_DCH; //to be changed to NAS_CX_FACH - cx->iid4=1; - nasmt_TOOL_imei2iid(NAS_RG_IMEI, (uint8_t *)cx->iid6); - sig_category = NAS_CMD_OPEN_RB; - //For demo, add automatically a radio bearer -#ifdef DEMO_3GSM - printk("nasmt_ASCTL_DC_decode_cx_establish - sig_category %u \n", sig_category); - nasmt_ASCTL_DC_send_peer_sig_data_request(cx, sig_category); -#endif - } else { - cx->state=NAS_IDLE; - } - -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_cx_establish: CONN_ESTABLISH_RESP\n"); - printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef); - printk(" Connection Establishment status %u\n",p->nasUEDCPrimitive.conn_establish_resp.status); - nasmt_TOOL_print_state(cx->state); -#endif -} - -//--------------------------------------------------------------------------- -// Decode CONN_LOSS_IND message from RRC -void nasmt_ASCTL_DC_decode_cx_loss_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_cx_loss - begin \n"); -#endif - - if (cx==NULL) { - printk("nasmt_ASCTL_DC_decode_cx_loss - input parameter cx is NULL \n"); - return; - } - - if (p==NULL) { - printk("nasmt_ASCTL_DC_decode_cx_loss - input parameter p is NULL \n"); - return; - } - - // End debug information - cx->state=NAS_IDLE; - cx->iid4=0; - //nasmt_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6); - nasmt_COMMON_flush_rb(cx); -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_cx_loss: CONN_LOSS_IND reception\n"); - printk(" Local Connection reference %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef); - nasmt_TOOL_print_state(cx->state); -#endif -} - -//--------------------------------------------------------------------------- -// Decode CONN_RELEASE_IND message from RRC -//void nasmt_ASCTL_DC_decode_cx_release_ind(struct cx_entity *cx, struct nas_ue_dc_element *p){ -//--------------------------------------------------------------------------- -// printk("\t\tCONN_RELEASE_IND\n"); -// printk("\t\tLocal Connection reference %u\n", p->nasUEDCPrimitive.conn_release_ind.localConnectionRef); -// printk("\t\tRelease cause %u\n", p->nasRGDCPrimitive.conn_release_ind.releaseCause); -// if (gpriv->cx[cxi].state==NAS_CX_DCH) -// { -// gpriv->cx[cxi].state=NAS_IDLE; -// printk("\t\tMobile no more connected\n"); -// return bytes_read; -// } -// printk("\t\tIncoherent state %u\n", gpriv->cx[cxi].state); -// return bytes_read; -//} - -//--------------------------------------------------------------------------- -// Decode DATA_TRANSFER_IND message from RRC -void nasmt_ASCTL_DC_decode_sig_data_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - // struct pdcp_data_ind_header_t *pdcph; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_sig_data - begin \n"); -#endif - - if (!cx || !p) { - printk("nasmt_ASCTL_DC_decode_sig_data - input parameter cx or p is NULL \n"); - return; - } - - // End debug information - -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_sig_data: DATA_TRANSFER_IND reception\n"); - printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.data_transfer_ind.localConnectionRef); - printk(" Signaling Priority %u\n",p->nasUEDCPrimitive.data_transfer_ind.priority); - printk(" NAS Data length %u\n",p->nasUEDCPrimitive.data_transfer_ind.nasDataLength); - printk(" NAS Data string %s\n", (uint8_t *)p+p->length); -#endif - - //nasmt_COMMON_receive(p->length, p->nasUEDCPrimitive.data_transfer_ind.nasDataLength, cx->sap[GRAAL_DC_OUTPUT_SAPI]); // original -#ifndef PDCP_USE_NETLINK - //void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - // data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer) - nasmt_COMMON_receive(p->length, p->nasUEDCPrimitive.data_transfer_ind.nasDataLength, NULL, 2, cx->sap[NAS_DC_OUTPUT_SAPI]); -#else - nasmt_COMMON_receive(p->length, p->nasUEDCPrimitive.data_transfer_ind.nasDataLength, (unsigned char *)p+p->length, 2, 0); -#endif - -} -//--------------------------------------------------------------------------- -// Decode RB_ESTABLISH_IND message from RRC -void nasmt_ASCTL_DC_decode_rb_establish_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; - int hard_coded_rbId = 3; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_rb_establish - begin \n"); -#endif - - if (cx==NULL) { - printk("nasmt_ASCTL_DC_decode_rb_establish - input parameter cx is NULL \n"); - return; - } - - if (p==NULL) { - printk("nasmt_ASCTL_DC_decode_rb_establish - input parameter p is NULL \n"); - return; - } - - // End debug information - // TEMP -MW - 26/9/13- Overwrite the rb_id sent by RRC - p->nasUEDCPrimitive.rb_establish_ind.rbId = hard_coded_rbId; - // TEMP -MW - 26/9/13- Rest should be kept unchanged - rb=nasmt_COMMON_search_rb(cx, p->nasUEDCPrimitive.rb_establish_ind.rbId); - - if (rb==NULL) { - rb=nasmt_COMMON_add_rb(cx, p->nasUEDCPrimitive.rb_establish_ind.rbId, p->nasUEDCPrimitive.rb_establish_ind.QoSclass); - rb->state=NAS_RB_DCH; - cx->state=NAS_CX_DCH; - rb->dscp = p->nasUEDCPrimitive.rb_establish_ind.dscp; - rb->sapi = p->nasUEDCPrimitive.rb_establish_ind.sapId; - rb->countimer=1; -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_IND reception\n"); - printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef); - printk(" Radio Bearer Identity %u \n",p->nasUEDCPrimitive.rb_establish_ind.rbId); - printk(" QoS Traffic Class %u\n",p->nasUEDCPrimitive.rb_establish_ind.QoSclass); - printk(" DSCP Code %u\n",p->nasUEDCPrimitive.rb_establish_ind.dscp); - printk(" SAP Id %u\n",p->nasUEDCPrimitive.rb_establish_ind.sapId); - nasmt_TOOL_print_state(cx->state); - nasmt_TOOL_print_rb_entity(rb); -#endif - } else - printk("NAS_MT_DC_DECODE_RB_ESTABLISH_IND: RB_ESTABLISH_IND reception, Radio bearer already opened\n"); -} - -//--------------------------------------------------------------------------- -// Decode RB_RELEASE_IND message from RRC -void nasmt_ASCTL_DC_decode_rb_release_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; - uint8_t dscp; - int hard_coded_rbId = 3; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_rb_release - begin \n"); -#endif - - if (!cx || !p) { - printk("nasmt_ASCTL_DC_decode_rb_release - input parameter is NULL \n"); - return; - } - - // End debug information - // TEMP -MW - 26/9/13- Overwrite the rb_id sent by RRC - p->nasUEDCPrimitive.rb_release_ind.rbId = hard_coded_rbId; - // TEMP -MW - 26/9/13- Rest should be kept unchanged - rb=nasmt_COMMON_search_rb(cx, p->nasUEDCPrimitive.rb_release_ind.rbId); - - if (rb!=NULL) { -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_rb_release : RB_RELEASE_IND reception\n"); - printk(" Local Connection reference %u\n",p->nasUEDCPrimitive.rb_release_ind.localConnectionRef); - printk(" Radio Bearer Identity %u\n",p->nasUEDCPrimitive.rb_release_ind.rbId); - nasmt_TOOL_print_state(cx->state); -#endif - // rb->state=NAS_IDLE; - dscp = rb->dscp; - nasmt_COMMON_del_rb(cx, p->nasUEDCPrimitive.rb_release_ind.rbId, dscp); - } else - printk("nasmt_ASCTL_DC_decode_rb_release: RB_RELEASE_IND reception, No corresponding radio bearer\n"); - -} -//--------------------------------------------------------------------------- -// Decode MEASUREMENT_IND message from RRC -void nasmt_ASCTL_DC_decode_measurement_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - uint8_t i; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_measurement - begin \n"); -#endif - - if (cx==NULL) { - printk("nasmt_ASCTL_DC_decode_measurement - input parameter cx is NULL \n"); - return; - } - - if (p==NULL) { - printk("nasmt_ASCTL_DC_decode_measurement - input parameter p is NULL \n"); - return; - } - - // End debug information -#ifdef NAS_DEBUG_DC_MEASURE - printk(" nasmt_ASCTL_DC_decode_measurement : MEASUREMENT_IND reception\n"); - printk(" Local Connection reference: %u\n", p->nasUEDCPrimitive.measurement_ind.localConnectionRef); - printk(" Number of RGs: %u\n", p->nasUEDCPrimitive.measurement_ind.nb_rg); - nasmt_TOOL_print_state(cx->state); - - for (i=0; inasUEDCPrimitive.measurement_ind.nb_rg; ++i) { - printk(" RG[%u]: Cell_Id %u, Level: %u\n", i, - p->nasUEDCPrimitive.measurement_ind.measures[i].cell_id, - p->nasUEDCPrimitive.measurement_ind.measures[i].level); - } - -#endif -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_measurement - Local cell %d\n",p->nasUEDCPrimitive.measurement_ind.measures[0].cell_id); -#endif - cx->num_measures = p->nasUEDCPrimitive.measurement_ind.nb_rg; - - for (i=0; inum_measures; i++) { - cx->meas_cell_id[i]= (int)(p->nasUEDCPrimitive.measurement_ind.measures[i].cell_id); - cx->meas_level[i] = (int)(p->nasUEDCPrimitive.measurement_ind.measures[i].level); - //npriv->provider_id[i]=; - } - - cx->provider_id[0]=25; - cx->provider_id[1]=1; - cx->provider_id[2]=25; - -} - -//--------------------------------------------------------------------------- -// Decode MBMS_UE_NOTIFY_IND message from RRC -void nasmt_ASCTL_DC_decode_mbms_ue_notify_ind(struct cx_entity *cx, struct nas_ue_dc_element *p) -{ - //--------------------------------------------------------------------------- - uint8_t i, j, k; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasmt_ASCTL_DC_decode_mbms_ue_notify - begin \n"); -#endif - - if (!cx || !p) { - printk("nasmt_ASCTL_DC_decode_mbms_ue_notify - input parameter is NULL \n"); - return; - } - - for (i = 0; inasUEDCPrimitive.mbms_ue_notify_ind.joined_services[i].mbms_serviceId >=0) { - for (j = 0; jjoined_services[j] ==-1) { - cx->joined_services[j]= p->nasUEDCPrimitive.mbms_ue_notify_ind.joined_services[i].mbms_serviceId; - break; - } - } - } - - if (p->nasUEDCPrimitive.mbms_ue_notify_ind.left_services[i].mbms_serviceId >=0) { - for (k = 0; kjoined_services[k] == p->nasUEDCPrimitive.mbms_ue_notify_ind.left_services[i].mbms_serviceId) { - cx->joined_services[k]=-1; - break; - } - } - } - } - - // End debug information -#ifdef NAS_DEBUG_DC - printk(" nasmt_ASCTL_DC_decode_mbms_ue_notify : MBMS_UE_NOTIFY_IND reception\n"); - printk(" Local Connection reference: %u\n", p->nasUEDCPrimitive.mbms_ue_notify_ind.localConnectionRef); - nasmt_TOOL_print_state(cx->state); - printk("Joined services: "); - - for (i = 0; inasUEDCPrimitive.mbms_ue_notify_ind.joined_services[i].mbms_serviceId) >= 0; i++) - printk("%d ", (p->nasUEDCPrimitive.mbms_ue_notify_ind.joined_services[i].mbms_serviceId)); - - printk("\n"); - printk("Left services: "); - - for (i = 0; inasUEDCPrimitive.mbms_ue_notify_ind.left_services[i].mbms_serviceId) >= 0; i++) - printk("%d ", (p->nasUEDCPrimitive.mbms_ue_notify_ind.left_services[i].mbms_serviceId)); - - printk("\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Check if anything in DC FIFO and decode it (MT) -int nasmt_ASCTL_DC_receive(struct cx_entity *cx, char *buffer) -{ - //--------------------------------------------------------------------------- - int bytes_read=0; - - // Start debug information -#ifdef NAS_DEBUG_DC_DETAIL - printk("nasmt_ASCTL_DC_receive - begin \n"); -#endif - - if (!cx) { - printk("nasmt_ASCTL_DC_receive - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - -#ifndef PDCP_USE_NETLINK - bytes_read = rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI] , gpriv->rbuffer, NAS_TL_SIZE); -#else - bytes_read = NAS_TL_SIZE; -#endif - - // - if (bytes_read>0) { - struct nas_ue_dc_element *p; - -#ifndef PDCP_USE_NETLINK - p= (struct nas_ue_dc_element *)(gpriv->rbuffer); - //get the rest of the primitive - bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], (uint8_t *)p+NAS_TL_SIZE, p->length-NAS_TL_SIZE); - - if (bytes_read!=p->length) { - printk("nasmt_ASCTL_DC_receive: Problem while reading primitive header\n"); - return bytes_read; - } - -#else - p= (struct nas_ue_dc_element *)(buffer); -#endif - - switch (p->type) { - case CONN_ESTABLISH_RESP : - if (p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: CONN_ESTABLISH_RESP, Local connection reference not correct %u\n",p->nasUEDCPrimitive.conn_establish_resp.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_CONNECTING: - nasmt_ASCTL_DC_decode_cx_establish_resp(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: CONN_ESTABLISH_RESP reception, Invalid state %u\n", cx->state); - } - } - - break; - - case CONN_LOSS_IND : - if (p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: CONN_LOSS_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_RELEASING_FAILURE: - cx->retry=0; - - case NAS_CX_DCH: - nasmt_ASCTL_DC_decode_cx_loss_ind(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: CONN_LOSS_IND reception, Invalid state %u", cx->state); - } - } - - break; - - // case CONN_RELEASE_IND : - // break; - case DATA_TRANSFER_IND : - if (p->nasUEDCPrimitive.data_transfer_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: DATA_TRANSFER_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.conn_loss_ind.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_FACH: - case NAS_CX_DCH: - nasmt_ASCTL_DC_decode_sig_data_ind(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: DATA_TRANSFER_IND reception, Invalid state %u", cx->state); - } - } - - break; - - case RB_ESTABLISH_IND : - if (p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: RB_ESTABLISH_IND reception, Local connexion reference not correct %u\n", p->nasUEDCPrimitive.rb_establish_ind.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_FACH: - case NAS_CX_DCH: - nasmt_ASCTL_DC_decode_rb_establish_ind(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: RB_ESTABLISH_IND reception, Invalid state %u", cx->state); - } - } - - break; - - case RB_RELEASE_IND : - if (p->nasUEDCPrimitive.rb_release_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: RB_RELEASE_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.rb_release_ind.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_DCH: - nasmt_ASCTL_DC_decode_rb_release_ind(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: RB_RELEASE_IND reception, Invalid state %u", cx->state); - } - } - - break; - - case MEASUREMENT_IND : - if (p->nasUEDCPrimitive.measurement_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: MEASUREMENT_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.measurement_ind.localConnectionRef); - else { - nasmt_ASCTL_DC_decode_measurement_ind(cx,p); - } - - break; - - case MBMS_UE_NOTIFY_IND : - if (p->nasUEDCPrimitive.rb_release_ind.localConnectionRef!=cx->lcr) - printk("nasmt_ASCTL_DC_receive: MBMS_UE_NOTIFY_IND reception, Local connection reference not correct %u\n", p->nasUEDCPrimitive.rb_release_ind.localConnectionRef); - else { - switch (cx->state) { - case NAS_CX_DCH: - nasmt_ASCTL_DC_decode_mbms_ue_notify_ind(cx,p); // process message - break; - - default: - printk("nasmt_ASCTL_DC_receive: MBMS_UE_NOTIFY_IND reception, Invalid state %u", cx->state); - } - } - - break; - - default : - printk("nasmt_ASCTL_DC_receive: Invalid message received\n"); - } - } - -#ifdef NAS_DEBUG_DC_DETAIL - printk("nasmt_ASCTL_DC_receive - end \n"); -#endif - return bytes_read; -} - -//--------------------------------------------------------------------------- -// Check if anything in GC FIFO and decode it (MT) -int nasmt_ASCTL_GC_receive(char *buffer) -{ - //--------------------------------------------------------------------------- - int bytes_read = 0; - -#ifdef NAS_DEBUG_GC - printk("nasmt_ASCTL_GC_receive - begin \n"); -#endif - // End debug information - -#ifndef PDCP_USE_NETLINK - bytes_read = rtf_get(gpriv->sap[NAS_GC_SAPI], gpriv->rbuffer, NAS_TL_SIZE); -#else - bytes_read = NAS_TL_SIZE; -#endif - - // - if (bytes_read>0) { - struct nas_ue_gc_element *p; -#ifndef PDCP_USE_NETLINK - p= (struct nas_ue_gc_element *)(gpriv->rbuffer); - //get the rest of the primitive - bytes_read += rtf_get(gpriv->sap[NAS_GC_SAPI], (uint8_t *)p+NAS_TL_SIZE, p->length-NAS_TL_SIZE); - - if (bytes_read!=p->length) { - printk("nasmt_ASCTL_GC_receive: Problem while reading primitive's header\n"); - return bytes_read; - } - -#else - p= (struct nas_ue_gc_element *)(buffer); - bytes_read = p->length; -#endif - - // start decoding message - switch (p->type) { - case INFO_BROADCAST_IND : -#ifndef PDCP_USE_NETLINK - bytes_read += rtf_get(gpriv->sap[NAS_GC_SAPI], (uint8_t *)p+p->length, p->nasUEGCPrimitive.broadcast_ind.nasDataLength); - - if (bytes_read!=p->length+p->nasUEGCPrimitive.broadcast_ind.nasDataLength) { - printk("nasmt_ASCTL_GC_receive: INFO_BROADCAST_IND reception, Problem while reading primitive's data\n"); - return bytes_read; - } - -#endif -#ifdef NAS_DEBUG_GC - printk(" nasmt_ASCTL_GC_receive : INFO_BROADCAST_IND reception\n"); - printk(" Primitive length %d \n", (int)(p->type)); - printk(" Data length %u\n", p->nasUEGCPrimitive.broadcast_ind.nasDataLength); - printk(" Data string %s\n", (uint8_t *)p+p->length); -#endif - return bytes_read; - - default : - printk("nasmt_ASCTL_GC_receive: Invalid message received, type %d\n", p->type); - nasmt_TOOL_print_buffer(buffer, 16); - return -1; - } - } else - return -1; -} - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_classifier.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_classifier.c deleted file mode 100644 index 3cc1ac0879..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_classifier.c +++ /dev/null @@ -1,884 +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 nasmt_classifier.c -* \brief Flow classification functions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasmt_variables.h" -#include "nasmt_proto.h" - -#include -#include - -#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) -#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) -#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) -#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) - -/* Address to accept any incoming messages. */ -#define INADDR_ANY ((unsigned long int) 0x00000000) - -#define NIPADDR(addr) \ - (uint8_t)(addr & 0x000000FF), \ - (uint8_t)((addr & 0x0000FF00) >> 8), \ - (uint8_t)((addr & 0x00FF0000) >> 16), \ - (uint8_t)((addr & 0xFF000000) >> 24) - -#define NIP6ADDR(addr) \ - ntohs((addr)->s6_addr16[0]), \ - ntohs((addr)->s6_addr16[1]), \ - ntohs((addr)->s6_addr16[2]), \ - ntohs((addr)->s6_addr16[3]), \ - ntohs((addr)->s6_addr16[4]), \ - ntohs((addr)->s6_addr16[5]), \ - ntohs((addr)->s6_addr16[6]), \ - ntohs((addr)->s6_addr16[7]) - - -#define IN6_IS_ADDR_UNSPECIFIED(a) \ - (((__const uint32_t *) (a))[0] == 0 \ - && ((__const uint32_t *) (a))[1] == 0 \ - && ((__const uint32_t *) (a))[2] == 0 \ - && ((__const uint32_t *) (a))[3] == 0) - -#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \ - (((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \ - && ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \ - && ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \ - && ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3])))) - -#define IN_ARE_ADDR_MASKED_EQUAL(a,b,m) \ - (((((__const uint8_t *) (a))[0] & (((__const uint8_t *) (m))[0])) == (((__const uint8_t *) (b))[0] & (((__const uint8_t *) (m))[0]))) \ - && ((((__const uint8_t *) (a))[1] & (((__const uint8_t *) (m))[1])) == (((__const uint8_t *) (b))[1] & (((__const uint8_t *) (m))[1]))) \ - && ((((__const uint8_t *) (a))[2] & (((__const uint8_t *) (m))[2])) == (((__const uint8_t *) (b))[2] & (((__const uint8_t *) (m))[2]))) \ - && ((((__const uint8_t *) (a))[3] & (((__const uint8_t *) (m))[3])) == (((__const uint8_t *) (b))[3] & (((__const uint8_t *) (m))[3])))) - -//--------------------------------------------------------------------------- -void nasmt_create_mask_ipv6_addr(struct in6_addr *masked_addrP, int prefix_len) -{ - //--------------------------------------------------------------------------- - int u6_addr8_index; - int u6_addr1_index; - int index; - - masked_addrP->s6_addr32[0] = 0xFFFFFFFF; - masked_addrP->s6_addr32[1] = 0xFFFFFFFF; - masked_addrP->s6_addr32[2] = 0xFFFFFFFF; - masked_addrP->s6_addr32[3] = 0xFFFFFFFF; - - u6_addr8_index = prefix_len >> 3; - u6_addr1_index = prefix_len & 0x07; - - for (index = u6_addr8_index + 1; index < 16; index++) { - masked_addrP->s6_addr[index] = 0; - } - - if (u6_addr1_index > 0) { - masked_addrP->s6_addr[u6_addr8_index] = 0xFF << (8-u6_addr1_index); - } -} -//--------------------------------------------------------------------------- -void nasmt_create_mask_ipv4_addr(struct in_addr *masked_addrP, int prefix_len) -{ - //--------------------------------------------------------------------------- - if (prefix_len > 32) { - prefix_len = 32; - } - - masked_addrP->s_addr = 0xFFFFFFFF << (32 - prefix_len); - return; -} - -//--------------------------------------------------------------------------- -// Add a new classifier rule (send direction) -struct classifier_entity *nasmt_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_sclassifier: begin for dscp %d, classref %d\n", dscp,classref); -#endif - - if (cx==NULL) { - printk("nasmt_CLASS_add_sclassifier - input parameter cx is NULL \n"); - return NULL; - } - - //*** - for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next) { - if (gc->classref==classref) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_sclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; - } - } - - gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_ATOMIC); - - if (gc==NULL) - return NULL; - - memset(gc, 0, sizeof(struct classifier_entity)); - gc->next=cx->sclassifier[dscp]; - gc->classref=classref; - cx->sclassifier[dscp]=gc; - ++cx->nsclassifier; - ++gpriv->next_sclassref; //increment send classref index - MW 15/01/07 -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_sclassifier: classifier created for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; -} - -//--------------------------------------------------------------------------- -// Add a new classifier rule (receive direction) -struct classifier_entity *nasmt_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_rclassifier: begin\n"); -#endif - - //*** - for (gc=gpriv->rclassifier[dscp]; gc!=NULL; gc=gc->next) { - if (gc->classref==classref) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_rclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; - } - } - - gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL); - - if (gc==NULL) - return NULL; - - gc->next=gpriv->rclassifier[dscp]; - gc->classref=classref; - gpriv->rclassifier[dscp]=gc; - ++gpriv->nrclassifier; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_add_rclassifier: classifier created for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; -} - -//--------------------------------------------------------------------------- -void nasmt_CLASS_flush_sclassifier(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t dscpi; - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_flush_sclassifier: begin\n"); -#endif - - if (cx==NULL) { - printk("nasmt_CLASS_flush_sclassifier - input parameter cx is NULL \n"); - return; - } - - //*** - for (dscpi=0; dscpisclassifier[dscpi]; gc!=NULL; gc=cx->sclassifier[dscpi]) { - cx->sclassifier[dscpi]=gc->next; - kfree(gc); - } - } - - cx->nsclassifier=0; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_flush_sclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -void nasmt_CLASS_flush_rclassifier() -{ - //--------------------------------------------------------------------------- - uint8_t dscpi; - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_flush_rclassifier: begin\n"); -#endif - - //*** - for (dscpi=0; dscpirclassifier[dscpi]; gc!=NULL; gc=gpriv->rclassifier[dscpi]) { - gpriv->rclassifier[dscpi]=gc->next; - kfree(gc); - } - } - - gpriv->nrclassifier=0; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_flush_rclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete a classifier rule (send direction) -void nasmt_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *p,*np; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_del_sclassifier: begin\n"); -#endif - - if (cx==NULL) { - printk("nasmt_CLASS_del_sclassifier - input parameter cx is NULL \n"); - return; - } - - //*** - p=cx->sclassifier[dscp]; - - if (p==NULL) - return; - - if (p->classref==classref) { - cx->sclassifier[dscp]=p->next; - kfree(p); - --cx->nsclassifier; - return; - } - - for (np=p->next; np!=NULL; p=np) { - if (np->classref==classref) { - p->next=np->next; - kfree(np); - --cx->nsclassifier; - return; - } - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_del_sclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete a classifier rule (receive direction) -void nasmt_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *p,*np; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_del_rclassifier: begin\n"); -#endif - //*** - p=gpriv->rclassifier[dscp]; - - if (p==NULL) - return; - - if (p->classref==classref) { - gpriv->rclassifier[dscp]=p->next; - kfree(p); - --gpriv->nrclassifier; - return; - } - - for (np=p->next; np!=NULL; p=np) { - if (np->classref==classref) { - p->next=np->next; - kfree(np); - --gpriv->nrclassifier; - return; - } - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_del_rclassifier: end\n"); -#endif -} - -/* ORIGINAL VERSION -//--------------------------------------------------------------------------- -// Search the entity with the IPv6 address 'addr' -struct cx_entity *nasmt_CLASS_cx6(struct sk_buff *skb){ -//--------------------------------------------------------------------------- - uint8_t cxi; - #ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx6: begin\n"); - #endif - cxi=0; - return gpriv->cx+cxi; -}*/ - -//--------------------------------------------------------------------------- -// Search the entity with the IPv6 address 'addr' -// Navid: the ipv6 classifier is not fully tested -struct cx_entity *nasmt_CLASS_cx6(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; - struct cx_entity *cx = NULL; - struct classifier_entity *sclassifier= NULL; - uint32_t mc_addr_hdr; - struct in6_addr masked_addr; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx6: begin\n"); -#endif - - if (skb) { -#ifdef NAS_DEBUG_CLASS - printk("SOURCE ADDR %X:%X:%X:%X:%X:%X:%X:%X",NIP6ADDR(&(ipv6_hdr(skb)->saddr))); - printk(" DEST ADDR %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&(ipv6_hdr(skb)->daddr))); -#endif - mc_addr_hdr = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0]); - - // First check if multicast [1st octet is FF] - if ((mc_addr_hdr & 0xFF000000) == 0xFF000000) { - // packet type according to the scope of the multicast packet - // we don't consider RPT bits in second octet [maybe done later if needed] - switch(mc_addr_hdr & 0x000F0000) { - case (0x00020000): - *paddr_type = NAS_IPV6_ADDR_MC_SIGNALLING; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx6: multicast packet - signalling \n"); -#endif - break; - - default: - printk("nasmt_CLASS_cx6: default multicast\n"); - *paddr_type = NAS_IPV6_ADDR_UNKNOWN; - } - } else { - // This is not multicast, so we should be able to identify the MT - *paddr_type = NAS_IPV6_ADDR_UNICAST; - cxi = 0; - (*cx_index)++; - sclassifier = gpriv->cx[cxi].sclassifier[dscp]; - - while (sclassifier!=NULL) { - // verify that this is an IPv6 classifier - if ((sclassifier->version == NAS_VERSION_6) || (sclassifier->version == NAS_VERSION_DEFAULT)) { - /*LGif (IN6_IS_ADDR_UNSPECIFIED(&(sclassifier->daddr.ipv6))) { - printk("nas_CLASS_cx6: addr is null \n"); - sclassifier = sclassifier->next; - continue; - }*/ -#ifdef NAS_DEBUG_CLASS - printk("cx %d : DSCP %d %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, dscp, NIP6ADDR(&(sclassifier->daddr.ipv6))); -#endif //NAS_DEBUG_CLASS - - //if ((dst = (unsigned int*)&(((struct rt6_info *)skbdst)->rt6i_gateway)) == 0){ - // LG: STRANGE - if (IN6_IS_ADDR_UNSPECIFIED(&ipv6_hdr(skb)->daddr)) { - printk("nasmt_CLASS_cx6: dst addr is null \n"); - sclassifier = sclassifier->next; - continue; - } - - nasmt_create_mask_ipv6_addr(&masked_addr, sclassifier->dplen); - // Modified MW to check only the iid6 - masked_addr.s6_addr32[0] = 0x00000000; - masked_addr.s6_addr32[1] = 0x00000000; - - if (IN6_ARE_ADDR_MASKED_EQUAL(&ipv6_hdr(skb)->daddr, &(sclassifier->daddr.ipv6), &masked_addr)) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx6: found cx %d: %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, NIP6ADDR(&(sclassifier->daddr.ipv6))); -#endif //NAS_DEBUG_CLASS - return &gpriv->cx[cxi]; - } - } - - // Go to next classifier entry for connection - sclassifier = sclassifier->next; - } - } - } - - //printk("nas_CLASS_cx6 NOT FOUND: %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&ipv6_hdr(skb)->daddr)); - return cx; -} - -/* ORIGINAL VERSION -//--------------------------------------------------------------------------- -// Search the entity with the IPv4 address 'addr' -struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb){ -//--------------------------------------------------------------------------- - uint8_t cxi; - #ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx4: begin\n"); - #endif - cxi=0; - return gpriv->cx+cxi; -}*/ - -//--------------------------------------------------------------------------- -// Search the entity with the IPv4 address 'addr' -struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index) -{ - //--------------------------------------------------------------------------- - unsigned char cxi; - uint32_t daddr; - struct cx_entity *cx=NULL; - struct classifier_entity *pclassifier=NULL; - struct in_addr masked_addr; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx4: begin\n"); -#endif - - if (skb!=NULL) { - daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; - - if (daddr != INADDR_ANY) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx4: SOURCE ADDR %d.%d.%d.%d",NIPADDR(ip_hdr(skb)->saddr)); - printk(" DEST ADDR %d.%d.%d.%d\n",NIPADDR(ip_hdr(skb)->daddr)); -#endif - - if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { - // TO BE CHECKED - *paddr_type = NAS_IPV4_ADDR_MC_SIGNALLING; - } else { - if (ipv4_is_lbcast(ip_hdr(skb)->daddr)) { - // TO BE CHECKED - *paddr_type = NAS_IPV4_ADDR_BROADCAST; - } else { - if (IN_CLASSA(ip_hdr(skb)->daddr) || IN_CLASSB(ip_hdr(skb)->daddr) || IN_CLASSC(ip_hdr(skb)->daddr)) { - *paddr_type = NAS_IPV4_ADDR_UNICAST; - cxi = 0; - (*cx_index)++; - pclassifier = gpriv->cx[cxi].sclassifier[dscp]; - - while (pclassifier!=NULL) { - // verify that this is an IPv4 classifier - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); - - if (IN_ARE_ADDR_MASKED_EQUAL(&ip_hdr(skb)->daddr, &(pclassifier->daddr.ipv4), &masked_addr)) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_cx4: IP MASK MATCHED: found cx %d: %d.%d.%d.%d/%d\n",cxi, NIPADDR(pclassifier->daddr.ipv4), pclassifier->dplen); -#endif - return &gpriv->cx[cxi]; - } - } - - // goto to next classification rule for the connection - pclassifier = pclassifier->next; - } - } else { - *paddr_type = NAS_IPV4_ADDR_UNKNOWN; - } - } - } - } - } - - return cx; -} - -//--------------------------------------------------------------------------- -// Search the sending function for IP Packet -void nasmt_CLASS_send(struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *pclassifier, *sp; - uint8_t *protocolh = NULL; - uint8_t version; - uint8_t protocol, dscp; - uint16_t classref; - struct cx_entity *cx; -#ifdef NAS_DEBUG_CLASS - char sfct[10], sprotocol[10]; -#endif - struct net_device *dev = gdev; - unsigned char cx_index,no_connection; - int addr_type; - struct in6_addr masked6_addr; - struct in_addr masked_addr; - // RARP vars - struct arphdr *rarp; - unsigned char *rarp_ptr; - /* s for "source", t for "target" */ - __be32 sip, tip; - unsigned char *sha, *tha; - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: begin -\n"); -#endif - - if (skb==NULL) { - printk("nasmt_CLASS_send - input parameter skb is NULL \n"); - return; - } - - //*** -#ifdef NAS_DEBUG_SEND - printk("nasmt_CLASS_send - Received IP packet to transmit:"); - - if ((skb->data) != NULL) { - if (skb->len<100) - nasmt_TOOL_print_buffer(skb->data,skb->len); - else - nasmt_TOOL_print_buffer(skb->data,100); - } - -#endif - //*** - // find all connections related to socket - cx_index = 0; - no_connection = 1; - cx = NULL; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: [before switch on IP protocol version] \n"); -#endif - - - // Get mobile connexion entity, protocol and dscp from IP packet - switch (ntohs(skb->protocol)) { - case ETH_P_IPV6: -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : skb->protocol : IPv6 \n"); -#endif - version = NAS_VERSION_6; - addr_type = NAS_IPV6_ADDR_UNKNOWN; - protocolh = nasmt_TOOL_get_protocol6(ipv6_hdr(skb), &protocol); - dscp = nasmt_TOOL_get_dscp6 (ipv6_hdr(skb)); - cx = nasmt_CLASS_cx6 (skb, dscp, &addr_type, &cx_index); -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send - ETH_P_IPV6 skb %p dscp %d gpriv %p cx_index %p \n",skb, dscp, gpriv, &cx_index); -#endif - - // find in default DSCP a valid classification - if (cx == NULL) { - switch (addr_type) { - case NAS_IPV6_ADDR_MC_SIGNALLING: - case NAS_IPV6_ADDR_UNICAST: - pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier!=NULL) { - if ((pclassifier->version == NAS_VERSION_6) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasmt_create_mask_ipv6_addr(&masked6_addr, pclassifier->dplen); - - if (IN6_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv6, &ipv6_hdr(skb)->daddr, &masked6_addr)) { - // then force dscp - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if(IN6_IS_ADDR_UNSPECIFIED(&pclassifier->daddr.ipv6)) { - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_IS_ADDR_UNSPECIFIED\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - - break; - - // should have found a valid classification rule - case NAS_IPV6_ADDR_UNKNOWN: - default: - printk("nasmt_CLASS_send: No corresponding address type\n"); - } - } - - break; - - case ETH_P_ARP: -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : skb->protocol : ARP \n"); -#endif - version = NAS_VERSION_4; - addr_type = NAS_IPV4_ADDR_BROADCAST; - dscp = 0; - cx = NULL; - // Basic sanity checks can be done without the lock - rarp = (struct arphdr *)skb_network_header(skb); - - if (rarp) { - if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) { - printk("nasmt_CLASS_send: ARP PACKET WRONG ADDR LEN or WRONG ARP HEADER TYPE\n"); - break; - } - } else { - printk("nasmt_CLASS_send: ARP HEADER POINTER IS NULL\n"); - break; - } - - // If it's not Ethernet, delete it. - if (rarp->ar_pro != htons(ETH_P_IP)) { - printk("nasmt_CLASS_send: ARP PACKET PROTOCOL IS NOT ETHERNET\n"); - break; - } - - rarp_ptr = (unsigned char *) (rarp + 1); - sha = rarp_ptr; - rarp_ptr += dev->addr_len; - memcpy(&sip, rarp_ptr, 4); - rarp_ptr += 4; - tha = rarp_ptr; - rarp_ptr += dev->addr_len; - memcpy(&tip, rarp_ptr, 4); -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: ARP DEST IP transport IP = %d.%d.%d.%d\n",NIPADDR(tip)); -#endif - pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier!=NULL) { - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: MASK = %d.%d.%d.%d\n",NIPADDR(masked_addr.s_addr)); -#endif - - // - if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &tip, &masked_addr.s_addr)) { - // then force dscp - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n", pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if (INADDR_ANY == pclassifier->daddr.ipv4) { - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - - break; - - case ETH_P_IP: -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : skb->protocol : IPv4 \n"); -#endif - version = NAS_VERSION_4; - addr_type = NAS_IPV4_ADDR_UNKNOWN; - dscp = nasmt_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb))); - cx = nasmt_CLASS_cx4(skb, dscp, &addr_type, &cx_index); - protocolh = nasmt_TOOL_get_protocol4((struct iphdr *)(skb_network_header(skb)), &protocol); - - // find in default DSCP a valid classification - if (cx == NULL) { - switch (addr_type) { - case NAS_IPV4_ADDR_MC_SIGNALLING: - case NAS_IPV4_ADDR_UNICAST: - case NAS_IPV4_ADDR_BROADCAST: - pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier != NULL) { - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : MASK = %d.%d.%d.%d\n", NIPADDR(masked_addr.s_addr)); -#endif - - if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &ip_hdr(skb)->daddr, &masked_addr.s_addr)) { - // then force dscp - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if(INADDR_ANY == pclassifier->daddr.ipv4) { - cx = &gpriv->cx[0]; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - - break; - - // should have found a valid classification rule - case NAS_IPV4_ADDR_UNKNOWN: - default: - printk("nasmt_CLASS_send: No corresponding address type\n"); - } - } - -#ifdef NAS_DEBUG_CLASS - - //printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %08X\n",ntohs(skb->protocol),dscp,cx); - if (cx) - printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %d\n",ntohs(skb->protocol),dscp,cx->lcr); - else - printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, No valid connection\n",ntohs(skb->protocol),dscp); - -#endif - break; - - default: - printk("nasmt_CLASS_send: Unknown IP version protocol\n"); - version = 0; - return; - } - -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasmt_CLASS_send: [before if (cx != NULL)]\n"); -#endif - - // If a valid connection for the DSCP/EXP with destination address - // is found scan all protocol-based classification rules - if (cx != NULL) { - classref = 0; - sp = NULL; - - if (cx->state!=NAS_CX_DCH) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: UE not connected, in state %d. Packet is dropped\n",cx->state); -#endif - return; - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: DSCP %d version %d: looking for classifier entry\n",dscp, version); -#endif - - for (pclassifier=cx->sclassifier[dscp]; pclassifier!=NULL; pclassifier=pclassifier->next) { -#ifdef NAS_DEBUG_CLASS - printk("nasmt_CLASS_send: DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,pclassifier->classref,pclassifier->protocol,pclassifier->version); -#endif - - // normal rule checks that network protocol version matches - if ((pclassifier->version == version) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - //printk("nasmt_CLASS_send: IP version are equals\n"); - sp=pclassifier; - classref=sp->classref; -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasmt_CLASS_send: classifier found for dscp %u \n", dscp); -#endif - break; - } - } - - if (sp!=NULL) { -#ifdef NAS_DEBUG_CLASS - - //char sfct[10], sprotocol[10]; - // classifier entity found. Print its parameters - if (sp->fct==nasmt_COMMON_QOS_send) - strcpy(sfct, "data xfer"); - - if (sp->fct==nasmt_CTL_send) - strcpy(sfct, "iocontrol"); - - if (sp->fct==nasmt_COMMON_del_send) - strcpy(sfct, "delete"); - - if (sp->fct==nasmt_ASCTL_DC_send_sig_data_request) - strcpy(sfct, "DC-SAP"); - - switch(protocol) { - case NAS_PROTOCOL_UDP: - strcpy(sprotocol, "udp"); - printk("udp packet\n"); - break; - - case NAS_PROTOCOL_TCP: - strcpy(sprotocol, "tcp"); - printk("tcp packet\n"); - break; - - case NAS_PROTOCOL_ICMP4: - strcpy(sprotocol, "icmp4"); - printk("icmp4 packet\n"); - break; - - case NAS_PROTOCOL_ICMP6: - strcpy(sprotocol, "icmp6"); - nasmt_TOOL_pk_icmp6((struct icmp6hdr*)protocolh); - break; - - default: - strcpy(sprotocol, "other L4"); - break; - } - - printk("nasmt_CLASS_send: (dscp %u, %s) received, (classref %u, fct %s, drb_id %u) classifier rule\n", - dscp, sprotocol, sp->classref, sfct, sp->rab_id); -#endif - - //forward packet to the correct entity - if (sp->fct!=NULL) { - sp->fct(skb, cx, sp); - } else { - printk("\n\nnasmt_CLASS_send: ERROR : CLASSIFIER FUNCTION IS NULL\n\n"); - } - - no_connection = 0; - // end : if classifier entry match found - } else { - printk("nasmt_CLASS_send: no corresponding item in the classifier list, so the message is dropped\n"); - printk("nasmt_CLASS_send: packet parameters: dscp %u, %s\n", dscp, sprotocol); - nasmt_COMMON_del_send(skb, cx, NULL); // Note MW: LG has commented this line. Why? - } - } // if connection found - -#ifdef NAS_DEBUG_CLASS - - if (no_connection == 1) { - printk("nasmt_CLASS_send: no corresponding connection, so the message is dropped\n"); - } - - printk("nasmt_CLASS_send: end\n"); -#endif -} diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_common.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_common.c deleted file mode 100644 index bbafa86ad1..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_common.c +++ /dev/null @@ -1,542 +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 nasmt_common.c -* \brief Common functions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasmt_variables.h" -#include "nasmt_proto.h" - -#include -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif - -//--------------------------------------------------------------------------- -// Receive data from FIFO (QOS or DC) -//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlen, int sap){ -//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlen, void *pdcp_sdu, int sap){ -void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap) -{ - //--------------------------------------------------------------------------- - struct sk_buff *skb; - struct ipversion *ipv; - unsigned int hard_header_len; - uint16_t *p_ether_type; - uint16_t ether_type; - -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: begin\n"); -#endif -#ifdef PDCP_USE_NETLINK - - // data_buffer is NULL if FIFOs - if (!data_buffer) { - printk("nasmt_COMMON_receive - input parameter data_buffer is NULL \n"); - return; - } - -#endif - - skb = dev_alloc_skb( payload_length + 2 ); - - if(!skb) { - printk("nasmt_COMMON_receive: low on memory\n"); - ++gpriv->stats.rx_dropped; - return; - } - - skb_reserve(skb,2); - -#ifndef PDCP_USE_NETLINK - bytes_read += rtf_get(sap, skb_put(skb, payload_length), payload_length); - - if (bytes_read != NAS_PDCPH_SIZE + payload_length) { - printk("nasmt_COMMON_receive: problem while reading DC sap\n"); - kfree(skb->data); - dev_kfree_skb(skb); - return; - } - -#else - memcpy(skb_put(skb, payload_length), data_buffer, payload_length); - bytes_read += payload_length; -#endif - -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: received packet from PDCP, length %d\n", bytes_read); -#endif - - skb->dev = gdev; - hard_header_len = gdev->hard_header_len; - skb->mac_header = skb->data; - skb->pkt_type = PACKET_HOST; - skb->ip_summed = CHECKSUM_UNNECESSARY; - - ipv = (struct ipversion *)&(skb->data[hard_header_len]); - - switch (ipv->version) { - case 6: -#ifdef NAS_DEBUG_RECEIVE_BASIC - printk("nasmt_COMMON_receive: receive IPv6 message\n"); -#endif - skb->network_header = &skb->data[hard_header_len]; - // set protocol default value - skb->protocol = htons(ETH_P_IPV6); - // If type Ethernet, correct it -#ifdef NAS_DRIVER_TYPE_ETHERNET - skb->protocol = eth_type_trans(skb, gdev); -#endif - break; - - case 4: -#ifdef NAS_DEBUG_RECEIVE_BASIC - printk("nasmt_COMMON_receive: receive IPv4 message\n"); -#endif - -#ifdef NAS_DEBUG_RECEIVE - addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr; - - if (addr) { - printk("nasmt_COMMON_receive: Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]); - } - - addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr; - - if (addr) { - printk("[NAS][COMMON][RECEIVE] Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]); - } - - printk("[NAS][COMMON][RECEIVE] protocol %d\n",((struct iphdr *)&skb->data[hard_header_len])->protocol); -#endif - - skb->network_header = &skb->data[hard_header_len]; - // set protocol default value - skb->protocol = htons(ETH_P_IP); - // If type Ethernet, correct it -#ifdef NAS_DRIVER_TYPE_ETHERNET - skb->protocol = eth_type_trans(skb, gdev); -#endif - break; - - default: - printk("nasmt_COMMON_receive: Packet is not IPv4 or IPv6 (version=%d)\n", ipv->version); - -#ifdef NAS_DRIVER_TYPE_ETHERNET -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: ether_type=%04X\n", ether_type); -#endif - skb->protocol = eth_type_trans(skb, gdev); - // minus 1(short) instead of 2(bytes) because uint16_t* - p_ether_type = (uint16_t *)&(skb->mac_header[hard_header_len-2]); - ether_type = ntohs(*p_ether_type); -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: ether_type=%04X\n", ether_type); -#endif - - switch (ether_type) { - case ETH_P_ARP: - printk("[NAS][COMMON] ether_type = ETH_P_ARP\n"); - skb->protocol = htons(ETH_P_ARP); - skb->network_header = &skb->mac_header[hard_header_len]; - break; - - default: - break; - } - -#endif - } - - ++gpriv->stats.rx_packets; - gpriv->stats.rx_bytes += bytes_read; -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: forwarding packet of size %d to kernel\n",skb->len); -#endif - - netif_rx(skb); -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_receive: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete the data -void nasmt_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp) -{ - //--------------------------------------------------------------------------- -#ifdef NAS_DEBUG_SEND - printk("nasmt_COMMON_del_send - updating statistics \n"); -#endif - ++gpriv->stats.tx_dropped; -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (QoS SAP) -void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - //struct pdcp_data_req pdcph; - struct pdcp_data_req_header_t pdcph; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_SEND - printk("nasmt_COMMON_QOS_send - begin \n"); -#endif - - // if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR - // { - // gpriv->stats.tx_dropped ++; - // printk("NAS_QOS_SEND: No connected, so message are dropped \n"); - // return; - // } - if (!skb || !gc || !cx) { - printk("nasmt_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n"); - return; - } - - // End debug information - - if (gc->rb==NULL) { - gc->rb = nasmt_COMMON_search_rb(cx, gc->rab_id); - - if (gc->rb==NULL) { - ++gpriv->stats.tx_dropped; - printk("nasmt_COMMON_QOS_send: No corresponding Radio Bearer, so message is dropped, rab_id=%u \n", gc->rab_id); - return; - } - } - -#ifdef NAS_DEBUG_SEND - printk("nasmt_COMMON_QOS_send #1 :"); - printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id); - nasmt_TOOL_print_classifier(gc); -#endif - - pdcph.data_size = skb->len; - pdcph.rb_id = ((gc->rb)->rab_id+(32*cx->lcr))-NAS_SIG_NUM_SRB; - pdcph.inst = 0; - -#ifdef PDCP_USE_NETLINK - bytes_wrote = nasmt_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP); - //printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len); -#else - //bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE); - bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE); - //printk("nasmt_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len); -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != NAS_PDCPH_SIZE) { - printk("nasmt_COMMON_QOS_send: problem while writing PDCP's header\n"); - printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef PDCP_USE_NETLINK - bytes_wrote += nasmt_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP); -#else - //bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len); - bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len); -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != skb->len + NAS_PDCPH_SIZE) { - printk("nasmt_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion - printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef NAS_DEBUG_SEND - printk("nasmt_COMMON_QOS_send - %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id,NAS2PDCP_FIFO); -#endif - gpriv->stats.tx_bytes += skb->len; - gpriv->stats.tx_packets ++; -#ifdef NAS_DEBUG_SEND - printk("nasmt_COMMON_QOS_send - end \n"); -#endif -} - -#ifndef PDCP_USE_NETLINK -//--------------------------------------------------------------------------- -void nasmt_COMMON_QOS_receive(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t sapi; - //struct pdcp_data_ind pdcph; - struct pdcp_data_ind_header_t pdcph; - int bytes_read = 0; - - // Start debug information -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_QOS_receive - begin \n"); -#endif - - if (!cx) { - printk("nasmt_COMMON_QOS_receive - input parameter cx is NULL \n"); - return; - } - - // End debug information - - // LG force the use of only 1 rt fifo - sapi = NAS_DRB_OUTPUT_SAPI; - - bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE); - - while (bytes_read>0) { - if (bytes_read != NAS_PDCPH_SIZE) { - printk("nasmt_COMMON_QOS_receive: problem while reading PDCP header\n"); - return; - } - - //void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - // data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer) - nasmt_COMMON_receive(NAS_PDCPH_SIZE, pdcph.data_size, NULL, pdcph->rb_id, gpriv->sap[sapi]); - // check if another frame is in the FIFO, otherwise return - bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE); - } - -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_QOS_receive - end \n"); -#endif -} - -#else -//--------------------------------------------------------------------------- -void nasmt_COMMON_QOS_receive(struct nlmsghdr *nlh) -{ - //--------------------------------------------------------------------------- - - struct pdcp_data_ind_header_t *pdcph; - - // Start debug information -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_QOS_receive - begin \n"); -#endif - - if (!nlh) { - printk("nasmt_COMMON_QOS_receive - input parameter nlh is NULL \n"); - return; - } - - // End debug information - pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh); - -#ifdef NAS_DEBUG_RECEIVE - printk("nasmt_COMMON_QOS_receive - receive from PDCP, size %d, rab %d\\n", pdcph->data_size, pdcph->rb_id); -#endif //NAS_DEBUG_RECEIVE - - //void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - nasmt_COMMON_receive(NAS_PDCPH_SIZE + pdcph->data_size, pdcph->data_size, (unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE, pdcph->rb_id, 0); - -} -#endif //PDCP_USE_NETLINK - - -//--------------------------------------------------------------------------- -struct cx_entity *nasmt_COMMON_search_cx(nasLocalConnectionRef_t lcr) -{ - //--------------------------------------------------------------------------- -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_search_cx - lcr %d\n",lcr); -#endif - - if (lcrcx+lcr; - else - return NULL; -} - -//--------------------------------------------------------------------------- -// Search a Radio Bearer -struct rb_entity *nasmt_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_search_rb - rab_id %d\n", rab_id); -#endif - - if (!cx) { - printk("nasmt_COMMON_search_rb - input parameter cx is NULL \n"); - return NULL; - } - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->rab_id==rab_id) - return rb; - } - - return NULL; -} - -//--------------------------------------------------------------------------- -struct rb_entity *nasmt_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_add_rb - begin for rab_id %d , qos %d\n", rab_id, qos ); -#endif - - if (cx==NULL) { - printk("nasmt_COMMON_add_rb - input parameter cx is NULL \n"); - return NULL; - } - - rb=nasmt_COMMON_search_rb(cx, rab_id); - - if (rb==NULL) { - rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL); - - if (rb!=NULL) { - rb->retry=0; - rb->countimer=NAS_TIMER_IDLE; - rb->rab_id=rab_id; - // rb->rab_id=rab_id+(32*cx->lcr); -#ifdef NAS_DEBUG_DC - printk("nasmt_COMMON_add_rb: rb rab_id=%u, rab_id=%u, mt_id=%u\n",rb->rab_id,rab_id, cx->lcr); -#endif - rb->qos=qos; - rb->sapi=NAS_DRB_INPUT_SAPI; - // LG force the use of only one rt-fifo rb->sapi=NAS_BA_INPUT_SAPI; - rb->state=NAS_IDLE; - rb->next=cx->rb; - cx->rb=rb; - ++cx->num_rb; - } else - printk("nasmt_COMMON_add_rb: no memory\n"); - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_add_rb - end \n" ); -#endif - return rb; -} - -//--------------------------------------------------------------------------- -// free the memory that has previously been allocated to rb and remove from linked list -void nasmt_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb, *curr_rb, *prev_rb; - struct classifier_entity *p; - uint16_t classref=0; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_del_rb - begin\n"); -#endif - - if (cx==NULL) { - printk("nasmt_COMMON_del_rb - input parameter cx is NULL \n"); - return; - } - - // End debug information - - // Clear the associated classifier - for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) { - if (p->classref>=classref) { - classref=p->classref; -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_del_rb: classifier found for dscp %u \n", dscp); -#endif - } - } - - nasmt_CLASS_del_sclassifier(cx, dscp, classref); - - // Now, delete the RB - curr_rb = NULL; - prev_rb = NULL; - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->rab_id == rab_id) { - curr_rb = rb; - - if (prev_rb!=NULL) { - prev_rb->next = rb->next; - } else { - cx->rb=rb->next; - } - - break; - } else { - prev_rb = rb; - } - } - - if (curr_rb!= NULL) { - printk("nasmt_COMMON_del_rb: del rab_id %u\n", rb->rab_id); - kfree(rb); - (cx->num_rb)--; - } else { - printk("\n\n--nasmt_COMMON_del_rb: ERROR, invalid rab_id %u\n", rb->rab_id); - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_del_rb - end\n"); -#endif -} - -//--------------------------------------------------------------------------- -void nasmt_COMMON_flush_rb(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; - struct classifier_entity *gc; - uint8_t dscp; - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_flush_rb - begin\n"); -#endif - - if (cx==NULL) { - printk("nasmt_COMMON_flush_rb - input parameter cx is NULL \n"); - return; - } - - // End debug information - for (rb=cx->rb; rb!=NULL; rb=cx->rb) { - printk("nasmt_COMMON_flush_rb: del rab_id %u\n", rb->rab_id); - cx->rb=rb->next; - kfree(rb); - } - - cx->num_rb=0; - cx->rb=NULL; - - for(dscp=0; dscpsclassifier[dscp]; gc!=NULL; gc=gc->next) - gc->rb=NULL; - } - -#ifdef NAS_DEBUG_CLASS - printk("nasmt_COMMON_flush_rb - end\n"); -#endif -} diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_constant.h b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_constant.h deleted file mode 100644 index bdba11ff79..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_constant.h +++ /dev/null @@ -1,210 +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 nasmt_constant.h -* \brief Defines all constants for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASMTD_CST -#define _NASMTD_CST - -//Debug flags -#define NAS_DEBUG_DC -//#define NAS_DEBUG_DC_DETAIL // detail of DC-SAP operation -#define NAS_DEBUG_SEND -#define NAS_DEBUG_SEND_DETAIL // detail of packet transmission -//#define NAS_DEBUG_RECEIVE -#define NAS_DEBUG_RECEIVE_BASIC -#define NAS_DEBUG_CLASS -//#define NAS_DEBUG_GC -//#define NAS_DEBUG_DC_MEASURE -//#define NAS_DEBUG_TIMER -#define NAS_DEBUG_DEVICE -//#define NAS_DEBUG_INTERRUPT -//#define NAS_DEBUG_TOOL -#define NETLINK_DEBUG -//#define NAS_DEBUG_RRCNL // RRC netlink socket - -// Other flags -#define DEMO_3GSM -#define ENABLE_SLEEP_MODE - -// Parameters for the default RAB started after attachment (needs DEMO_3GSM defined) -#define NASMT_DEFAULTRAB_CLASSREF 1 //MW-01/01/07- -#define NASMT_DEFAULTRAB_DSCP 0 //MW-01/01/07- -#define NASMT_DEFAULTRAB_IPVERSION NAS_VERSION_DEFAULT //MW-01/01/07- - -#define NAS_DEFAULT_IPv6_PREFIX_LENGTH 128 // used to compare destination address - - -// General Constants -#define NAS_MTU 1500 -#define NAS_TX_QUEUE_LEN 100 -#define NAS_ADDR_LEN 8 -#define NAS_INET6_ADDRSTRLEN 46 -#define NAS_INET_ADDRSTRLEN 16 - -#define NAS_RESET_RX_FLAGS 0 - -#define NAS_CX_MAX 1 -//#define NAS_CX_MULTICAST_ALLNODE 2 -#define NASMT_MBMS_SVCES_MAX 4 // Identical to RRC constant - -#define NAS_RETRY_LIMIT_DEFAULT 5 - -#define NAS_MESSAGE_MAXLEN 1600 - -// UMTS -#define NAS_SIG_SRB3 3 -#define NAS_SIG_SRB4 3 // not used yet -//LTE -#define NAS_SIG_NUM_SRB 3 // number of srbs in LTE to send Rb_Id to PDCP - -//peer-to-peer messages between NAS entities -#define NAS_CMD_OPEN_RB 1 -#define NAS_CMD_ENTER_SLEEP 2 -#define NAS_CMD_LEAVE_SLEEP 3 - -//#define NAS_IID1_CONTROL 0x0 -//#define NAS_IID2_CONTROL __constant_htonl(0xffffffff) - -//#define NAS_STATE_IDLE 0 -//#define NAS_STATE_CONNECTED 1 -//#define NAS_STATE_ESTABLISHMENT_REQUEST 2 -//#define NAS_STATE_ESTABLISHMENT_FAILURE 3 -//#define NAS_STATE_RELEASE_FAILURE 4 -#define NAS_CX_RELEASE_UNDEF_CAUSE 1 - -// MT+RG NAS States -#define NAS_IDLE 0x01 -// Connection -#define NAS_CX_FACH 0x06 -#define NAS_CX_DCH 0x0A -#define NAS_CX_RECEIVED 0x10 -#define NAS_CX_CONNECTING 0x04 -#define NAS_CX_RELEASING 0x08 -#define NAS_CX_CONNECTING_FAILURE 0x14 -#define NAS_CX_RELEASING_FAILURE 0x18 -// Radio Bearers -#define NAS_RB_ESTABLISHING 0x24 -#define NAS_RB_RELEASING 0x28 -#define NAS_RB_DCH 0x2A - - -#define NAS_TIMER_ESTABLISHMENT_DEFAULT 12 -#define NAS_TIMER_RELEASE_DEFAULT 2 -#define NAS_TIMER_IDLE UINT_MAX -#define NAS_TIMER_TICK HZ - -#define NAS_PDCPH_SIZE sizeof(struct pdcp_data_req_header_t) -#define NAS_IPV4_SIZE 20 -#define NAS_IPV6_SIZE 40 - -#define NAS_DIRECTION_SEND 0 -#define NAS_DIRECTION_RECEIVE 1 - -// function number -#define NAS_FCT_DEL_SEND 1 -#define NAS_FCT_QOS_SEND 2 -#define NAS_FCT_DC_SEND 3 -#define NAS_FCT_CTL_SEND 4 - -// type of IOCTL command -#define NASMT_IOCTL_RAL 0x89F0 - -// Error cause -#define NAS_ERROR_ALREADYEXIST 1 -#define NAS_ERROR_NOMEMORY 3 -#define NAS_ERROR_NOTMT 9 -#define NAS_ERROR_NOTRG 10 -#define NAS_ERROR_NOTIDLE 11 -#define NAS_ERROR_NOTCONNECTED 12 -#define NAS_ERROR_NORB 14 -#define NAS_ERROR_NOTCORRECTVALUE 32 -#define NAS_ERROR_NOTCORRECTLCR 33 -#define NAS_ERROR_NOTCORRECTDIR 34 -#define NAS_ERROR_NOTCORRECTDSCP 35 -#define NAS_ERROR_NOTCORRECTVERSION 36 -#define NAS_ERROR_NOTCORRECTRABI 37 - - -/**********************************************************/ -/* Constants related with IP protocols */ -/**********************************************************/ -// Destination address types -#define NAS_IPV6_ADDR_UNICAST 1 -#define NAS_IPV6_ADDR_MC_SIGNALLING 2 -#define NAS_IPV6_ADDR_MC_MBMS 3 -#define NAS_IPV6_ADDR_UNKNOWN 4 - -#define NAS_IPV4_ADDR_UNICAST 5 -#define NAS_IPV4_ADDR_MC_SIGNALLING 6 -#define NAS_IPV4_ADDR_BROADCAST 7 -#define NAS_IPV4_ADDR_UNKNOWN 8 - - -//#define NAS_PORT_CONTROL __constant_htons(0xc45) -//#define NAS_PORT_AUTHENTICATION __constant_htons(1811) - -//#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000) //Yan -#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0ff00000) - -// Network control codepoint 111000 + IP version 6 -#define NAS_FLOWINFO_NCONTROL __constant_htonl(0x6e000000) -// network control codepoint 111000 -#define NAS_DSCP_NCONTROL 56 //0x38 -// default codepoint 1000000 -#define NAS_DSCP_DEFAULT 64 -#define NAS_DSCP_MAX 65 - -#define NAS_PROTOCOL_DEFAULT 0 -#define NAS_PROTOCOL_TCP IPPROTO_TCP -#define NAS_PROTOCOL_UDP IPPROTO_UDP -#define NAS_PROTOCOL_ICMP4 IPPROTO_ICMP -#define NAS_PROTOCOL_ICMP6 IPPROTO_ICMPV6 - -#define NAS_PORT_DEFAULT __constant_htons(65535) -#define NAS_PORT_HTTP __constant_htons(80) - -#define NAS_VERSION_DEFAULT 0 -#define NAS_VERSION_4 4 -#define NAS_VERSION_6 6 //?MW - -/**********************************************************/ -/* Constants related with Netlink sockets */ -/**********************************************************/ -#define OAI_IP_DRIVER_NETLINK_ID 31 -#define NL_DEST_PID 1 - -// defined in rrc_nas_sap.h -//#define NAS_RRCNL_ID 30 -//#define NL_DEST_RRC_PID 2 - -#define NASNL_DEST_PDCP 0 -#define NASNL_DEST_RRC 1 - -#endif - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c deleted file mode 100644 index efc8562bf9..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c +++ /dev/null @@ -1,565 +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 nasmt_device.c -* \brief Networking Device Driver for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef PDCP_USE_NETLINK -#ifdef RTAI -#include "rtai_posix.h" -#define RTAI_IRQ 30 //try to get this irq with RTAI -#endif // RTAI -#endif // PDCP_USE_NETLINK -//:::::::::::::::::::::::::::::::::::::::;; -#include "nasmt_variables.h" -#include "nasmt_proto.h" -//:::::::::::::::::::::::::::::::::::::::;; -//#include -#include -#include -#include -#include -#include - -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif -//:::::::::::::::::::::::::::::::::::::::;; -struct net_device *gdev; -struct nas_priv *gpriv; -//int bytes_wrote; -//int bytes_read; -uint8_t NAS_NULL_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00}; -uint8_t NAS_RG_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x01}; - -// TEMP -//uint8_t nas_IMEI[14]; -static unsigned char nas_IMEI[14]; -static int m_arg=0; - - -#ifdef PDCP_USE_NETLINK -extern void nasmt_netlink_release(void); -extern int nasmt_netlink_init(void); -#endif -extern void nasmt_ASCTL_timer(unsigned long data); - - -#ifndef PDCP_USE_NETLINK -//--------------------------------------------------------------------------- -//void nasmt_interrupt(void){ -void *nasmt_interrupt(void) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; - char *buffer = NULL; -#ifdef NAS_DEBUG_INTERRUPT - printk("nasmt_interrupt - begin\n"); -#endif - //spin_lock(&gpriv->lock); - cxi=0; - nasmt_COMMON_QOS_receive(gpriv->cx+cxi); - nasmt_ASCTL_GC_receive(buffer); - nasmt_ASCTL_DC_receive(gpriv->cx+cxi, buffer); - //spin_unlock(&gpriv->lock); -#ifdef NAS_DEBUG_INTERRUPT - printk("nasmt_interrupt: end\n"); -#endif -} -#endif //NETLINK - -//--------------------------------------------------------------------------- -// Called by ifconfig when the device is activated by ifconfig -int nasmt_open(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - printk("nasmt_open: begin\n"); - - gpriv=netdev_priv(dev); - - // Address has already been set at init -#ifndef PDCP_USE_NETLINK - - if (gpriv->irq==-EBUSY) { - printk("nasmt_open: irq failure\n"); - return -EBUSY; - } - -#endif //NETLINK - - // next lines prevent compilation of the driver with kernel version under 2.6.29 - // ATTENTION !!!!!! NASMT is not usable with these versions - - if(!netif_queue_stopped(dev)) - netif_start_queue(dev); - else - netif_wake_queue(dev); - - // - init_timer(&gpriv->timer); - (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; - (gpriv->timer).data=0L; - (gpriv->timer).function=nasmt_ASCTL_timer; - // ??LITE comments: add_timer(&gpriv->timer); - add_timer(&gpriv->timer); - // - printk("nasmt_open: name = %s, end\n", dev->name); - return 0; -} - -//--------------------------------------------------------------------------- -// Called by ifconfig when the device is desactivated by ifconfig -int nasmt_stop(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - struct nas_priv *priv = netdev_priv(dev); - printk("nasmt_stop: begin\n"); - del_timer(&priv->timer); - netif_stop_queue(dev); - - printk("nasmt_stop: name = %s, end\n", dev->name); - return 0; -} - -//--------------------------------------------------------------------------- -void nasmt_teardown(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - int cxi; -#ifndef PDCP_USE_NETLINK - struct nas_priv *priv = netdev_priv(dev); -#endif //PDCP_USE_NETLINK - - printk("nasmt_teardown: begin\n"); - // priv=(struct nas_priv *)(gdev.priv); - - if (dev) { -#ifndef PDCP_USE_NETLINK - - if (priv->irq!=-EBUSY) { - *pt_nas_ue_irq=-1; - rt_free_srq(priv->irq); - } - -#endif //PDCP_USE_NETLINK - -#ifdef PDCP_USE_NETLINK - nasmt_netlink_release(); -#endif //PDCP_USE_NETLINK - // for (sapi=0; sapisap[sapi]); - nasmt_CLASS_flush_rclassifier(); - cxi=0; - nasmt_COMMON_flush_rb(gpriv->cx+cxi); - nasmt_CLASS_flush_sclassifier(gpriv->cx+cxi); - // for (sapi=0; sapicx[cxi].sap[sapi]); - } // check dev - else { - printk("nasmt_teardown: Device is null\n"); - } - - printk("nasmt_teardown: end\n"); -} - -//--------------------------------------------------------------------------- -int nasmt_set_config(struct net_device *dev, struct ifmap *map) -{ - //--------------------------------------------------------------------------- - printk("nasmt_set_config: begin\n"); - - if (dev->flags & IFF_UP) - return -EBUSY; - - if (map->base_addr != dev->base_addr) { - printk(KERN_WARNING "nasmt_set_config: Can't change I/O address\n"); - return -EOPNOTSUPP; - } - - if (map->irq != dev->irq) - dev->irq = map->irq; - - printk("nasmt_set_config: end\n"); - return 0; -} - -//--------------------------------------------------------------------------- -// -int nasmt_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_DEVICE - printk("nasmt_hard_start_xmit: begin\n"); -#endif - - if ((!skb)||(!dev)) { - printk("nasmt_hard_start_xmit - input parameter skb or dev is NULL \n"); - return -1; - } - - // End debug information - netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - netif_trans_update(dev); -#else - dev->trans_start = jiffies; -#endif -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasmt_hard_start_xmit: step 1\n"); -#endif - nasmt_CLASS_send(skb); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasmt_hard_start_xmit: step 2\n"); -#endif - dev_kfree_skb(skb); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasmt_hard_start_xmit: step 3\n"); -#endif - netif_wake_queue(dev); -#ifdef NAS_DEBUG_DEVICE - printk("nasmt_hard_start_xmit: end\n"); -#endif - return 0; -} - -//--------------------------------------------------------------------------- -struct net_device_stats *nasmt_get_stats(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - // return &((struct nas_priv *)dev->priv)->stats; - struct nas_priv *npriv = netdev_priv(dev); - return &npriv->stats; -} - -//--------------------------------------------------------------------------- -// New function from LITE DRIVER -int nasmt_set_mac_address(struct net_device *dev, void *mac) -{ - //--------------------------------------------------------------------------- - struct sockaddr *addr = mac; - printk("nasmt_set_mac_address: begin\n"); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - return 0; -} - - -//--------------------------------------------------------------------------- -int nasmt_change_mtu(struct net_device *dev, int mtu) -{ - //--------------------------------------------------------------------------- - printk("nasmt_change_mtu: begin\n"); - - if ((mtu<50) || (mtu>1500)) - // if ((mtu<1280) || (mtu>1500)) - return -EINVAL; - - dev->mtu = mtu; - return 0; -} - -//--------------------------------------------------------------------------- -int nasmt_change_rx_flags(struct net_device *dev, int flags) -{ - //--------------------------------------------------------------------------- - //struct nas_priv *priv = netdev_priv(dev); - printk("nasmt_change_rx_flags %08X\n", flags); - gpriv->rx_flags ^= flags; - return 0; -} - -//--------------------------------------------------------------------------- -void nasmt_tx_timeout(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - /* Transmitter timeout, serious problems. */ - printk("nasmt_tx_timeout: begin\n"); - //((struct nas_priv *)(dev->priv))->stats.tx_errors++; - (gpriv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - netif_trans_update(dev); -#else - dev->trans_start = jiffies; -#endif - netif_wake_queue(dev); - printk("nasmt_tx_timeout: transmit timed out %s\n",dev->name); -} - -//--------------------------------------------------------------------------- -// Define pointers for the module -static const struct net_device_ops nasmt_netdev_ops = { - // ?? nasmt_interrupt - // - .ndo_open = nasmt_open, - .ndo_stop = nasmt_stop, - .ndo_start_xmit = nasmt_hard_start_xmit, - .ndo_validate_addr = NULL, - .ndo_get_stats = nasmt_get_stats, - //#ifdef KERNEL_VERSION_GREATER_THAN_32 - // .ndo_set_multicast_list = NULL, - .ndo_set_mac_address = nasmt_set_mac_address, - .ndo_set_config = nasmt_set_config, - .ndo_do_ioctl = nasmt_CTL_ioctl, - .ndo_change_mtu = nasmt_change_mtu, - .ndo_tx_timeout = nasmt_tx_timeout, - .ndo_change_rx_flags = nasmt_change_rx_flags, - //#endif -}; -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Initialisation of the network device -void nasmt_init(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - uint8_t cxi, dscpi; - - printk("nasmt_init: begin\n"); - - if (dev) { - gpriv=netdev_priv(dev); - memset(gpriv, 0, sizeof(struct nas_priv)); - // Initialize function pointers - dev->netdev_ops = &nasmt_netdev_ops; - -#ifndef NAS_DRIVER_TYPE_ETHERNET - // Update driver properties - dev->type = ARPHRD_EURUMTS; - dev->features = NETIF_F_NO_CSUM; - dev->hard_header_len = 0; - dev->addr_len = NAS_ADDR_LEN; - dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; - dev->tx_queue_len = NAS_TX_QUEUE_LEN; - dev->mtu = NAS_MTU; -#endif - // Can be one of the following enum defined in include/linux/netdevice.h: - // enum netdev_state_t { - // __LINK_STATE_START, - // __LINK_STATE_PRESENT, - // __LINK_STATE_NOCARRIER, - // __LINK_STATE_LINKWATCH_PENDING, - // __LINK_STATE_DORMANT, - // }; - set_bit(__LINK_STATE_PRESENT, &dev->state); - -#ifdef NAS_DRIVER_TYPE_ETHERNET - // overwrite values written above ( header_ops,type,hard_header_len,mtu,addr_len,tx_queue_len,flags,broadcast) - printk("\nnasmt_init: WARNING Driver type ETHERNET\n"); - ether_setup(dev); -#endif - - // - // Initialize private structure - gpriv->rx_flags = NAS_RESET_RX_FLAGS; - - gpriv->sap[NAS_GC_SAPI] = RRC_DEVICE_GC; - gpriv->sap[NAS_NT_SAPI] = RRC_DEVICE_NT; - gpriv->cx[0].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0; - gpriv->cx[0].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0; - - //gpriv->sap[NAS_CO_INPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_INPUT; - //gpriv->sap[NAS_CO_OUTPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_OUTPUT; - gpriv->sap[NAS_DRB_INPUT_SAPI] = PDCP2PDCP_USE_RT_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT; - gpriv->sap[NAS_DRB_OUTPUT_SAPI] = NAS2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT; - - gpriv->retry_limit = NAS_RETRY_LIMIT_DEFAULT; - gpriv->timer_establishment = NAS_TIMER_ESTABLISHMENT_DEFAULT; - gpriv->timer_release = NAS_TIMER_RELEASE_DEFAULT; - - for (dscpi=0; dscpirclassifier[dscpi] = NULL; - - gpriv->nrclassifier = 0; - // - cxi=0; -#ifdef NAS_DEBUG_DEVICE - printk("nasmt_init: init classifiers, state and timer for MT %u\n", cxi); -#endif - gpriv->cx[cxi].state = NAS_IDLE; - gpriv->cx[cxi].countimer = NAS_TIMER_IDLE; - gpriv->cx[cxi].retry = 0; - gpriv->cx[cxi].lcr = cxi; - gpriv->cx[cxi].rb = NULL; - gpriv->cx[cxi].num_rb = 0; - - // initialisation of the classifiers - for (dscpi=0; dscpicx[cxi].sclassifier[dscpi]=NULL; - } - - gpriv->cx[cxi].nsclassifier=0; - // initialisation of the IP address - nasmt_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)gpriv->cx[cxi].iid6); - gpriv->cx[cxi].iid4=0; - // - spin_lock_init(&gpriv->lock); - printk("nasmt_init: init IMEI to IID\n"); - -#ifdef NAS_DRIVER_TYPE_ETHERNET - nasmt_TOOL_eth_imei2iid(nas_IMEI, dev->dev_addr ,(uint8_t *)gpriv->cx[0].iid6, dev->addr_len); -#else - nasmt_TOOL_imei2iid(nas_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address) - nasmt_TOOL_imei2iid(nas_IMEI, (uint8_t *)gpriv->cx[0].iid6); -#endif - - nasmt_ASCTL_init(); - } else { - printk("\n\nnasmt_init: ERROR, Device is NULL!!\n"); - } - - printk("nasmt_init: end\n"); - return; -} - -//--------------------------------------------------------------------------- -int init_module (void) -{ - //--------------------------------------------------------------------------- - int err; - int inst = 0; - int index; - struct nas_priv *priv; - char devicename[100]; - - printk("\n\n\ninit_module: begin \n"); - - // check IMEI parameter - printk("number of IMEI parameters %d, IMEI ", m_arg); - - for (index = 0; index < m_arg; index++) { - printk("%02X ", nas_IMEI[index]); - } - - printk("\n"); - - -#ifndef PDCP_USE_NETLINK - - // Initialize parameters shared with RRC (done first to avoid going further) - if (pt_nas_ue_irq==NULL) { - printk("init_module: shared irq parameter not initialised\n"); - err = -EBUSY; - printk("init_module: returning %d \n\n", err); - return err; - } - - printk("init_module: pt_nas_ue_irq valid \n"); -#endif - - // Allocate device structure - sprintf(devicename,"oai%d",inst); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) - gdev = alloc_netdev(sizeof(struct nas_priv), devicename, nasmt_init); -#else - gdev = alloc_netdev(sizeof(struct nas_priv), devicename, NET_NAME_PREDICTABLE, nasmt_init); -#endif - priv = netdev_priv(gdev); - //// -#ifndef PDCP_USE_NETLINK - priv->irq=rt_request_srq(0, nasmt_interrupt, NULL); - - if (priv->irq == -EBUSY || priv->irq == -EINVAL) { - printk("\n init_module: No interrupt resource available\n"); - - if (gdev) { - free_netdev(gdev); - printk("init_module: free_netdev ..\n"); - } - - return -EBUSY; - } else - printk("init_module: Interrupt %d, ret = %d \n", priv->irq , ret); - - if (pt_nas_ue_irq==NULL) { - printk("init_module: shared irq parameter has been reset\n"); - } else { - *pt_nas_ue_irq=priv->irq; - } - -#endif - -#ifdef PDCP_USE_NETLINK - - if ((err=nasmt_netlink_init()) == -1) - printk("init_module: NETLINK failed\n"); - - printk("init_module: NETLINK INIT successful\n"); -#endif //NETLINK - // - err= register_netdev(gdev); - - if (err) { - printk("init_module: error %i registering device %s\n", err, gdev->name); - } else { - printk("init_module: registering device %s, ifindex = %d\n\n",gdev->name, gdev->ifindex); - } - - return err; -} - -//--------------------------------------------------------------------------- -void cleanup_module(void) -{ - //--------------------------------------------------------------------------- - printk("nasmt_cleanup_module: begin\n"); - unregister_netdev(gdev); - nasmt_teardown(gdev); - free_netdev(gdev); - printk("nasmt_cleanup_module: end\n\n\n\n"); -} - -//--------------------------------------------------------------------------- -// Replaced by init_module and cleanup_module -//module_init (nasmt_init_module); -//module_exit (nasmt_cleanup_module); -//--------------------------------------------------------------------------- - -#define DRV_NAME "oai_nasmt" -#define DRV_VERSION "3.0.1"DRV_NAME -#define DRV_DESCRIPTION "OPENAIR CELLULAR LTE NASMT Device Driver" -#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2013" -#define DRV_AUTHOR "Michelle Wetterwald "DRV_COPYRIGHT - -module_param_array_named(nas_IMEI,nas_IMEI,byte,&m_arg,0); -//module_param_array(oai_nw_drv_IMEI,byte,&m_arg,0444); -MODULE_PARM_DESC(nas_IMEI,"Terminal IMEI Identifier (14 digits, only first 10 significant if ETH option ON)"); - - -// MODULE_LICENSE("GPL"); -// MODULE_DESCRIPTION("LTE Driver for Mobile Terminal, playing as Non Access Stratum"); -// MODULE_AUTHOR("Michelle Wetterwald "); - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.c deleted file mode 100644 index 296ae78866..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.c +++ /dev/null @@ -1,764 +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 nasmt_iocontrol.c -* \brief I/O control functions for upper layers of driver for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasmt_variables.h" -#include "nasmt_iocontrol.h" -#include "nasmt_proto.h" - -//#include -#include -#include -#include - -extern int nasmt_ASCTL_DC_send_cx_establish_request(struct cx_entity *cx); - -// Statistic -//--------------------------------------------------------------------------- -void nasmt_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep) -{ - //--------------------------------------------------------------------------- - msgrep->rx_packets=gpriv->stats.rx_packets; - msgrep->tx_packets=gpriv->stats.tx_packets; - msgrep->rx_bytes=gpriv->stats.rx_bytes; - msgrep->tx_bytes=gpriv->stats.tx_bytes; - msgrep->rx_errors=gpriv->stats.rx_errors; - msgrep->tx_errors=gpriv->stats.tx_errors; - msgrep->rx_dropped=gpriv->stats.rx_dropped; - msgrep->tx_dropped=gpriv->stats.tx_dropped; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_statistic_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_statistic_reply msgrep; - printk("nasmt_ioCTL_statistic: stat requested\n"); - nasmt_set_msg_statistic_reply(&msgrep); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_statistic: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Connections List -//--------------------------------------------------------------------------- -void nasmt_set_msg_cx_list_reply(uint8_t *msgrep) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - nasLocalConnectionRef_t lcr; - struct nas_msg_cx_list_reply *list; - msgrep[0]=NAS_CX_MAX; - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - - for(lcr=0; lcrstate; - list[lcr].cellid=cx->cellid; - list[lcr].iid4=cx->iid4; - list[lcr].iid6[0]=cx->iid6[0]; - list[lcr].iid6[1]=cx->iid6[1]; - list[lcr].num_rb=cx->num_rb; - list[lcr].nsclassifier=cx->nsclassifier; - printk("nasmt_set_msg_cx_list_reply: nsc=%u\n",cx->nsclassifier); - } -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_cx_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1]; - printk("nasmt_ioCTL_cx_list: connection list requested\n"); - nasmt_set_msg_cx_list_reply(msgrep); - - if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) { - printk("nasmt_ioCTL_cx_list: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasmt_ioCTL_cx_list: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Connection Establishment -//--------------------------------------------------------------------------- -void nasmt_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep, struct nas_msg_cx_establishment_request *msgreq) -{ - //--------------------------------------------------------------------------- -#ifdef NODE_RG - msgrep->status=-NAS_ERROR_NOTMT; -#else - struct cx_entity *cx; - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { - if (cx->state == NAS_CX_RELEASING) { - msgrep->status=nasmt_ASCTL_leave_sleep_mode(cx); - } else { - cx->cellid=msgreq->cellid; - msgrep->status=nasmt_ASCTL_DC_send_cx_establish_request(cx); - } - } else - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - -#endif -} -//--------------------------------------------------------------------------- -int nasmt_ioCTL_cx_establishment_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_cx_establishment_request msgreq; - struct nas_msg_cx_establishment_reply msgrep; - printk("nasmt_ioCTL_cx_establishment: connection establishment requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_cx_establishment: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_cx_establishment_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_cx_establishment: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Connection Release -//--------------------------------------------------------------------------- -void nasmt_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep, struct nas_msg_cx_release_request *msgreq) -{ - //--------------------------------------------------------------------------- -#ifdef NODE_RG - msgrep->status=-NAS_ERROR_NOTMT; -#else - struct cx_entity *cx; - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { -#ifdef ENABLE_SLEEP_MODE - msgrep->status=nasmt_ASCTL_enter_sleep_mode(cx); -#endif -#ifndef ENABLE_SLEEP_MODE - msgrep->status=nasmt_ASCTL_DC_send_cx_release_request(cx); -#endif - } else - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - -#endif -} - -//--------------------------------------------------------------------------- -// Request the release of a connection -int nasmt_ioCTL_cx_release_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_cx_release_request msgreq; - struct nas_msg_cx_release_reply msgrep; - - printk("nasmt_ioCTL_cx_release: connection release requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_cx_release: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_cx_release_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_cx_release: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasmt_ioCTL_cx_release: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer List -//--------------------------------------------------------------------------- -void nasmt_set_msg_rb_list_reply(uint8_t *msgrep, struct nas_msg_rb_list_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { - uint8_t rbi; - struct rb_entity *rb; - struct nas_msg_rb_list_reply *list; - - if (cx->num_rb > NAS_LIST_RB_MAX) - msgrep[0] = NAS_LIST_RB_MAX; - else - msgrep[0] = cx->num_rb; - - list=(struct nas_msg_rb_list_reply *)(msgrep+1); - - for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbinext, ++rbi) { - list[rbi].state=rb->state; - list[rbi].rab_id=rb->rab_id; - list[rbi].sapi=rb->sapi; - list[rbi].qos=rb->qos; - } - } else - msgrep[0]=0; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_rb_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1]; - struct nas_msg_rb_list_request msgreq; - printk("nasmt_ioCTL_rb_list: Radio Bearer list requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_rb_list: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_rb_list_reply(msgrep, &msgreq); - - if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) { - printk("nasmt_ioCTL_rb_list: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasmt_ioCTL_rb_list: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer Establishment -//--------------------------------------------------------------------------- -void nasmt_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep, struct nas_msg_rb_establishment_request *msgreq) -{ - //--------------------------------------------------------------------------- - msgrep->status=-NAS_ERROR_NOTRG; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_rb_establishment_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_rb_establishment_request msgreq; - struct nas_msg_rb_establishment_reply msgrep; - printk("nasmt_ioCTL_rb_establishment: Radio bearer establishment requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_rb_establishment: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_rb_establishment_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_rb_establishment: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer Release -//--------------------------------------------------------------------------- -void nasmt_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep, struct nas_msg_rb_release_request *msgreq) -{ - //--------------------------------------------------------------------------- - msgrep->status=-NAS_ERROR_NOTRG; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_rb_release_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_rb_release_request msgreq; - struct nas_msg_rb_release_reply msgrep; - printk("nasmt_ioCTL_rb_release: Radio bearer release requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_rb_release: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_rb_release_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_rb_release: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Classifier List -//--------------------------------------------------------------------------- -void nasmt_set_msg_class_list_reply(uint8_t *msgrep, struct nas_msg_class_list_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - struct classifier_entity *gc; - struct nas_msg_class_list_reply *list; - uint8_t cli; - list=(struct nas_msg_class_list_reply *)(msgrep+1); - - switch(msgreq->dir) { - case NAS_DIRECTION_SEND: - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx==NULL) { - msgrep[0]=0; - return; - } - - gc=cx->sclassifier[msgreq->dscp]; - break; - - case NAS_DIRECTION_RECEIVE: - cx=NULL; - gc=gpriv->rclassifier[msgreq->dscp]; - break; - - default: - cx=NULL; - msgrep[0]=0; - return; - } - - for (cli=0; (gc!=NULL)&&(clinext, ++cli) { - list[cli].classref=gc->classref; - list[cli].lcr=msgreq->lcr; - list[cli].dir=msgreq->dir; - list[cli].dscp=msgreq->dscp; - list[cli].rab_id=gc->rab_id; - list[cli].version=gc->version; - - switch(gc->version) { - case 4: - list[cli].saddr.ipv4 = gc->saddr.ipv4; - list[cli].daddr.ipv4 = gc->daddr.ipv4; - break; - - case 6: - list[cli].saddr.ipv6 = gc->saddr.ipv6; - list[cli].daddr.ipv6 = gc->daddr.ipv6; - break; - } - - list[cli].protocol=gc->protocol; - list[cli].sport=ntohs(gc->sport); - list[cli].dport=ntohs(gc->dport); - list[cli].splen=gc->splen; - list[cli].dplen=gc->dplen; - list[cli].fct=nasmt_TOOL_invfct(gc); - } - - msgrep[0]=cli; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_class_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1]; - struct nas_msg_class_list_request msgreq; - printk("nasmt_ioCTL_class_list: classifier list requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_class_list: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_class_list_reply(msgrep, &msgreq); - - if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) { - printk("nasmt_ioCTL_class_list: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Request the addition of a classifier rule -//--------------------------------------------------------------------------- -void nasmt_set_msg_class_add_reply(struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - if (msgreq->dscp>NAS_DSCP_DEFAULT) { - printk("nasmt_set_msg_class_add_reply: Incoherent parameter value\n"); - msgrep->status=-NAS_ERROR_NOTCORRECTDSCP; - return; - } - - if (msgreq->dir==NAS_DIRECTION_SEND) { - struct cx_entity *cx; - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { - printk("nasmt_set_msg_class_add_reply: DSCP %d, Classref %d\n",msgreq->dscp, msgreq->classref ); - gc=nasmt_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref); - printk("nasmt_set_msg_class_add_reply: %p %p\n" , msgreq, gc); - - if (gc==NULL) { - msgrep->status=-NAS_ERROR_NOMEMORY; - return; - } - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - return; - } - - gc->rab_id=msgreq->rab_id; - gc->rb=nasmt_COMMON_search_rb(cx, gc->rab_id); - } else { - if (msgreq->dir==NAS_DIRECTION_RECEIVE) { - gc=nasmt_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref); - - if (gc==NULL) { - msgrep->status=-NAS_ERROR_NOMEMORY; - return; - } - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTDIR; - return; - } - } - - nasmt_TOOL_fct(gc, msgreq->fct); - gc->version=msgreq->version; - - switch(gc->version) { - case 4: - gc->saddr.ipv4=msgreq->saddr.ipv4; - gc->daddr.ipv4=msgreq->daddr.ipv4; - gc->splen=msgreq->splen; - gc->dplen=msgreq->dplen; - break; - - case 6: - gc->saddr.ipv6=msgreq->saddr.ipv6; - gc->daddr.ipv6=msgreq->daddr.ipv6; - gc->splen=msgreq->splen; - gc->dplen=msgreq->dplen; - break; - - case 0: - gc->saddr.ipv6.s6_addr32[0]=0; - gc->daddr.ipv6.s6_addr32[1]=0; - gc->saddr.ipv6.s6_addr32[2]=0; - gc->daddr.ipv6.s6_addr32[3]=0; - gc->splen=0; - gc->dplen=0; - break; - - default: - msgrep->status=-NAS_ERROR_NOTCORRECTVERSION; - kfree(gc); - return; - } - - gc->protocol=msgreq->protocol; - gc->sport=htons(msgreq->sport); - gc->dport=htons(msgreq->dport); - msgrep->status=0; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_class_add_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_class_add_request msgreq; - struct nas_msg_class_add_reply msgrep; - printk("nasmt_ioCTL_class_add: Add classifier components requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_class_add: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_class_add_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_class_add: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Request the deletion of a classifier rule -//--------------------------------------------------------------------------- -void nasmt_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep, struct nas_msg_class_del_request *msgreq) -{ - //--------------------------------------------------------------------------- - if (msgreq->dscp>NAS_DSCP_DEFAULT) { - printk("nasmt_set_msg_class_del_reply: Incoherent parameter value\n"); - msgrep->status=-NAS_ERROR_NOTCORRECTDSCP; - return; - } - - if (msgreq->dir==NAS_DIRECTION_SEND) { - struct cx_entity *cx; - cx=nasmt_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) - nasmt_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref); - else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - return; - } - } else { - if (msgreq->dir==NAS_DIRECTION_RECEIVE) - nasmt_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref); - else { - msgrep->status=-NAS_ERROR_NOTCORRECTDIR; - return; - } - } - - msgrep->status=0; -} - -//--------------------------------------------------------------------------- -int nasmt_ioCTL_class_del_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_class_del_request msgreq; - struct nas_msg_class_del_reply msgrep; - printk("nasmt_ioCTL_class_del: Del classifier components requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_class_del: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_class_del_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_class_del: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Measurement -// Messages for Measurement transfer - -//--------------------------------------------------------------------------- -void nasmt_set_msg_measure_reply(struct nas_msg_measure_reply *msgrep, struct nas_msg_measure_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - int lcr=0; // Temp lcr->mt =0 - int i; - - cx = nasmt_COMMON_search_cx(lcr); - - if (cx!=NULL) { - msgrep->num_cells = cx->num_measures; - - for (i=0; inum_measures; i++) { - msgrep-> measures[i].cell_id = cx->meas_cell_id[i]; - msgrep-> measures[i].level = cx->meas_level[i]; - msgrep-> measures[i].provider_id = cx->provider_id[i]; - } - - msgrep->signal_lost_flag = 0; - } else { - // msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - // return; - } -} -//--------------------------------------------------------------------------- -int nasmt_ioCTL_measure_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_measure_request msgreq; - struct nas_msg_measure_reply msgrep; - printk("nasmt_ioCTL_measure: Measurement requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasmt_ioCTL_measure: copy_from_user failure\n"); - return -EFAULT; - } - - nasmt_set_msg_measure_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_measure: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// IMEI -// Messages for IMEI transfer -//--------------------------------------------------------------------------- -void nasmt_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - int lcr=0; // Temp lcr->mt =0 - int i; - - cx=nasmt_COMMON_search_cx(lcr); - - if (cx!=NULL) { - msgrep->l2id[0] = cx->iid6[0]; - msgrep->l2id[1] = cx->iid6[1]; - } else { - // msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - // return; - } -} -//--------------------------------------------------------------------------- -int nasmt_ioCTL_imei_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_l2id_reply msgrep; - printk("nasmt_ioCTL_imei: IMEI requested\n"); - nasmt_set_msg_imei_reply(&msgrep); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasmt_ioCTL_imei: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// IOCTL command -//--------------------------------------------------------------------------- -int nasmt_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - //--------------------------------------------------------------------------- - struct nas_ioctl *gifr; - int r; - printk("nasmt_CTL_ioctl: begin\n"); - - //spin_lock(&gpriv->lock); - switch(cmd) { - case NASMT_IOCTL_RAL: - gifr=(struct nas_ioctl *)ifr; - - switch(gifr->type) { - case NAS_MSG_STATISTIC_REQUEST: - r=nasmt_ioCTL_statistic_request(gifr); - break; - - case NAS_MSG_CX_ESTABLISHMENT_REQUEST: - r=nasmt_ioCTL_cx_establishment_request(gifr); - break; - - case NAS_MSG_CX_RELEASE_REQUEST: - r=nasmt_ioCTL_cx_release_request(gifr); - break; - - case NAS_MSG_CX_LIST_REQUEST: - r=nasmt_ioCTL_cx_list_request(gifr); - break; - - case NAS_MSG_RB_ESTABLISHMENT_REQUEST: - r=nasmt_ioCTL_rb_establishment_request(gifr); - break; - - case NAS_MSG_RB_RELEASE_REQUEST: - r= nasmt_ioCTL_rb_release_request(gifr); - break; - - case NAS_MSG_RB_LIST_REQUEST: - r=nasmt_ioCTL_rb_list_request(gifr); - break; - - case NAS_MSG_CLASS_ADD_REQUEST: - r=nasmt_ioCTL_class_add_request(gifr); - break; - - case NAS_MSG_CLASS_LIST_REQUEST: - r=nasmt_ioCTL_class_list_request(gifr); - break; - - case NAS_MSG_CLASS_DEL_REQUEST: - r=nasmt_ioCTL_class_del_request(gifr); - break; - - case NAS_MSG_MEAS_REQUEST: - r=nasmt_ioCTL_measure_request(gifr); - break; - - case NAS_MSG_IMEI_REQUEST: - r=nasmt_ioCTL_imei_request(gifr); - break; - - default: - printk("nasmt_CTL_ioctl: unkwon request type, type=%x\n", gifr->type); - r=-EFAULT; - } - - break; - - default: - printk("nasmt_CTL_ioctl: Unknown ioctl command, cmd=%x\n", cmd); - r=-EFAULT; - } - - //spin_unlock(&gpriv->lock); - printk("nasmt_CTL_ioctl: end\n"); - return r; -} - -//--------------------------------------------------------------------------- -void nasmt_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - printk("nasmt_CTL_send - void \n"); -} - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.h b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.h deleted file mode 100644 index 40118d8368..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_iocontrol.h +++ /dev/null @@ -1,211 +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 nasmt_iocontrol.h -* \brief I/O control constnats and structures for upper layers of driver for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef NASMTD_CTL_H -#define NASMTD_CTL_H - -#include -#include -#include -#include - -#define NAS_MSG_MAXLEN 1100 - -// type of CTL message -#define NAS_MSG_STATISTIC_REQUEST 1 -#define NAS_MSG_STATISTIC_REPLY 2 -#define NAS_MSG_ECHO_REQUEST 3 -#define NAS_MSG_ECHO_REPLY 4 -#define NAS_MSG_CX_ESTABLISHMENT_REQUEST 5 -#define NAS_MSG_CX_ESTABLISHMENT_REPLY 6 -#define NAS_MSG_CX_RELEASE_REQUEST 7 -#define NAS_MSG_CX_RELEASE_REPLY 8 -#define NAS_MSG_CX_LIST_REQUEST 9 -#define NAS_MSG_CX_LIST_REPLY 10 -#define NAS_MSG_RB_ESTABLISHMENT_REQUEST 11 -#define NAS_MSG_RB_ESTABLISHMENT_REPLY 12 -#define NAS_MSG_RB_RELEASE_REQUEST 13 -#define NAS_MSG_RB_RELEASE_REPLY 14 -#define NAS_MSG_RB_LIST_REQUEST 15 -#define NAS_MSG_RB_LIST_REPLY 16 -#define NAS_MSG_CLASS_ADD_REQUEST 17 -#define NAS_MSG_CLASS_ADD_REPLY 18 -#define NAS_MSG_CLASS_DEL_REQUEST 19 -#define NAS_MSG_CLASS_DEL_REPLY 20 -#define NAS_MSG_CLASS_LIST_REQUEST 21 -#define NAS_MSG_CLASS_LIST_REPLY 22 -#define NAS_MSG_MEAS_REQUEST 23 -#define NAS_MSG_MEAS_REPLY 24 -#define NAS_MSG_IMEI_REQUEST 25 -#define NAS_MSG_IMEI_REPLY 26 - -// Max number of entry of a message list -#define NAS_LIST_CX_MAX 32 -#define NAS_LIST_RB_MAX 32 -#define NAS_LIST_CLASS_MAX 32 - -typedef uint16_t nasMsgType_t; - -struct nas_ioctl { - char name[IFNAMSIZ]; - nasMsgType_t type; - char *msg; -}; - -struct nas_msg_statistic_reply { - uint32_t rx_packets; - uint32_t tx_packets; - uint32_t rx_bytes; - uint32_t tx_bytes; - uint32_t rx_errors; - uint32_t tx_errors; - uint32_t rx_dropped; - uint32_t tx_dropped; -}; - -struct nas_msg_cx_list_reply { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t state; - nasCellID_t cellid; // cell identification - uint32_t iid6[2]; // IPv6 interface identification - uint8_t iid4; // IPv4 interface identification - uint16_t num_rb; - uint16_t nsclassifier; -}; -struct nas_msg_cx_establishment_reply { - int status; -}; -struct nas_msg_cx_establishment_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasCellID_t cellid; // Cell identification -}; -struct nas_msg_cx_release_reply { - int status; -}; -struct nas_msg_cx_release_request { - nasLocalConnectionRef_t lcr; // Local Connection reference -}; - -struct nas_msg_rb_list_reply { - nasRadioBearerId_t rab_id; - nasSapId_t sapi; - nasQoSTrafficClass_t qos; - uint8_t state; -}; -struct nas_msg_rb_list_request { - nasLocalConnectionRef_t lcr; // Local Connection reference -}; -struct nas_msg_rb_establishment_reply { - int status; -}; -struct nas_msg_rb_establishment_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; - nasQoSTrafficClass_t qos; -}; - -struct nas_msg_rb_release_reply { - int status; -}; -struct nas_msg_rb_release_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; -}; - -struct nas_msg_class_add_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; - uint8_t dir; // direction (send or receive) - uint8_t dscp; // codepoint - uint8_t fct; - uint16_t classref; - uint8_t version; - union { - struct in6_addr ipv6; - uint32_t ipv4; - } saddr; // IP source address - uint8_t splen; // prefix length - union { - struct in6_addr ipv6; - uint32_t ipv4; - } daddr; // IP destination address - uint8_t dplen; // prefix length - uint8_t protocol; // high layer protocol type - uint16_t sport; // source port - uint16_t dport; // destination port -}; -struct nas_msg_class_add_reply { - int status; -}; -struct nas_msg_class_del_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t dir; // direction (send or receive) - uint8_t dscp; // codepoint - uint16_t classref; -}; -struct nas_msg_class_del_reply { - int status; -}; -#define nas_msg_class_list_reply nas_msg_class_add_request -struct nas_msg_class_list_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t dir; - uint8_t dscp; -}; - - -// Messages for Measurement transfer - MW 01/04/2005 -typedef uint32_t nioctlProviderId_t; -typedef uint16_t nioctlSignalLoss_t; -typedef struct nioctlMeasures { - nasCellID_t cell_id; - nasSigLevel_t level; - nioctlProviderId_t provider_id; -} nioctlMeasures_t; - -struct nas_msg_measure_request { - nasNumRGsMeas_t num_cells; - nasCellID_t cellid[MAX_MEASURE_NB]; // Cell identification - uint16_t num_providers; - nioctlProviderId_t provider_id[MAX_MEASURE_NB]; // Provider identification -}; -struct nas_msg_measure_reply { - nasNumRGsMeas_t num_cells; - nioctlMeasures_t measures[MAX_MEASURE_NB]; - nioctlSignalLoss_t signal_lost_flag; -}; - -// Messages for L2Id transfer - MW -typedef uint32_t nioctlL2Id_t[2]; - -struct nas_msg_l2id_reply { - nioctlL2Id_t l2id; -}; - - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_netlink.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_netlink.c deleted file mode 100644 index 2f92b94717..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_netlink.c +++ /dev/null @@ -1,233 +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 nasmt_netlink.c -* \brief Netlink socket functions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -//#include -#include -#include -#include -#include -#include -#include - -#include - -#include "nasmt_variables.h" -#include "nasmt_proto.h" - -static struct sock *nas_nl_sk = NULL; -static struct sock *nas_rrcnl_sk = NULL; - -//static int exit_netlink_thread=0; -static DEFINE_MUTEX(nasmt_mutex); - -// This can also be implemented using thread to get the data from PDCP without blocking. -//--------------------------------------------------------------------------- -// Function for transfer with PDCP (from NASLITE) -static void nasmt_nl_data_ready (struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct nlmsghdr *nlh = NULL; - - // Start debug information -#ifdef NETLINK_DEBUG - printk("nasmt_nl_data_ready - begin \n"); -#endif - - if (!skb) { - printk("nasmt_nl_data_ready - input parameter skb is NULL \n"); - return; - } - - // End debug information - -#ifdef NETLINK_DEBUG - printk("nasmt_nl_data_ready - Received socket from PDCP\n"); -#endif //NETLINK_DEBUG - nlh = (struct nlmsghdr *)skb->data; - nasmt_COMMON_QOS_receive(nlh); -} - -//--------------------------------------------------------------------------- -// Function for transfer with RRC -static void nasmt_rrcnl_data_ready (struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct nlmsghdr *nlh = NULL; - char target_sap; - uint8_t cxi = 0; - - // Start debug information -#ifdef NAS_DEBUG_RRCNL - printk("nasmt_rrcnl_data_ready - begin \n"); -#endif - - if (!skb) { - printk("nasmt_rrcnl_data_ready - input parameter skb is NULL \n"); - return; - } - - // End debug information - - nlh = (struct nlmsghdr *)skb->data; - //pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh); - //nasmt_TOOL_print_buffer((char *)NLMSG_DATA(nlh), 48); - - target_sap = ((char*)NLMSG_DATA(nlh))[0]; -#ifdef NAS_DEBUG_RRCNL - printk("nasmt_rrcnl_data_ready - Received on socket from RRC, SAP %d\n", target_sap); -#endif //NAS_DEBUG_RRCNL - - switch (target_sap) { - case RRC_NAS_GC_OUT: - //printk("nasmt_rrcnl_data_ready - Calling nasmt_ASCTL_GC_receive\n"); - nasmt_ASCTL_GC_receive(&((char*)NLMSG_DATA(nlh))[1]); - break; - - case RRC_NAS_DC0_OUT: - //printk("nasmt_rrcnl_data_ready - Calling nasmt_ASCTL_DC_receive\n"); - nasmt_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]); - break; - - default: - printk("nasmt_rrcnl_data_ready - Invalid SAP value received\n"); - } - -} - -//--------------------------------------------------------------------------- -int nasmt_netlink_init(void) -{ - //--------------------------------------------------------------------------- - printk("nasmt_netlink_init - begin \n"); - - nas_nl_sk = netlink_kernel_create(&init_net,OAI_IP_DRIVER_NETLINK_ID, 0, nasmt_nl_data_ready, - &nasmt_mutex, // NULL - THIS_MODULE); - - if (!nas_nl_sk) { - printk("nasmt_netlink_init - netlink_kernel_create failed for PDCP socket\n"); - return(-1); - } - - nas_rrcnl_sk = netlink_kernel_create(&init_net,NAS_RRCNL_ID, 0, nasmt_rrcnl_data_ready, - &nasmt_mutex, // NULL - THIS_MODULE); - - if (!nas_rrcnl_sk) { - printk("nasmt_rrcnl_init - netlink_kernel_create failed for RRC socket\n"); - return(-1); - } - - return(0); -} - -//--------------------------------------------------------------------------- -void nasmt_netlink_release(void) -{ - //--------------------------------------------------------------------------- - printk("nasmt_netlink_release - begin \n"); - - //exit_netlink_thread=1; - printk("nasmt_netlink_release - Releasing netlink sockets\n"); - - if(nas_nl_sk) { - netlink_kernel_release(nas_nl_sk); - } - - if(nas_rrcnl_sk) { - netlink_kernel_release(nas_rrcnl_sk); - } - -} - -//--------------------------------------------------------------------------- -int nasmt_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination) -{ - //--------------------------------------------------------------------------- - struct sk_buff *nl_skb; - struct nlmsghdr *nlh; - int status; - // Start debug information -#ifdef NETLINK_DEBUG - printk("nasmt_netlink_send - begin \n"); -#endif - - if (!data_buffer) { - printk("nasmt_netlink_send - ERROR - input parameter data is NULL \n"); - return(0); - } - - if (!nas_nl_sk || !nas_rrcnl_sk) { - printk("nasmt_netlink_send - ERROR - socket is NULL\n"); - return(0); - } - - // End debug information - - nl_skb = alloc_skb(NLMSG_SPACE(data_length),GFP_ATOMIC); - - if (!nl_skb) { - printk("nasmt_netlink_send - ERROR - could not allocate skbuffer\n"); - return(0); - } - - nlh = (struct nlmsghdr *)nl_skb->data; - - // printk("nasmt_netlink_send Sending %d bytes (%d)\n",data_length,NLMSG_SPACE(data_length)); - skb_put(nl_skb, NLMSG_SPACE(data_length)); - memcpy(NLMSG_DATA(nlh), data_buffer, data_length); - nlh->nlmsg_len = NLMSG_SPACE(data_length); - - nlh->nlmsg_pid = 0; /* from kernel */ - NETLINK_CB(nl_skb).pid = 0; - - // destination 0 = PDCP, 1 = RRC - if (!destination) { -#ifdef NETLINK_DEBUG - printk("nasmt_netlink_send - nl_skb %p, nl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_nl_sk, nlh, nlh->nlmsg_len); -#endif //DEBUG_NETLINK - status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT); - } else { -#ifdef NAS_DEBUG_RRCNL - printk("nasmt_rrcnl_send - nl_skb %p, nas_rrcnl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_rrcnl_sk, nlh, nlh->nlmsg_len); -#endif //NAS_DEBUG_RRCNL - status = netlink_unicast(nas_rrcnl_sk, nl_skb, NL_DEST_RRC_PID, MSG_DONTWAIT); - } - - if (status < 0) { - printk("nasmt_netlink_send - SEND status is %d\n",status); - return(0); - } else { -#ifdef NETLINK_DEBUG - printk("nasmt_netlink_send - SEND status is %d, data_length %d\n",status, data_length); -#endif - return data_length; - } -} - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_proto.h b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_proto.h deleted file mode 100644 index 3a6ffe4848..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_proto.h +++ /dev/null @@ -1,122 +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 nasmt_proto.h -* \brief Function prototypes for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASMTD_PROTO_H -#define _NASMTD_PROTO_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include - -//#include "rrc_nas_primitives.h" -//#include "protocol_vars_extern.h" -//#include "as_sap.h" -//#include "rrc_qos.h" -//#include "rrc_sap.h" - -// nasmt_netlink.c -void nasmt_netlink_release(void); -int nasmt_netlink_init(void); -int nasmt_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination); - -// nasmt_common.c -//void nasmt_COMMON_receive(uint16_t hlen, uint16_t dlength, int sap); -void nasmt_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - -void nasmt_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -void nasmt_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -#ifndef PDCP_USE_NETLINK -void nasmt_COMMON_QOS_receive(struct cx_entity *cx); -#else -void nasmt_COMMON_QOS_receive(struct nlmsghdr *nlh); -#endif -struct rb_entity *nasmt_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rabi, nasQoSTrafficClass_t qos); -struct rb_entity *nasmt_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rabi); -struct cx_entity *nasmt_COMMON_search_cx(nasLocalConnectionRef_t lcr); -void nasmt_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp); -void nasmt_COMMON_flush_rb(struct cx_entity *cx); - - -//nasmt_ascontrol.c -void nasmt_ASCTL_init(void); -void nasmt_ASCTL_timer(unsigned long data); -int nasmt_ASCTL_DC_receive(struct cx_entity *cx, char *buffer); -int nasmt_ASCTL_GC_receive(char *buffer); -int nasmt_ASCTL_DC_send_cx_establish_request(struct cx_entity *cx); -int nasmt_ASCTL_DC_send_cx_release_request(struct cx_entity *cx); -void nasmt_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -void nasmt_ASCTL_DC_send_peer_sig_data_request(struct cx_entity *cx, uint8_t sig_category); -int nasmt_ASCTL_leave_sleep_mode(struct cx_entity *cx); -int nasmt_ASCTL_enter_sleep_mode(struct cx_entity *cx); - -// nasmt_iocontrol.c -void nasmt_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -int nasmt_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -// nasmt_classifier.c -void nasmt_CLASS_send(struct sk_buff *skb); -struct classifier_entity *nasmt_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref); -struct classifier_entity *nasmt_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref); -void nasmt_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref); -void nasmt_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref); -void nasmt_CLASS_flush_sclassifier(struct cx_entity *cx); -void nasmt_CLASS_flush_rclassifier(void); - -// nasmt_tool.c -uint8_t nasmt_TOOL_invfct(struct classifier_entity *gc); -void nasmt_TOOL_fct(struct classifier_entity *gc, uint8_t fct); -void nasmt_TOOL_imei2iid(uint8_t *imei, uint8_t *iid); - -void nasmt_TOOL_eth_imei2iid(unsigned char *imei, unsigned char *addr ,unsigned char *iid, unsigned char len); -uint8_t nasmt_TOOL_get_dscp6(struct ipv6hdr *iph); -uint8_t nasmt_TOOL_get_dscp4(struct iphdr *iph); -uint8_t *nasmt_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol); -uint8_t *nasmt_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol); - -void nasmt_TOOL_pk_icmp6(struct icmp6hdr *icmph); - -void nasmt_TOOL_print_state(uint8_t state); -void nasmt_TOOL_print_buffer(unsigned char * buffer,int length); -void nasmt_TOOL_print_rb_entity(struct rb_entity *rb); -void nasmt_TOOL_print_classifier(struct classifier_entity *gc); - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_sap.h b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_sap.h deleted file mode 100644 index c0934f4622..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_sap.h +++ /dev/null @@ -1,73 +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 nasmt_sap.h -* \brief SAP constants for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASMTD_SAP_H -#define _NASMTD_SAP_H - -// RT-FIFO identifiers ** must be identical to Access Stratum as_sap.h and rrc_sap.h -#define RRC_DEVICE_GC RRC_SAPI_UE_GCSAP -#define RRC_DEVICE_NT RRC_SAPI_UE_NTSAP -#define RRC_DEVICE_DC_INPUT0 RRC_SAPI_UE_DCSAP_IN -#define RRC_DEVICE_DC_OUTPUT0 RRC_SAPI_UE_DCSAP_OUT - -//#define QOS_DEVICE_CONVERSATIONAL_INPUT QOS_SAPI_CONVERSATIONAL_INPUT_MT -//#define QOS_DEVICE_CONVERSATIONAL_OUTPUT QOS_SAPI_CONVERSATIONAL_OUTPUT_MT - -#define PDCP2PDCP_USE_RT_FIFO 21 -#define NAS2PDCP_FIFO 22 - -//FIFO indexes in control blocks -#define NAS_DC_INPUT_SAPI 0 -#define NAS_DC_OUTPUT_SAPI 1 -#define NAS_SAPI_CX_MAX 2 - -#define NAS_GC_SAPI 0 -#define NAS_NT_SAPI 1 -#define NAS_DRB_INPUT_SAPI 2 //NAS_CO_INPUT_SAPI -#define NAS_DRB_OUTPUT_SAPI 3 //NAS_CO_OUTPUT_SAPI -#define NAS_SAPI_MAX 4 - -//#define NAS_QOS_CONVERSATIONAL UMTS_TRAFFIC_CONVERSATIONAL -// - -/* Defined in RRC -#define RRC_NAS_GC_IN 0 -#define RRC_NAS_GC_OUT 1 -#define RRC_NAS_NT_IN 2 -#define RRC_NAS_NT_OUT 3 -#define RRC_NAS_DC0_IN 4 -#define RRC_NAS_DC0_OUT 5 -#define RRC_NAS_DC1_IN 6 -#define RRC_NAS_DC1_OUT 7 -#define RRC_NAS_DC2_IN 8 -#define RRC_NAS_DC2_OUT 9 -*/ -#endif - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_tool.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_tool.c deleted file mode 100644 index 4c5d3fcf6e..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_tool.c +++ /dev/null @@ -1,494 +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 - */ - -/*************************************************************************** - nasmt_tool.c - description - *************************************************************************** - - ***************************************************************************/ -/*! \file nasmt_tool.c -* \brief Tool functions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ - -#include "nasmt_variables.h" -#include "nasmt_proto.h" - -//--------------------------------------------------------------------------- -// -void nasmt_TOOL_fct(struct classifier_entity *gc, uint8_t fct) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_fct - begin \n"); -#endif - - if (gc==NULL) { - printk("nasmt_TOOL_fct - input parameter gc is NULL \n"); - return; - } - - // End debug information - switch(fct) { - case NAS_FCT_QOS_SEND: - gc->fct=nasmt_COMMON_QOS_send; - break; - - case NAS_FCT_CTL_SEND: - gc->fct=nasmt_CTL_send; - break; - - case NAS_FCT_DC_SEND: - gc->fct=nasmt_ASCTL_DC_send_sig_data_request; - break; - - case NAS_FCT_DEL_SEND: - gc->fct=nasmt_COMMON_del_send; - break; - - default: - gc->fct=nasmt_COMMON_del_send; - } -} - -//--------------------------------------------------------------------------- -uint8_t nasmt_TOOL_invfct(struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_invfct - begin \n"); -#endif - - if (gc==NULL) { - printk("nasmt_TOOL_invfct - input parameter gc is NULL \n"); - return 0; - } - - // End debug information - if (gc->fct==nasmt_COMMON_QOS_send) - return NAS_FCT_QOS_SEND; - - if (gc->fct==nasmt_CTL_send) - return NAS_FCT_CTL_SEND; - - if (gc->fct==nasmt_COMMON_del_send) - return NAS_FCT_DEL_SEND; - - if (gc->fct==nasmt_ASCTL_DC_send_sig_data_request) - return NAS_FCT_DC_SEND; - - return 0; -} - -//--------------------------------------------------------------------------- -uint8_t nasmt_TOOL_get_dscp6(struct ipv6hdr *iph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_get_dscp6 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasmt_TOOL_get_dscp6 - input parameter ipv6hdr is NULL \n"); - return 0; - } - - // End debug information - // return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>22; //Yan - return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>20; -} - -//--------------------------------------------------------------------------- -uint8_t nasmt_TOOL_get_dscp4(struct iphdr *iph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_get_dscp4 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasmt_TOOL_get_dscp4 - input parameter ipv4hdr is NULL \n"); - return 0; - } - - // End debug information - return ((iph->tos)>>5)<<3; -} - - -//--------------------------------------------------------------------------- -uint8_t *nasmt_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol) -{ - //--------------------------------------------------------------------------- - uint16_t size; - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_get_protocol6 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasmt_TOOL_get_protocol6 - input parameter ipv6hdr is NULL \n"); - return NULL; - } - - if (protocol==NULL) { - printk("nasmt_TOOL_get_protocol6 - input parameter protocol is NULL \n"); - return NULL; - } - - // End debug information - *protocol=iph->nexthdr; - size=NAS_IPV6_SIZE; - - while (1) { - switch(*protocol) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_ICMPV6: - return (uint8_t *)((uint8_t *)iph+size); - - case IPPROTO_HOPOPTS: - case IPPROTO_ROUTING: - case IPPROTO_DSTOPTS: - *protocol=((uint8_t *)iph+size)[0]; - size+=((uint8_t *)iph+size)[1]*8+8; - break; - - case IPPROTO_FRAGMENT: - *protocol=((uint8_t *)iph+size)[0]; - size+=((uint8_t *)iph+size)[1]+8; - break; - - case IPPROTO_NONE: - case IPPROTO_AH: - case IPPROTO_ESP: - default: - return NULL; - } - } -} - -//--------------------------------------------------------------------------- -uint8_t *nasmt_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_get_protocol4 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasmt_TOOL_get_protocol4 - input parameter iph is NULL \n"); - return NULL; - } - - if (protocol==NULL) { - printk("nasmt_TOOL_get_protocol4 - input parameter protocol is NULL \n"); - return NULL; - } - - // End debug information - *protocol=iph->protocol; - - switch(*protocol) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_ICMP: - return (uint8_t *)((uint8_t *)iph+iph->tot_len); - - default: - return NULL; - } -} - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void nasmt_TOOL_imei2iid(uint8_t *imei, uint8_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_imei2iid - begin \n"); -#endif - - if (imei==NULL) { - printk("nasmt_TOOL_imei2iid - input parameter imei is NULL \n"); - return; - } - - if (iid==NULL) { - printk("nasmt_TOOL_imei2iid - input parameter iid is NULL \n"); - return; - } - - // End debug information - memset(iid, 0, NAS_ADDR_LEN); - iid[0] = 0x03; - iid[1] = 16*imei[0]+imei[1]; - iid[2] = 16*imei[2]+imei[3]; - iid[3] = 16*imei[4]+imei[5]; - iid[4] = 16*imei[6]+imei[7]; - iid[5] = 16*imei[8]+imei[9]; - iid[6] = 16*imei[10]+imei[11]; - iid[7] = 16*imei[12]+imei[13]; -} - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void nasmt_TOOL_eth_imei2iid(unsigned char *imei, unsigned char *addr ,unsigned char *iid, unsigned char len) -{ - //--------------------------------------------------------------------------- - unsigned int index; - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_eth_imei2iid - begin \n"); -#endif - - if (!imei || !addr || !iid) { - printk("OAI_NW_DRV_TOOL_eNB_IMEI2IID - input parameter imei, addr or iid is NULL \n"); - return; - } - - // End debug information - // set addr (should be device HW address) - memset(addr, 0, len); - addr[0] = 0x00; // to be compatible between link local and global - - // len -1 because of insertion of 0 above - for (index = 0; index < (len-1); index++) { - addr[index+1] = 16*imei[index*2]+imei[index*2+1]; - } - - // set iid6 - memset(iid, 0, NAS_ADDR_LEN); - iid[0] = 0x02; - iid[1] = 16*imei[0]+imei[1]; - iid[2] = 16*imei[2]+imei[3]; - iid[3] = 0xff; - iid[4] = 0xfe; - iid[5] = 16*imei[4]+imei[5]; - iid[6] = 16*imei[6]+imei[7]; - iid[7] = 16*imei[8]+imei[9]; - -} - -//--------------------------------------------------------------------------- -void nasmt_TOOL_pk_icmp6(struct icmp6hdr *icmph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef GRAAL_DEBUG_TOOL - printk("nasmt_TOOL_pk_icmp6 - begin \n"); -#endif - - if (!icmph) { - printk("nasmt_TOOL_pk_icmp6 - input parameter icmph is NULL \n"); - return; - } - - // End debug information - printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code); - - switch(icmph->icmp6_type) { - case ICMPV6_DEST_UNREACH: - printk("Destination unreachable\n"); - break; - - case ICMPV6_PKT_TOOBIG: - printk("Packet too big\n"); - break; - - case ICMPV6_TIME_EXCEED: - printk("Time exceeded\n"); - break; - - case ICMPV6_PARAMPROB: - printk("Parameter problem\n"); - break; - - case ICMPV6_ECHO_REQUEST: - printk("Echo request\n"); - break; - - case ICMPV6_ECHO_REPLY: - printk("Echo reply\n"); - break; - - case ICMPV6_MGM_QUERY: - printk("Multicast listener query\n"); - break; - - case ICMPV6_MGM_REPORT: - printk("Multicast listener report\n"); - break; - - case ICMPV6_MGM_REDUCTION: - printk("Multicast listener done\n"); - break; - - case NDISC_ROUTER_SOLICITATION: - printk("Router solicitation\n"); - break; - - case NDISC_ROUTER_ADVERTISEMENT: - printk("Router advertisment\n"); - break; - - case NDISC_NEIGHBOUR_SOLICITATION: - printk("Neighbour solicitation\n"); - break; - - case NDISC_NEIGHBOUR_ADVERTISEMENT: - printk("Neighbour advertisment\n"); - break; - - case NDISC_REDIRECT: - printk("redirect message\n"); - break; - } -} - -//--------------------------------------------------------------------------- -void nasmt_TOOL_print_state(uint8_t state) -{ - //--------------------------------------------------------------------------- - switch(state) { - case NAS_IDLE: - printk("NAS_IDLE\n"); - return; - - case NAS_CX_FACH: - printk("NAS_CX_FACH\n"); - return; - - case NAS_CX_DCH: - printk("NAS_CX_DCH\n"); - return; - - case NAS_CX_RECEIVED: - printk("NAS_CX_RECEIVED\n"); - return; - - case NAS_CX_CONNECTING: - printk("NAS_CX_CONNECTING\n"); - return; - - case NAS_CX_RELEASING: - printk("NAS_CX_RELEASING\n"); - return; - - case NAS_CX_CONNECTING_FAILURE: - printk("NAS_CX_CONNECTING_FAILURE\n"); - return; - - case NAS_CX_RELEASING_FAILURE: - printk("NAS_CX_RELEASING_FAILURE\n"); - return; - - case NAS_RB_ESTABLISHING: - printk("NAS_RB_ESTABLISHING\n"); - return; - - case NAS_RB_RELEASING: - printk("NAS_RB_RELEASING\n"); - return; - - case NAS_RB_DCH: - printk("NAS_RB_DCH\n"); - return; - - default: - printk("nasmt_TOOL_print_state - Unknown state\n"); - } -} - -//----------------------------------------------------------------------------- -// Print the content of a buffer in hexadecimal -void nasmt_TOOL_print_buffer(unsigned char * buffer,int length) -{ - //----------------------------------------------------------------------------- - int i; - - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_print_buffer - begin \n"); -#endif - - if (buffer==NULL) { - printk("nasmt_TOOL_print_buffer - input parameter buffer is NULL \n"); - return; - } - - // End debug information - printk("\nBuffer content: "); - - for (i=0; irab_id, rb->sapi, rb->qos, rb->dscp); - printk("state %d, retry %d, countimer %d\n",rb->state, rb->retry, rb->countimer); -}; - -//----------------------------------------------------------------------------- -void nasmt_TOOL_print_classifier(struct classifier_entity *gc) -{ - //----------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasmt_TOOL_print_classifier - begin \n"); -#endif - - if (gc==NULL) { - printk("nasmt_TOOL_print_classifier - input parameter gc is NULL \n"); - return; - } - - // End debug information - printk("\nClassifier content: classref %d, version %d, splen %d, dplen %d,\n", gc->classref, gc->version, gc->splen, gc->dplen); - printk("protocol %d, sport %d, dport %d, rab_id %d\n", gc->protocol, gc->sport, gc->dport, gc->rab_id); - nasmt_TOOL_print_rb_entity(gc->rb); -}; - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_variables.h b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_variables.h deleted file mode 100644 index c5754e948e..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_variables.h +++ /dev/null @@ -1,173 +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 nasmt_variables.h -* \brief Variable and structure definitions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASMTD_VAR_H -#define _NASMTD_VAR_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include - -#include "rrc_nas_primitives.h" -#include "rrc_qos_classes.h" -#include "rrc_nas_sap.h" - -#include "nasmt_constant.h" -#include "nasmt_sap.h" - -struct cx_entity; - -struct rb_entity { - uint32_t cnxid; - nasRadioBearerId_t rab_id; //ue_rbId - nasSapId_t sapi; - nasQoSTrafficClass_t qos; - nasQoSTrafficClass_t RadioQosClass; - nasIPdscp_t dscp; - uint8_t state; - uint8_t result; - uint8_t retry; - uint32_t countimer; - struct rb_entity *next; -}; - -struct classifier_entity { - uint32_t classref; // classifier identity - uint8_t version; // IP version 4 or 6 - union { - struct in6_addr ipv6; - uint32_t ipv4; - } saddr; // IP source address - uint8_t splen; // IP prefix size - union { - struct in6_addr ipv6; - uint32_t ipv4; - } daddr; // IP destination address - uint8_t dplen; // IP prefix size - uint8_t protocol; // layer 4 protocol type (tcp, udp, ...) - uint16_t sport; // source port - uint16_t dport; // destination port - struct rb_entity *rb; - nasRadioBearerId_t rab_id; // RAB identification - void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); - struct classifier_entity *next; -}; - - -struct cx_entity { - int sap[NAS_SAPI_CX_MAX]; - uint8_t state; // state of the connection - nasLocalConnectionRef_t lcr; // Local connection reference - nasCellID_t cellid; // cell identification - uint32_t countimer; // timeout's counter - uint8_t retry; // number of retransmissions - struct classifier_entity *sclassifier[NAS_DSCP_MAX]; // send classifiers table - uint16_t nsclassifier; - uint32_t iid6[2]; // IPv6 interface identification - uint8_t iid4; // IPv4 interface identification - struct rb_entity *rb; - uint16_t num_rb; - //measures - int req_prov_id[MAX_MEASURE_NB]; - int num_measures; - int meas_cell_id[MAX_MEASURE_NB]; - int meas_level[MAX_MEASURE_NB]; - int provider_id[MAX_MEASURE_NB]; - //MBMS - int joined_services[NASMT_MBMS_SVCES_MAX]; - -}; - -struct nas_priv { - int irq; - int rx_flags; - struct timer_list timer; - spinlock_t lock; - struct net_device_stats stats; - uint8_t retry_limit; - uint32_t timer_establishment; - uint32_t timer_release; - struct cx_entity cx[NAS_CX_MAX]; - struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier - uint16_t nrclassifier; - uint32_t next_sclassref; - int sap[NAS_SAPI_MAX]; - uint8_t xbuffer[NAS_MAX_LENGTH]; // transmission buffer - uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer -}; - -struct ipversion { -#if defined(__LITTLE_ENDIAN_BITFIELD) - uint8_t reserved:4, - version:4; -#else - uint8_t version:4, - reserved:4; -#endif -}; - -typedef struct pdcp_data_req_header_t { - unsigned int rb_id; - unsigned int data_size; - int inst; -} pdcp_data_req_header_t; - -typedef struct pdcp_data_ind_header_t { - unsigned int rb_id; - unsigned int data_size; - int inst; -} pdcp_data_ind_header_t; -// - -extern struct nas_priv *gpriv; -extern struct net_device *gdev; -//extern int bytes_wrote; -//extern int bytes_read; - -extern uint8_t NAS_NULL_IMEI[14]; -extern uint8_t NAS_RG_IMEI[14]; - -//global variables shared with RRC -extern int *pt_nas_ue_irq; -//extern uint8_t nas_IMEI[14]; -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/Makefile b/openair2/NAS/DRIVER/CELLULAR/NASRG/Makefile deleted file mode 100755 index 758fa0420b..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# NAS CELLULAR Driver makefile -# -include $(OPENAIR_DIR)/common/utils/Makefile.inc - -NAS_UPDIR := $(shell /bin/pwd) - -#################################################### -# D E B U G F L A G S -#################################################### - -#################################################### -# EXTRA COMPILER FLAGS -#################################################### -EXTRA_CFLAGS = -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,) - -ifdef ADDRCONF -EXTRA_CFLAGS += -DADDRCONF -endif - -ifdef NAS_DRIVER_TYPE_ETHERNET -EXTRA_CFLAGS += -DNAS_DRIVER_TYPE_ETHERNET -endif - - -ifdef PDCP_USE_NETLINK -EXTRA_CFLAGS += -DPDCP_USE_NETLINK -else -EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall -endif - -ifdef LOOPBACK -EXTRA_CFLAGS += -DLOOPBACK_TEST -endif - -ifdef ADDRESS_FIX -EXTRA_CFLAGS += -DNAS_ADDRESS_FIX -endif - -#################################################### -# NASRGCELL extra compilation flags -#################################################### -#RTAI=1 -RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR -EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_RG - -#################################################### -# LOADABLE MODULE GOALS -#################################################### -obj-m += nascellrg.o -nascellrg-objs += nasrg_device.o -nascellrg-objs += nasrg_common.o -nascellrg-objs += nasrg_iocontrol.o -nascellrg-objs += nasrg_classifier.o -nascellrg-objs += nasrg_tool.o -nascellrg-objs += nasrg_ascontrol.o -ifdef PDCP_USE_NETLINK -nascellrg-objs += nasrg_netlink.o -endif - -#################################################### -# REVOIR LE CLEAN -#################################################### - -#netlink.ko: - #make $(x)$(y) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR) M=`pwd` modules - -#nasmesh.ko: -# make V=1 -C $(KERNEL_DIR) M=`pwd` modules -print: - @echo RRC_DIR $(RRC_DIR) -clean: - rm -f *.ko - rm -f .*.ko.cmd - rm -f .*.o.cmd - rm -f *.o - rm -f *.mod.c - find . -name *.ko -delete - find . -name *.o -delete - find . -name *.mod.c -delete diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_ascontrol.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_ascontrol.c deleted file mode 100644 index 4a6ef0e275..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_ascontrol.c +++ /dev/null @@ -1,1494 +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 nasrg_ascontrol.c -* \brief Access Stratum Control functions for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifdef NODE_RG -#include "nasrg_variables.h" -#include "nasrg_proto.h" - -//--------------------------------------------------------------------------- -void nasrg_ASCTL_init(void) -{ - //--------------------------------------------------------------------------- - int cxi, i; - - gpriv->next_sclassref = NASRG_DEFAULTRAB_CLASSREF; - - // Initialize MBMS services list in MT - for (cxi=0; cxicx[cxi].requested_joined_services[i]= -1; - gpriv->cx[cxi].requested_left_services[i]= -1; - gpriv->cx[cxi].joined_services[i]= -1; - } - } - - printk("nasrg_ASCTL_init Complete\n"); -} - -//--------------------------------------------------------------------------- -int nasrg_ASCTL_write(int sap, unsigned char *data_buffer, unsigned int data_length) -{ - //--------------------------------------------------------------------------- - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xmit_buffer [NAS_MESSAGE_MAXLEN]; - - //write SAP_Id - switch (sap) { - case RRC_DEVICE_GC: - xmit_buffer[0] = RRC_NAS_GC_IN; - break; - - case RRC_DEVICE_NT: - xmit_buffer[0] = RRC_NAS_NT_IN; - break; - - case RRC_DEVICE_DC_INPUT0: - xmit_buffer[0] = RRC_NAS_DC0_IN; - break; - - case RRC_DEVICE_DC_INPUT1: - xmit_buffer[0] = RRC_NAS_DC1_IN; - //case RRC_DEVICE_DC_INPUT2: - //xmit_buffer[0] = RRC_NAS_DC2_IN; - break; - - default: - printk("nasrg_ASCTL_write - ERROR - Invalid SAP %d\n", sap); - return 0; - break; - } - - memcpy (&((char*)xmit_buffer)[1], data_buffer, data_length); -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_write - Sending data to RRC, sap %d, length %d (including NETLINK SAP value)\n", sap, data_length+1); - nasrg_TOOL_print_buffer(xmit_buffer,data_length+1); -#endif - bytes_wrote = nasrg_netlink_send(xmit_buffer,data_length+1, NASNL_DEST_RRC); -#else - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); //original version - bytes_wrote = rtf_put(sap, data_buffer, data_length+1); -#endif //PDCP_USE_NETLINK - return bytes_wrote-1; -} - -//--------------------------------------------------------------------------- -//For demo, add automatically a radio bearer -//Equivalent to rb add send 0 5 2 -void nasrg_ASCTL_start_default_rb(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- -#ifdef DEMO_3GSM - struct rb_entity *rb; - int status; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_start_default_rb - begin \n"); -#endif - - if (!cx) { - printk("nasrg_ASCTL_start_default_rb - input parameter cx is NULL \n"); - return; - } - - // End debug information - - rb = nasrg_COMMON_add_rb(cx, NASRG_DEFAULTRAB_RBID, NASRG_DEFAULTRAB_QoS); - - if (rb!=NULL) { - rb->cnxid = (NAS_RB_MAX_NUM * cx->lcr)+1; - //rb->default_rab =1; - rb->dscp = NASRG_DEFAULTRAB_DSCP; - rb->dscp_ul = NASRG_DEFAULTRAB_DSCP; - status=nasrg_ASCTL_DC_send_rb_establish_request(cx, rb); - } else - status=-NAS_ERROR_NOMEMORY; - -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_start_default_rb - end %d \n",status); -#endif -} -#endif - -//--------------------------------------------------------------------------- -//For demo, add automatically a classifier -//Equivalent to class add send 0 -f qos -cr 0 -void nasrg_ASCTL_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_default_sclassifier - begin \n"); -#endif - - if (!cx || !rb) { - printk("nasrg_ASCTL_start_default_sclassifier - input parameter is NULL \n"); - return; - } - - // End debug information - gc=nasrg_CLASS_add_sclassifier(cx, NAS_DSCP_DEFAULT, gpriv->next_sclassref); - - if (gc==NULL) { - printk("nasrg_ASCTL_start_default_sclassifier - Classifier pointer is null : not added \n"); - return; - } - - gc->fct = nasrg_COMMON_QOS_send; - gc->rab_id =rb->rab_id; - gc->rb= rb; - gc->version = NASRG_DEFAULTRAB_IPVERSION; - gc->protocol= NAS_PROTOCOL_DEFAULT; - gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH; - // copy locator part of address into the gc structure - //gc->daddr.ipv6.s6_addr32[0] = 0; - //gc->daddr.ipv6.s6_addr32[1] = 0; - //gc->daddr.ipv6.s6_addr32[2] = 0; - //gc->daddr.ipv6.s6_addr32[3] = 0; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_default_sclassifier - end \n"); - nasrg_TOOL_print_classifier(gc); -#endif -} - -//--------------------------------------------------------------------------- -//Add automatically a classifier on DSCP -//Equivalent to class add send 0 -f qos -cr 0 -void nasrg_ASCTL_start_sclassifier(struct cx_entity *cx,struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_sclassifier - begin \n"); -#endif - - if (!cx || !rb) { - printk("nasrg_ASCTL_start_sclassifier - input parameter is NULL \n"); - return; - } - - // End debug information - gc=nasrg_CLASS_add_sclassifier(cx, rb->dscp, gpriv->next_sclassref); - - if (gc==NULL) { - printk("nasrg_ASCTL_start_sclassifier - Classifier pointer is null : not added \n"); - return; - } - - gc->fct = nasrg_COMMON_QOS_send; - gc->rab_id =rb->rab_id; - gc->rb= rb; - gc->version = NASRG_DEFAULTRAB_IPVERSION; - gc->protocol= NAS_PROTOCOL_DEFAULT; - gc->dplen= NAS_DEFAULT_IPv6_PREFIX_LENGTH; - // copy locator part of address into the gc structure - gc->daddr.ipv6.s6_addr32[2] = cx->iid6[0]; - gc->daddr.ipv6.s6_addr32[3] = cx->iid6[1]; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_sclassifier - end \n"); - nasrg_TOOL_print_classifier(gc); -#endif -} - -//--------------------------------------------------------------------------- -//Add automatically a classifier for mbms -void nasrg_ASCTL_start_mbmsclassifier(int mbms_ix,struct rb_entity *mbms_rb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_mbmsclassifier - begin \n"); -#endif - - if (!mbms_rb) { - printk("nasrg_ASCTL_start_mbmsclassifier - input parameter is NULL \n"); - return; - } - - // End debug information - // - // gc=nasrg_CLASS_add_mbmsclassifier(mbms_ix, gpriv->next_mbmsclassref); - gc=nasrg_CLASS_add_mbmsclassifier(mbms_ix, gpriv->next_sclassref++); - - if (gc==NULL) { - printk("nasrg_ASCTL_start_mbmsclassifier - Classifier pointer is null : not added \n"); - return; - } - - gc->fct = nasrg_COMMON_QOS_send; - gc->rab_id =mbms_rb->mbms_rbId; - gc->rb= mbms_rb; - gc->version = NASRG_DEFAULTRAB_IPVERSION; - gc->protocol= NAS_PROTOCOL_DEFAULT; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_ASCTL_start_mbmsclassifier - end \n"); - nasrg_TOOL_print_classifier(gc); -#endif -} - -//--------------------------------------------------------------------------- -//Notifies automatically UE on default MBMS service -void nasrg_ASCTL_start_default_ue_notification(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_start_default_ue_notification - begin \n"); -#endif - - if (!cx) { - printk("\nERROR nasrg_ASCTL_start_default_ue_notification - input parameter is NULL \n"); - return; - } - - // End debug information - // set value for default MBMS service - cx->requested_joined_services[0] = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1; - nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx); -} - -//--------------------------------------------------------------------------- -//Notifies automatically UE on default MBMS service -void nasrg_ASCTL_start_default_mbms_service(void) -{ - //--------------------------------------------------------------------------- - int mbms_ix=0; // should allocate index based on Service_id /cnxid / MC IP address -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_start_default_mbms_service - begin \n"); -#endif - - // Establish MBMS bearer if not already done - if ((gpriv->mbms_rb[mbms_ix].state != NAS_CX_DCH)&&(gpriv->mbms_rb[mbms_ix].state != NAS_RB_ESTABLISHING)) { - gpriv->mbms_rb[mbms_ix].cnxid = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1; - gpriv->mbms_rb[mbms_ix].serviceId = (NAS_CX_MAX*NAS_RB_MAX_NUM) +1; - gpriv->mbms_rb[mbms_ix].sessionId = NASRG_TEMP_MBMS_SESSION_ID; //Temp hard coded - gpriv->mbms_rb[mbms_ix].mbms_rbId = NASRG_DEFAULTRAB_RBID; - gpriv->mbms_rb[mbms_ix].sapi = NAS_DC_INPUT_SAPI; -#ifdef NAS_DEBUG_MBMS_PROT - gpriv->mbms_rb[mbms_ix].sapi = NAS_DRB_INPUT_SAPI; //Only one RT-FIFO is used -#endif - gpriv->mbms_rb[mbms_ix].qos = 20; //from first version of MBMS traces - gpriv->mbms_rb[mbms_ix].dscp = 0; //maybe 7 - gpriv->mbms_rb[mbms_ix].duration = NASRG_TEMP_MBMS_DURATION; //Temp hard coded - //memcpy ((char *)&(gpriv->mbms_rb[mbms_ix].mcast_address),(char *)&(msgreq->mcast_group), 16); - gpriv->mbms_rb[mbms_ix].mcast_address[0] = 0xFF; - gpriv->mbms_rb[mbms_ix].mcast_address[1] = 0x0E; - nasrg_ASCTL_GC_send_mbms_bearer_establish_req(mbms_ix); - } else { -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_start_default_mbms_service - skipped, mbms_rb.state = %d \n", gpriv->mbms_rb[mbms_ix].state); -#endif - } -} -//--------------------------------------------------------------------------- -void nasrg_ASCTL_timer(unsigned long data) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; - struct cx_entity *cx; - struct rb_entity *rb; - spin_lock(&gpriv->lock); -#ifdef NAS_DEBUG_TIMER - printk("nasrg_ASCTL_timer - begin \n"); -#endif - (gpriv->timer).function = nasrg_ASCTL_timer; - (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; - (gpriv->timer).data=0L; - - for (cxi=0; cxicx+cxi; - - if (!cx) { - printk("nasrg_ASCTL_timer - No pointer for connection %d \n", cxi); - continue; - } - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->countimer!=NAS_TIMER_IDLE) { -#ifdef NAS_DEBUG_TIMER - printk("nasrg_ASCTL_timer : rb countimer %d, rb state %d\n", rb->countimer, rb->state); -#endif - - if (rb->countimer==0) { - switch (rb->state) { - case NAS_CX_CONNECTING: - case NAS_CX_CONNECTING_FAILURE: // MW - 15/01/07 Useless, currently no retry if failure - if (rb->retryretry_limit) { - printk("nasrg_ASCTL_timer: Retry RB establishment %d\n", rb->retry); - nasrg_ASCTL_DC_send_rb_establish_request(cx, rb); - } else { - printk("nasrg_ASCTL_timer: RB Establishment failure\n"); - rb->state=NAS_IDLE; - rb->countimer=NAS_TIMER_IDLE; - } - - break; - - case NAS_CX_DCH: -#ifdef DEMO_3GSM - if (cx->num_rb == 1) { - nasrg_ASCTL_start_default_sclassifier(cx, rb); - } - -#endif - nasrg_ASCTL_start_sclassifier(cx, rb); - rb->countimer=NAS_TIMER_IDLE; - break; - - case NAS_CX_RELEASING_FAILURE: - nasrg_ASCTL_DC_send_rb_release_request(cx, rb); - break; - - default: - rb->countimer=NAS_TIMER_IDLE; - } - } else { - --rb->countimer; - printk("nasrg_ASCTL_timer : rb countimer-- %d, rb state %d\n", rb->countimer, rb->state); - } - } - } - } - - add_timer(&gpriv->timer); -#ifdef NAS_DEBUG_TIMER - printk("nasrg_ASCTL_timer - end \n"); -#endif - spin_unlock(&gpriv->lock); -} - - -/*************************************************************************** - Transmission side - ***************************************************************************/ -//--------------------------------------------------------------------------- -// Encode INFO_BROADCAST_REQ message -int nasrg_ASCTL_GC_send_broadcast_request(uint8_t category) -{ - //--------------------------------------------------------------------------- - char *xmit_data = "TESTING BROADCASTING ROUTER ADVERTISEMENT. TESTING BROADCASTING ROUTER ADVERTISEMENT. BROADCASTING ROUTER.\0"; - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xbuffer[NAS_MESSAGE_MAXLEN]; - int count=0; -#endif - - struct nas_rg_gc_element *p; - p= (struct nas_rg_gc_element *)(gpriv->xbuffer); - p->type = INFO_BROADCAST_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASInfoBroadcastReq); - // - p->nasRGGCPrimitive.broadcast_req.period = 0; - p->nasRGGCPrimitive.broadcast_req.category = category; - p->nasRGGCPrimitive.broadcast_req.nasDataLength = strlen(xmit_data)+1; // TBD - - //bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); //original version -#ifdef PDCP_USE_NETLINK - memcpy(xbuffer,(unsigned char *)p, p->length); - count = p->length; - bytes_wrote = count; -#else - bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length); -#endif - //printk("nasrg_ASCTL_GC_send_broadcast_request - Wrote %d bytes to RRC NAS_GC_SAPII\n", bytes_wrote); - - //bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength); -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength); - count += p->nasRGGCPrimitive.broadcast_req.nasDataLength; - bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], xbuffer, count); -#else - bytes_wrote += nasrg_ASCTL_write((gpriv->sap[NAS_GC_SAPI], xmit_data, p->nasRGGCPrimitive.broadcast_req.nasDataLength); -#endif - - if (bytes_wrote==p->length+p->nasRGGCPrimitive.broadcast_req.nasDataLength) { -#ifdef NAS_DEBUG_GC - printk("nasrg_ASCTL_GC_send_broadcast: INFO_BROADCAST_REQ primitive sent successfully in GC-FIFO\n"); -#endif - } else { - printk("nasrg_ASCTL_GC_send_broadcast: Message sent failure in GC-FIFO\n"); - } - return bytes_wrote; -} - - -//--------------------------------------------------------------------------- -// Encode INFO_BROADCAST_REQ message for RRC SIB1 -int nasrg_ASCTL_GC_send_SIB1_broadcast_request(struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct nas_rg_gc_element *p; - char sib1_flag; // will be used for reception in nas_ue - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xbuffer[NAS_MESSAGE_MAXLEN]; - int count=0; -#endif - - // Start debug information -#ifdef NAS_DEBUG_GC - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - begin \n"); -#endif - - if (!skb) { - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - input parameter is NULL \n"); - return 0; - } - - // End debug information - p= (struct nas_rg_gc_element *)(gpriv->xbuffer); - p->type = INFO_BROADCAST_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASInfoBroadcastReq); - // - p->nasRGGCPrimitive.broadcast_req.period = 10; // to be checked - p->nasRGGCPrimitive.broadcast_req.category = 1; - p->nasRGGCPrimitive.broadcast_req.nasDataLength = skb->len+1; // TBD - sib1_flag = 1; - // send header - //bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); //original version -#ifdef PDCP_USE_NETLINK - memcpy(xbuffer,(unsigned char *)p, p->length); - count = p->length; - bytes_wrote = count; -#else - bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length); -#endif - //printk("nasrg_ASCTL_GC_send_broadcast_request - Wrote %d bytes to RRC NAS_GC_SAPII\n", bytes_wrote); - - - if (bytes_wrote!=p->length) { - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: Header send failure in GC-FIFO\n"); - return bytes_wrote; - } - - // send sib1_flag - //bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], &sib1_flag, 1); -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)&sib1_flag, 1); - count += 1; - bytes_wrote = count; -#else - bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)&sib1_flag, 1); -#endif - - if (bytes_wrote!=p->length+1) { - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: sib1_flag send failure in GC-FIFO\n"); - return bytes_wrote; - } - - // send data - //bytes_wrote += rtf_put(gpriv->sap[NAS_GC_SAPI], skb->data, skb->len); -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),skb->data, skb->len); - count += skb->len; - bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], xbuffer, count); -#else - bytes_wrote += nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], skb->data, skb->len); -#endif - - - if (bytes_wrote!=p->length+skb->len+1) { - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request: Data send failure in GC-FIFO\n"); - return bytes_wrote; - } - -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_GC_send_SIB1_broadcast_request - end \n"); -#endif - return bytes_wrote; -} - -//----------------------------------------------------------------------------- -// Encode MBMS_BEARER_ESTABLISH_REQ message -int nasrg_ASCTL_GC_send_mbms_bearer_establish_req(int mbms_ix ) -{ - //----------------------------------------------------------------------------- - struct nas_rg_gc_element *p; - int bytes_wrote = 0; - - p= (struct nas_rg_gc_element *)(gpriv->xbuffer); - p->type = MBMS_BEARER_ESTABLISH_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASMBMSBearerEstablishReq); - // - p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId = gpriv->mbms_rb[mbms_ix].serviceId; - p->nasRGGCPrimitive.mbms_establish_req.mbms_sessionId = gpriv->mbms_rb[mbms_ix].sessionId; - p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId = gpriv->mbms_rb[mbms_ix].mbms_rbId; - p->nasRGGCPrimitive.mbms_establish_req.mbms_sapId = gpriv->mbms_rb[mbms_ix].sapi; - p->nasRGGCPrimitive.mbms_establish_req.mbms_QoSclass = gpriv->mbms_rb[mbms_ix].qos; - p->nasRGGCPrimitive.mbms_establish_req.mbms_duration = gpriv->mbms_rb[mbms_ix].duration; - gpriv->mbms_rb[mbms_ix].state = NAS_RB_ESTABLISHING; - // - //bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { -#ifdef NAS_DEBUG_GC - printk(" nasrg_ASCTL_GC_send_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_REQ primitive sent successfully in GC-FIFO\n"); - printk(" ServiceId %d, RB_Id %d , qos class %d \n", - p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId, - p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId, - p->nasRGGCPrimitive.mbms_establish_req.mbms_QoSclass); -#endif - } else { - printk("nasrg_ASCTL_GC_send_mbms_bearer_establish: Message sent failure in GC-FIFO\n"); - } - - return bytes_wrote; -} - -//----------------------------------------------------------------------------- -// HNN - Encode MBMS_BEARER_RELEASE_REQ message -int nasrg_ASCTL_GC_send_mbms_bearer_release_req(int mbms_ix) -{ - //----------------------------------------------------------------------------- - struct nas_rg_gc_element *p; - uint16_t classref=0; - int bytes_wrote = 0; - - p= (struct nas_rg_gc_element *)(gpriv->xbuffer); - - p->type = MBMS_BEARER_RELEASE_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASMBMSBearerReleaseReq); - // - p->nasRGGCPrimitive.mbms_release_req.mbms_serviceId = gpriv->mbms_rb[mbms_ix].serviceId; - p->nasRGGCPrimitive.mbms_release_req.mbms_sessionId = gpriv->mbms_rb[mbms_ix].sessionId; - p->nasRGGCPrimitive.mbms_release_req.mbms_rbId = gpriv->mbms_rb[mbms_ix].mbms_rbId; - //gpriv->mbms_rb[mbms_ix].state = NAS_RB_RELEASING; - // - //bytes_wrote = rtf_put(gpriv->sap[NAS_GC_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(gpriv->sap[NAS_GC_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { -#ifdef NAS_DEBUG_GC - printk(" nasrg_ASCTL_GC_send_mbms_bearer_release: MBMS_BEARER_RELEASE_REQ primitive sent successfully in GC-FIFO\n"); - printk(" ServiceId %d, RB_Id %d \n", p->nasRGGCPrimitive.mbms_establish_req.mbms_serviceId, p->nasRGGCPrimitive.mbms_establish_req.mbms_rbId); -#endif - // clean NASRG private structures - classref = (gpriv->mbmsclassifier[mbms_ix])->classref; - nasrg_CLASS_del_mbmsclassifier(mbms_ix, classref); - //nasrg_CLASS_flush_mbmsclassifier(); - //gpriv->mbms_rb[mbms_ix].state = NAS_IDLE; - memset (&(gpriv->mbms_rb[mbms_ix]),0,sizeof (struct rb_entity)); - } else { - printk("nasrg_ASCTL_GC_send_mbms_bearer_release: Message sent failure in GC-FIFO\n"); - } - - return bytes_wrote; -} - -//--------------------------------------------------------------------------- -// Confirm the establishment of a connection (DC channel) -int nasrg_ASCTL_DC_send_cx_establish_confirm(struct cx_entity *cx, uint8_t response) -{ - //--------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_cx_establish - begin \n"); -#endif - - if (!cx) { - printk("nasrg_ASCTL_DC_send_cx_establish - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - p= (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = CONN_ESTABLISH_CNF; - p->length = NAS_TL_SIZE + sizeof(struct NASConnEstablishConf); - p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef = cx->lcr; - p->nasRGDCPrimitive.conn_establish_conf.status = response; // can be ACCEPTED or FAILURE - p->nasRGDCPrimitive.conn_establish_conf.num_RBs = 0; // Hard coded in first step - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_cx_establish: CONN_ESTABLISH_CNF primitive sent successfully in DC-FIFO\n"); - printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.conn_establish_conf.localConnectionRef); - printk(" Status %u\n",p->nasRGDCPrimitive.conn_establish_conf.status); -#endif - } else - printk("nasrg_ASCTL_DC_send_cx_establish: Message transmission failure to DC-FIFO\n"); - - return bytes_wrote; -} - -//--------------------------------------------------------------------------- -// Request the establishment of a radio bearer -int nasrg_ASCTL_DC_send_rb_establish_request(struct cx_entity *cx, struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_rb_establish - begin \n"); -#endif - - if (!cx || !rb) { - printk("nasrg_ASCTL_DC_send_rb_establish - input parameter is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - switch(rb->state) { - case NAS_CX_CONNECTING: - case NAS_CX_CONNECTING_FAILURE: - case NAS_IDLE: - ++rb->retry; - rb->countimer=gpriv->timer_establishment; - - if (cx->state==NAS_CX_DCH) { - p= (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = RB_ESTABLISH_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASrbEstablishReq); - p->nasRGDCPrimitive.rb_establish_req.localConnectionRef = cx->lcr; - p->nasRGDCPrimitive.rb_establish_req.rbId = rb->rab_id + (NAS_RB_MAX_NUM * cx->lcr); - p->nasRGDCPrimitive.rb_establish_req.QoSclass = rb->qos; - p->nasRGDCPrimitive.rb_establish_req.dscp = rb->dscp_ul; - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { - rb->state=NAS_CX_CONNECTING; -#ifdef NAS_DEBUG_DC - printk(" nasrg_ASCTL_DC_send_rb_establish: RB_ESTABLISH_REQ primitive sent successfully in DC-FIFO\n"); - printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.rb_establish_req.localConnectionRef); - printk(" Radio Bearer identification %u\n",p->nasRGDCPrimitive.rb_establish_req.rbId); - printk(" QoS %u\n",p->nasRGDCPrimitive.rb_establish_req.QoSclass); -#endif - } else { - rb->state=NAS_CX_CONNECTING_FAILURE; - printk("nasrg_ASCTL_DC_send_rb_establish: Message sent failure in DC-FIFO\n"); - } - - return bytes_wrote; - } else { - rb->state=NAS_CX_CONNECTING_FAILURE; - printk("nasrg_ASCTL_DC_send_rb_establish: Failure \n"); - return 0; - } - - default: - return -NAS_ERROR_NOTIDLE; - } -} - -//--------------------------------------------------------------------------- -// Request the release of a radio bearer -int nasrg_ASCTL_DC_send_rb_release_request(struct cx_entity *cx, struct rb_entity *rb) -{ - //--------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_rb_release - begin \n"); -#endif - - if (!cx || !rb) { - printk("nasrg_ASCTL_DC_send_rb_release - input parameter is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - switch (rb->state) { - case NAS_CX_RELEASING_FAILURE: - case NAS_CX_DCH: - p= (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = RB_RELEASE_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASrbReleaseReq); - p->nasRGDCPrimitive.rb_release_req.localConnectionRef = cx->lcr; - p->nasRGDCPrimitive.rb_release_req.rbId = rb->rab_id + (NAS_RB_MAX_NUM * cx->lcr); - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote) { - rb->state=NAS_IDLE; -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_rb_release: RB_RELEASE_REQ primitive sent successfully in DC-FIFO\n"); -#endif - } else { - ++rb->retry; - rb->countimer=gpriv->timer_release; - rb->state=NAS_CX_RELEASING_FAILURE; - printk("nasrg_ASCTL_DC_send_rb_release: Message sent failure in DC-FIFO\n"); - } - - return bytes_wrote; - - default: - return -NAS_ERROR_NOTCONNECTED; - } -} - -//----------------------------------------------------------------------------- -// Request the notification of a UE to joined or left services -int nasrg_ASCTL_DC_send_mbms_ue_notify_req(struct cx_entity *cx) -{ - //----------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int i; - int bytes_wrote = 0; - -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req - begin \n"); -#endif - - if (!cx) { - printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req - input parameter is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - p= (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = MBMS_UE_NOTIFY_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASMBMSUENotifyReq); - // - p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef = cx->lcr; - - // joined/left services are lists of MAX_MBMS_SERVICES - // -1 means the end of the list - for (i = 0; i < MAX_MBMS_SERVICES; i++) { - p->nasRGDCPrimitive.mbms_ue_notify_req.joined_services[i].mbms_serviceId = (nasMBMSServiceId_t)cx->requested_joined_services[i]; - p->nasRGDCPrimitive.mbms_ue_notify_req.left_services[i].mbms_serviceId = (nasMBMSServiceId_t)cx->requested_left_services[i]; - } - - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req: MBMS_UE_NOTIFY_REQ primitive sent successfully in DC-FIFO\n"); - printk(" lcr (Mobile_id) %u\n",p->nasRGDCPrimitive.mbms_ue_notify_req.localConnectionRef); - printk(" joined service %d, left service %d\n",cx->requested_joined_services[0], cx->requested_left_services[0] ); -#endif - } else - printk("nasrg_ASCTL_DC_send_mbms_ue_notify_req: Message transmission failure to DC-FIFO\n"); - - return bytes_wrote; -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (DC SAP) -void nasrg_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int bytes_wrote = 0; -#ifdef PDCP_USE_NETLINK - unsigned char xbuffer[NAS_MESSAGE_MAXLEN]; - int count=0; -#endif - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_sig_data - begin \n"); -#endif - - if (!skb || !gc || !cx) { - printk("nasrg_ASCTL_DC_send_sig_data - input parameter is NULL \n"); - return; - } - - // End debug information - if (cx->state!=NAS_CX_DCH) { - printk("nasrg_ASCTL_DC_send_sig_data: Not connected, so the message is dropped\n"); - ++gpriv->stats.tx_dropped; - return; - } - - p = (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = DATA_TRANSFER_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASDataReq); - p->nasRGDCPrimitive.data_transfer_req.localConnectionRef = cx->lcr; - p->nasRGDCPrimitive.data_transfer_req.priority = NAS_SIG_SRB3; - p->nasRGDCPrimitive.data_transfer_req.nasDataLength = skb->len; - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); -#ifdef PDCP_USE_NETLINK - memcpy(xbuffer,(unsigned char *)p, p->length); - count = p->length; - bytes_wrote = count; -#else - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); -#endif - - if (bytes_wrote!=p->length) { - printk("nasrg_ASCTL_DC_send_sig_data: Header sent failure in DC-FIFO\n"); - return; - } - - //bytes_wrote += rtf_put(cx->sap[NAS_DC_INPUT_SAPI], skb->data, skb->len); -#ifdef PDCP_USE_NETLINK - memcpy(&(xbuffer[count]),(unsigned char *)skb->data, skb->len); - count += skb->len; - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], xbuffer, count); -#else - bytes_wrote += nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)skb->data, skb->len); -#endif - - if (bytes_wrote!=p->length+skb->len) { - printk("nasrg_ASCTL_DC_send_sig_data: Data sent failure in DC-FIFO\n"); - return; - } - - gpriv->stats.tx_bytes += skb->len; - gpriv->stats.tx_packets ++; -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_sig_data - end \n"); -#endif -} - -//--------------------------------------------------------------------------- -// Confirm the establishment of a connection (DC channel) -int nasrg_ASCTL_DC_send_eNBmeasurement_req(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - struct nas_rg_dc_element *p; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_eNBmeasurement_req - begin \n"); -#endif - - if (!cx) { - printk("nasrg_ASCTL_DC_send_eNBmeasurement_req - input parameter cx is NULL \n"); - return NAS_ERROR_NOTCORRECTVALUE; - } - - // End debug information - p= (struct nas_rg_dc_element *)(gpriv->xbuffer); - p->type = ENB_MEASUREMENT_REQ; - p->length = NAS_TL_SIZE + sizeof(struct NASENbMeasureReq); - p->nasRGDCPrimitive.eNBmeasurement_req.cell_id = cx->cellid; - // - //bytes_wrote = rtf_put(cx->sap[NAS_DC_INPUT_SAPI], p, p->length); - bytes_wrote = nasrg_ASCTL_write(cx->sap[NAS_DC_INPUT_SAPI], (unsigned char *)p, p->length); - - if (bytes_wrote==p->length) { -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_send_eNBmeasurement_req: ENB_MEASUREMENT_REQ primitive sent successfully in DC-FIFO\n"); - printk(" cell_id %u\n",p->nasRGDCPrimitive.eNBmeasurement_req.cell_id); -#endif - } else - printk("nasrg_ASCTL_DC_send_eNBmeasurement_req: Message transmission failure to DC-FIFO\n"); - - return bytes_wrote; -} - -/*************************************************************************** - Reception side - ***************************************************************************/ - -//--------------------------------------------------------------------------- -// Decode CONN_ESTABLISH_IND message from RRC -void nasrg_ASCTL_DC_decode_cx_establish_ind(struct cx_entity *cx, struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - int i; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_establish - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_cx_establish - input parameter is NULL \n"); - return; - } - - // End debug information - if (nasrg_ASCTL_DC_send_cx_establish_confirm(cx, ACCEPTED)>0) { - nasrg_TOOL_imei2iid(p->nasRGDCPrimitive.conn_establish_ind.InterfaceIMEI, (uint8_t *)cx->iid6); - cx->iid4=97; // A AUTOMATISER - cx->lcr = p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef; - cx->state=NAS_CX_DCH; -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_establish: CONN_ESTABLISH_IND reception\n"); - printk(" primitive length %d\n",p->length); - printk(" Local Connection reference %d\n",p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef); - printk(" IMEI "); - - for (i=0; i<14; ++i) - printk("%u",p->nasRGDCPrimitive.conn_establish_ind.InterfaceIMEI[i]); - - printk(" state "); - nasrg_TOOL_print_state(cx->state); -#endif - } -} - -//--------------------------------------------------------------------------- -// Decode CONN_RELEASE_IND message from RRC -void nasrg_ASCTL_DC_decode_cx_release_ind(struct cx_entity *cx, struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_release - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_cx_release - input parameter is NULL \n"); - return; - } - - // End debug information - cx->state=NAS_IDLE; - cx->iid4=0; - nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6); - nasrg_COMMON_flush_rb(cx); - nasrg_CLASS_flush_sclassifier(cx); -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_release: CONN_RELEASE_IND reception\n"); - printk(" Primitive length %u\n",p->length); - printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.conn_release_ind.localConnectionRef); - printk(" Release cause %u\n",p->nasRGDCPrimitive.conn_release_ind.releaseCause); - nasrg_TOOL_print_state(cx->state); -#endif -} - -//--------------------------------------------------------------------------- -// Decode CONN_LOSS_IND message from RRC -void nasrg_ASCTL_DC_decode_cx_loss_ind(struct cx_entity *cx, struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_loss - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_cx_loss - input parameter is NULL \n"); - return; - } - - // End debug information - cx->state = NAS_IDLE; - cx->iid4=0; - nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)cx->iid6); - nasrg_COMMON_flush_rb(cx); -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_cx_loss: CONN_LOSS_IND reception\n"); - printk(" Primitive length %u\n",(int)(p->length)); - printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef); - nasrg_TOOL_print_state(cx->state); -#endif -} -//--------------------------------------------------------------------------- -// Decode RB_ESTABLISH_CNF message from RRC -void nasrg_ASCTL_DC_decode_rb_establish_cnf(struct cx_entity *cx, struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; - int rb_id; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_rb_establish - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_rb_establish - input parameter is NULL \n"); - return; - } - - // End debug information - rb_id = p->nasRGDCPrimitive.rb_establish_conf.rbId; - rb=nasrg_COMMON_search_rb(cx, rb_id - (NAS_RB_MAX_NUM * cx->lcr)); - - // - if (rb!=NULL) { - if (rb->state==NAS_CX_CONNECTING) { -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF received\n"); - printk(" Primitive length %u\n", p->length); - printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef); - printk(" RB Id %u\n",p->nasRGDCPrimitive.rb_establish_conf.rbId); - printk(" SAP Id %u\n",p->nasRGDCPrimitive.rb_establish_conf.sapId); - printk(" Status %u, Failure code %d, Cx state, RB state\n",p->nasRGDCPrimitive.rb_establish_conf.status, p->nasRGDCPrimitive.rb_establish_conf.fail_code); - nasrg_TOOL_print_state(cx->state); - nasrg_TOOL_print_state(rb->state); -#endif - - switch (p->nasRGDCPrimitive.rb_establish_conf.status) { - case ACCEPTED: - rb->state = NAS_CX_DCH; - rb->countimer=1; - break; - - case FAILURE: - printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF rejected\n"); - rb->state = NAS_CX_CONNECTING_FAILURE; - //delete rb - break; - - default: - printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF reception, invalid status\n"); - } - } else - printk("nasrg_ASCTL_DC_decode_rb_establish: invalid state %u\n", cx->state); - } else - printk("nasrg_ASCTL_DC_decode_rb_establish: RB_ESTABLISH_CNF, No corresponding radio bearer\n"); -} - -//--------------------------------------------------------------------------- -// Decode DATA_TRANSFER_IND message from RRC -void nasrg_ASCTL_DC_decode_data_transfer_ind(struct cx_entity *cx, struct nas_rg_dc_element *p, char *buffer) -{ - //--------------------------------------------------------------------------- - uint8_t nasrg_data[10]; - unsigned int nas_length; - char data_type; - int bytes_read=0; - unsigned int peer_command; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_data_transfer - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_data_transfer - input parameter is NULL \n"); - return; - } - - // End debug information - - bytes_read=p->length; - // Get first character - nas_length = (p->nasRGDCPrimitive.data_transfer_ind.nasDataLength) -1; -#ifndef PDCP_USE_NETLINK - bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], &data_type, 1); -#else - memcpy (&data_type, (char *)(&buffer[bytes_read]), 1); - bytes_read ++; -#endif - - //check if peer message - if (data_type =='A') { - // receive in a skbuff - //nasrg_COMMON_receive((p->length) + 1, nas_length, cx->sap[NAS_DC_OUTPUT_SAPI]); // original -#ifndef PDCP_USE_NETLINK - //void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - // data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer) - nasrg_COMMON_receive((p->length) + 1, nas_length, NULL, 2, cx->sap[NAS_DC_OUTPUT_SAPI]); -#else - //nasrg_COMMON_receive((p->length) + 1, nas_length, (unsigned char *)p+p->length+1, 2, 0); - nasrg_COMMON_receive((p->length) + 1, nas_length, (unsigned char *)(&buffer[bytes_read]), 2, 0); -#endif - } else { - // if FIFO, empty remaining data -#ifndef PDCP_USE_NETLINK - bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], (gpriv->rbuffer)+ (p->length), nas_length); -#endif - - if (data_type=='Z') { -#ifndef PDCP_USE_NETLINK - memcpy (&nasrg_data, (char *)(gpriv->rbuffer)+ (p->length), 10); -#else - memcpy (&nasrg_data, (char *)(&buffer[bytes_read]), 10); -#endif - peer_command = (int)nasrg_data[0]; - printk("nasrg_ASCTL_DC_decode_data_transfer: Received peer message %d %d \n", nasrg_data[0], peer_command); - nasrg_TOOL_print_buffer(nasrg_data, 10); - - if (nasrg_data[0]== NAS_CMD_OPEN_RB) { - // open radio bearer - printk("nasrg_ASCTL_DC_decode_data_transfer: Opening Default Radio Bearer\n"); - nasrg_ASCTL_start_default_rb(cx); - } else if (nasrg_data[0]== NAS_CMD_ENTER_SLEEP) { - printk("nasrg_ASCTL_DC_decode_data_transfer: Entering Sleep Mode\n"); - cx->state = NAS_CX_RELEASING; - } else if (nasrg_data[0]== NAS_CMD_LEAVE_SLEEP) { - printk("nasrg_ASCTL_DC_decode_data_transfer: Leaving Sleep Mode\n"); - cx->state = NAS_CX_DCH; - } else { - printk("\n\nnasrg_ASCTL_DC_decode_data_transfer: Unknown peer command\n"); - } - } else - printk("nasrg_ASCTL_DC_decode_data_transfer: Error during reception of the message - Dropped\n"); - } - -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_data_transfer: DATA_TRANSFER_IND reception\n"); - printk(" Primitive length %u\n", p->length); - printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.data_transfer_ind.localConnectionRef); - printk(" Data Length %u\n", p->nasRGDCPrimitive.data_transfer_ind.nasDataLength); - nasrg_TOOL_print_state(cx->state); -#endif -} - -//--------------------------------------------------------------------------- -// Decode MBMS_BEARER_ESTABLISH_CNF message from RRC -void nasrg_ASCTL_DC_decode_mbms_bearer_establish_cnf(struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - int mbms_ix; - int rb_id; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish - begin \n"); -#endif - - if (!p) { - printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish - input parameter is NULL \n"); - return; - } - - // End debug information - rb_id = p->nasRGDCPrimitive.mbms_establish_cnf.rbId; - mbms_ix = 0; // A revoir - find using cnxid... - - if (rb_id == gpriv->mbms_rb[mbms_ix].mbms_rbId) { - switch (p->nasRGDCPrimitive.mbms_establish_cnf.status) { - case ACCEPTED: - gpriv->mbms_rb[mbms_ix].state = NAS_CX_DCH; - gpriv->mbms_rb[mbms_ix].rab_id = gpriv->mbms_rb[mbms_ix].mbms_rbId; - nasrg_ASCTL_start_mbmsclassifier(mbms_ix,&(gpriv->mbms_rb[mbms_ix])); - break; - - case FAILURE: - printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF rejected\n"); - gpriv->mbms_rb[mbms_ix].state = NAS_CX_CONNECTING_FAILURE; //supprimer l'entree - break; - - default: - printk("nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF reception, invalid status\n"); - } - } else - printk(" nasrg_ASCTL_DC_decode_mbms_bearer_establish: invalid RB_Id %d\n", rb_id); - -#ifdef NAS_DEBUG_DC - printk(" nasrg_ASCTL_DC_decode_mbms_bearer_establish: MBMS_BEARER_ESTABLISH_CNF reception\n"); - printk(" Primitive length %u\n",p->length); - printk(" rb_id %d, status %d\n",p->nasRGDCPrimitive.mbms_establish_cnf.rbId, p->nasRGDCPrimitive.mbms_establish_cnf.status); - nasrg_TOOL_print_state(gpriv->mbms_rb[mbms_ix].state); -#endif -} - -//--------------------------------------------------------------------------- -// Decode MBMS_UE_NOTIFY_CNF message from RRC -void nasrg_ASCTL_DC_decode_mbms_ue_notify_cnf(struct cx_entity *cx, struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - int i, j, k; - - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_mbms_ue_notify - begin \n"); -#endif - - if (!cx || !p) { - printk("nasrg_ASCTL_DC_decode_mbms_ue_notify - input parameter is NULL \n"); - return; - } - - // End debug information - if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.mbmsStatus == ACCEPTED) { - for (i = 0; irequested_joined_services[i] >=0) { - for (j = 0; jjoined_services[j] ==-1) { - cx->joined_services[j]= cx->requested_joined_services[i]; - cx->requested_joined_services[i]=-1; - break; - } - } - } - - if (cx->requested_left_services[i] >=0) { - for (k = 0; kjoined_services[k] == cx->requested_left_services[i]) { - cx->joined_services[k]=-1; - cx->requested_left_services[i]=-1; - break; - } - } - } - } - } - -#ifdef NAS_DEBUG_DC - printk(" nasrg_ASCTL_DC_decode_mbms_ue_notify: MBMS_UE_NOTIFY_CNF reception\n"); - printk(" Primitive length %u\n",p->length); - printk(" Local Connection reference %u\n",p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef); - printk(" MBMS Status: %d\n", p->nasRGDCPrimitive.mbms_ue_notify_cnf.mbmsStatus); - printk(" UE services currently joined \n"); - - for (i = 0; ijoined_services[i]); - - nasrg_TOOL_print_state(cx->state); -#endif -} -/* - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.cell_id = protocol_bs->rrc.rg_cell_id; - // next values are temp hard coded, to be replaced by real values - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.num_UEs = num_connected_UEs; - for (ix=0; ixnum_connected_UEs; ix++){ - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].rlcBufferOccupancy = 100 - (30*ix); - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].scheduledPRB = 500 - (200*ix); - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.measures[ix].totalDataVolume = 640000 + (160000*ix); - } - msgToBuild->nasRgPrimitive.dc_sap_prim.nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs = 1000; - -*/ -//--------------------------------------------------------------------------- -// Decode ENB_MEASUREMENT_IND message from RRC -void nasrg_ASCTL_DC_decode_eNBmeasurement_ind(struct nas_rg_dc_element *p) -{ - //--------------------------------------------------------------------------- - uint8_t i; - // Start debug information -#ifdef NAS_DEBUG_DC - printk("nasrg_ASCTL_DC_decode_eNBmeasurement_ind - begin \n"); -#endif - - if (!p) { - printk("nasrg_ASCTL_DC_decode_eNBmeasurement_ind - input parameter p is NULL \n"); - return; - } - - // End debug information -#ifdef NAS_DEBUG_DC_DETAIL - printk(" nasrg_ASCTL_DC_decode_eNBmeasurement_ind : ENB_MEASUREMENT_IND reception\n"); - printk(" Measured Cell: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.cell_id); - printk(" Number of Connected Mobiles: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.num_UEs); - - for (i=0; inasRGDCPrimitive.eNBmeasurement_ind.num_UEs; ++i) { - printk(" UE[%u]: rlcBufferOccupancy %u, scheduledPRB: %u, totalDataVolume: %u\n", i, - p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].rlcBufferOccupancy, - p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].scheduledPRB, - p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].totalDataVolume); - } - - printk(" Total number of PRBs: %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs); -#endif - // store Measures - gpriv->measured_cell_id = p->nasRGDCPrimitive.eNBmeasurement_ind.cell_id; - gpriv->num_UEs = p->nasRGDCPrimitive.eNBmeasurement_ind.num_UEs; - - for (i=0; i num_UEs; ++i) { - gpriv->rlcBufferOccupancy[i] = p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].rlcBufferOccupancy; - gpriv->scheduledPRB[i] += p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].scheduledPRB; - gpriv->totalDataVolume[i] += p->nasRGDCPrimitive.eNBmeasurement_ind.measures[i].totalDataVolume; - } - - gpriv->totalNumPRBs += p->nasRGDCPrimitive.eNBmeasurement_ind.totalNumPRBs; -} - -//--------------------------------------------------------------------------- -// Check if anything in DC FIFO and process it (RG Finite State Machine) -int nasrg_ASCTL_DC_receive(struct cx_entity *cx, char *buffer) -{ - //--------------------------------------------------------------------------- - int bytes_read=0; - - // Start debug information -#ifdef NAS_DEBUG_DC_DETAIL - printk("nasrg_ASCTL_DC_receive - begin \n"); -#endif - - if (!cx) { - printk("nasrg_ASCTL_DC_receive - input parameter cx is NULL \n"); - return 0; - } - - // End debug information - -#ifndef PDCP_USE_NETLINK - bytes_read = rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI] , gpriv->rbuffer, NAS_TL_SIZE); -#else - bytes_read = NAS_TL_SIZE; -#endif - - if (bytes_read>0) { - struct nas_rg_dc_element *p; -#ifndef PDCP_USE_NETLINK - p= (struct nas_rg_dc_element *)(gpriv->rbuffer); - //get the rest of the primitive - bytes_read += rtf_get(cx->sap[NAS_DC_OUTPUT_SAPI], (uint8_t *)p+NAS_TL_SIZE, p->length-NAS_TL_SIZE); - - if (bytes_read!=p->length) { - printk("nasrg_ASCTL_DC_receive: Problem while reading primitive's header\n"); - return bytes_read; - } - -#else - p= (struct nas_rg_dc_element *)(buffer); - bytes_read=p->length; -#endif - - switch (p->type) { - case CONN_ESTABLISH_IND : - if (p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: CONN_ESTABLISH_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_establish_ind.localConnectionRef); - else { - switch(cx->state) { - case NAS_IDLE: - nasrg_ASCTL_DC_decode_cx_establish_ind(cx,p); - break; - - default: - printk("nasrg_ASCTL_DC_receive: CONN_ESTABLISH_IND reception, invalid state %u\n", cx->state); - } - } - - break; - - case CONN_RELEASE_IND : - if (p->nasRGDCPrimitive.conn_release_ind.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: CONN_RELEASE_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_release_ind.localConnectionRef); - else { - switch(cx->state) { - case NAS_CX_DCH: - nasrg_ASCTL_DC_decode_cx_release_ind(cx,p); - break; - - default: - printk("nasrg_ASCTL_DC_receive: CONN_RELEASE_IND reception, invalid state %u\n", cx->state); - } - } - - break; - - case CONN_LOSS_IND: - if (p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: CONN_LOSS_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.conn_loss_ind.localConnectionRef); - else { - switch(cx->state) { - case NAS_CX_DCH: - nasrg_ASCTL_DC_decode_cx_loss_ind(cx,p); - break; - - default: - printk("nasrg_ASCTL_DC_receive: CONN_LOSS_IND reception, invalid state %u\n", cx->state); - } - } - - break; - - case RB_ESTABLISH_CNF: - if (p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: RB_ESTABLISH_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef); - else { - switch(cx->state) { - case NAS_CX_DCH: - nasrg_ASCTL_DC_decode_rb_establish_cnf(cx,p); -#ifdef NAS_AUTO_MBMS - nasrg_ASCTL_start_default_ue_notification(cx); -#endif - break; - - default: - printk("nasrg_ASCTL_DC_receive: RB_ESTABLISH_CNF reception, invalid state %u\n", cx->state); - } - } - - break; - - case DATA_TRANSFER_IND: - if (p->nasRGDCPrimitive.data_transfer_ind.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: DATA_TRANSFER_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef); - else { - switch(cx->state) { - case NAS_CX_DCH: - case NAS_CX_RELEASING: - nasrg_ASCTL_DC_decode_data_transfer_ind(cx,p,buffer); - break; - - default: - printk("nasrg_ASCTL_DC_receive: DATA_TRANSFER_IND reception, invalid state %u\n", cx->state); - } - } - - break; - - // Temp - Should be in uplink GC-SAP - case MBMS_BEARER_ESTABLISH_CNF: - // if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef!=cx->lcr) - // printk("nasrg_ASCTL_DC_receive: MBMS_BEARER_ESTABLISH_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef); - // else - nasrg_ASCTL_DC_decode_mbms_bearer_establish_cnf(p); - break; - - case MBMS_UE_NOTIFY_CNF: - if (p->nasRGDCPrimitive.mbms_ue_notify_cnf.localConnectionRef!=cx->lcr) - printk("nasrg_ASCTL_DC_receive: MBMS_UE_NOTIFY_CNF reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.rb_establish_conf.localConnectionRef); - else { - switch(cx->state) { - case NAS_CX_DCH: - nasrg_ASCTL_DC_decode_mbms_ue_notify_cnf(cx,p); - /* //Temp - nasrg_ASCTL_start_default_mbms_service();*/ - break; - - default: - printk("nasrg_ASCTL_DC_receive: MBMS_UE_NOTIFY_CNF reception, invalid state %u\n", cx->state); - } - } - - break; - - // Temp - Should be in uplink GC-SAP - case ENB_MEASUREMENT_IND : - // if (p->nasRGDCPrimitive.eNBmeasurement_ind.localConnectionRef!=cx->lcr) - // printk("nasrg_ASCTL_DC_receive: ENB_MEASUREMENT_IND reception, Local connection reference not correct %u\n", p->nasRGDCPrimitive.eNBmeasurement_ind.localConnectionRef); - // else - nasrg_ASCTL_DC_decode_eNBmeasurement_ind(p); - break; - - default : - printk("nasrg_ASCTL_DC_receive: Invalid message received\n"); - } - } - - return bytes_read; -} - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_classifier.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_classifier.c deleted file mode 100644 index 4c0cf8aa1e..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_classifier.c +++ /dev/null @@ -1,1139 +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 nasrg_classifier.c -* \brief Flow classification functions for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasrg_variables.h" -#include "nasrg_proto.h" - -#include -#include - -#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) -#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) -#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) -#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) - -/* Address to accept any incoming messages. */ -#define INADDR_ANY ((unsigned long int) 0x00000000) - -#define NIPADDR(addr) \ - (uint8_t)(addr & 0x000000FF), \ - (uint8_t)((addr & 0x0000FF00) >> 8), \ - (uint8_t)((addr & 0x00FF0000) >> 16), \ - (uint8_t)((addr & 0xFF000000) >> 24) - -#define NIP6ADDR(addr) \ - ntohs((addr)->s6_addr16[0]), \ - ntohs((addr)->s6_addr16[1]), \ - ntohs((addr)->s6_addr16[2]), \ - ntohs((addr)->s6_addr16[3]), \ - ntohs((addr)->s6_addr16[4]), \ - ntohs((addr)->s6_addr16[5]), \ - ntohs((addr)->s6_addr16[6]), \ - ntohs((addr)->s6_addr16[7]) - - -#define IN6_IS_ADDR_UNSPECIFIED(a) \ - (((__const uint32_t *) (a))[0] == 0 \ - && ((__const uint32_t *) (a))[1] == 0 \ - && ((__const uint32_t *) (a))[2] == 0 \ - && ((__const uint32_t *) (a))[3] == 0) - -#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \ - (((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \ - && ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \ - && ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \ - && ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3])))) - -#define IN_ARE_ADDR_MASKED_EQUAL(a,b,m) \ - (((((__const uint8_t *) (a))[0] & (((__const uint8_t *) (m))[0])) == (((__const uint8_t *) (b))[0] & (((__const uint8_t *) (m))[0]))) \ - && ((((__const uint8_t *) (a))[1] & (((__const uint8_t *) (m))[1])) == (((__const uint8_t *) (b))[1] & (((__const uint8_t *) (m))[1]))) \ - && ((((__const uint8_t *) (a))[2] & (((__const uint8_t *) (m))[2])) == (((__const uint8_t *) (b))[2] & (((__const uint8_t *) (m))[2]))) \ - && ((((__const uint8_t *) (a))[3] & (((__const uint8_t *) (m))[3])) == (((__const uint8_t *) (b))[3] & (((__const uint8_t *) (m))[3])))) - -//--------------------------------------------------------------------------- -void nasrg_create_mask_ipv6_addr(struct in6_addr *masked_addrP, int prefix_len) -{ - //--------------------------------------------------------------------------- - int u6_addr8_index; - int u6_addr1_index; - int index; - - masked_addrP->s6_addr32[0] = 0xFFFFFFFF; - masked_addrP->s6_addr32[1] = 0xFFFFFFFF; - masked_addrP->s6_addr32[2] = 0xFFFFFFFF; - masked_addrP->s6_addr32[3] = 0xFFFFFFFF; - - u6_addr8_index = prefix_len >> 3; - u6_addr1_index = prefix_len & 0x07; - - for (index = u6_addr8_index + 1; index < 16; index++) { - masked_addrP->s6_addr[index] = 0; - } - - if (u6_addr1_index > 0) { - masked_addrP->s6_addr[u6_addr8_index] = 0xFF << (8-u6_addr1_index); - } - -#ifdef NAS_DEBUG_CLASS - //printk("nasrg_create_mask_ipv6_addr: MASK = %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(masked_addrP)); -#endif -} -//--------------------------------------------------------------------------- -void nasrg_create_mask_ipv4_addr(struct in_addr *masked_addrP, int prefix_len) -{ - //--------------------------------------------------------------------------- - if (prefix_len > 32) { - prefix_len = 32; - } - - masked_addrP->s_addr = 0xFFFFFFFF << (32 - prefix_len); -#ifdef NAS_DEBUG_CLASS - //printk("nasrg_create_mask_ipv4_addr: MASK = %d.%d.%d.%d\n",NIPADDR(masked_addrP)); -#endif - return; -} - -//--------------------------------------------------------------------------- -// Add a new classifier rule (send direction) -struct classifier_entity *nasrg_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_sclassifier: begin for dscp %d, classref %d\n", dscp,classref); -#endif - - if (cx==NULL) { - printk("nasrg_CLASS_add_sclassifier - input parameter cx is NULL \n"); - return NULL; - } - - //*** - for (gc=cx->sclassifier[dscp]; gc!=NULL; gc=gc->next) { - if (gc->classref==classref) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_sclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; - } - } - - gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_ATOMIC); - - if (gc==NULL) - return NULL; - - memset(gc, 0, sizeof(struct classifier_entity)); - gc->next=cx->sclassifier[dscp]; - gc->classref=classref; - cx->sclassifier[dscp]=gc; - ++cx->nsclassifier; - ++gpriv->next_sclassref; //increment send classref index - MW 15/01/07 -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_sclassifier: classifier created for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; -} - -//--------------------------------------------------------------------------- -// Add a new classifier rule (receive direction) -struct classifier_entity *nasrg_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_rclassifier: begin\n"); -#endif - - //*** - for (gc=gpriv->rclassifier[dscp]; gc!=NULL; gc=gc->next) { - if (gc->classref==classref) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_rclassifier: classifier already exist for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; - } - } - - gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_KERNEL); - - if (gc==NULL) - return NULL; - - gc->next=gpriv->rclassifier[dscp]; - gc->classref=classref; - gpriv->rclassifier[dscp]=gc; - ++gpriv->nrclassifier; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_rclassifier: classifier created for dscp %d, classref %d\n",dscp,classref); -#endif - return gc; -} - -//--------------------------------------------------------------------------- -// Add a new classifier rule (mbms direction) -struct classifier_entity *nasrg_CLASS_add_mbmsclassifier(int mbms_ix, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_mbmsclassifier: begin\n"); -#endif - - //*** - for (gc=gpriv->mbmsclassifier[mbms_ix]; gc!=NULL; gc=gc->next) { - if (gc->classref==classref) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_mbmsclassifier: classifier already exist for service %d, classref %d\n",mbms_ix,classref); -#endif - return gc; - } - } - - gc=(struct classifier_entity *)kmalloc(sizeof(struct classifier_entity), GFP_ATOMIC); - - if (gc==NULL) - return NULL; - - gc->next=gpriv->mbmsclassifier[mbms_ix]; - gc->classref=classref; - gpriv->mbmsclassifier[mbms_ix]=gc; - ++gpriv->nmbmsclassifier; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_add_mbmsclassifier: classifier created for service index %d, classref %d\n",mbms_ix,classref); -#endif - return gc; -} - -//--------------------------------------------------------------------------- -void nasrg_CLASS_flush_sclassifier(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t dscpi; - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_sclassifier: begin\n"); -#endif - - if (cx==NULL) { - printk("nasrg_CLASS_flush_sclassifier - input parameter cx is NULL \n"); - return; - } - - //*** - for (dscpi=0; dscpisclassifier[dscpi]; gc!=NULL; gc=cx->sclassifier[dscpi]) { - cx->sclassifier[dscpi]=gc->next; - kfree(gc); - } - } - - cx->nsclassifier=0; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_sclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -void nasrg_CLASS_flush_rclassifier() -{ - //--------------------------------------------------------------------------- - uint8_t dscpi; - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_rclassifier: begin\n"); -#endif - - //*** - for (dscpi=0; dscpirclassifier[dscpi]; gc!=NULL; gc=gpriv->rclassifier[dscpi]) { - gpriv->rclassifier[dscpi]=gc->next; - kfree(gc); - } - } - - gpriv->nrclassifier=0; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_rclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -void nasrg_CLASS_flush_mbmsclassifier() -{ - //--------------------------------------------------------------------------- - int mbmsi; - struct classifier_entity *gc; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_mbmsclassifier: begin\n"); -#endif - - //*** - for (mbmsi=0; mbmsimbmsclassifier[mbmsi]; gc!=NULL; gc=gpriv->mbmsclassifier[mbmsi]) { - gpriv->mbmsclassifier[mbmsi]=gc->next; - kfree(gc); - } - } - - gpriv->nmbmsclassifier=0; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_flush_mbmsclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete a classifier rule (send direction) -void nasrg_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *p,*np; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_sclassifier: begin\n"); -#endif - - if (cx==NULL) { - printk("nasrg_CLASS_del_sclassifier - input parameter cx is NULL \n"); - return; - } - - //*** - p=cx->sclassifier[dscp]; - - if (p==NULL) - return; - - if (p->classref==classref) { - cx->sclassifier[dscp]=p->next; - kfree(p); - --cx->nsclassifier; - return; - } - - for (np=p->next; np!=NULL; p=np) { - if (np->classref==classref) { - p->next=np->next; - kfree(np); - --cx->nsclassifier; - return; - } - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_sclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete a classifier rule (receive direction) -void nasrg_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *p,*np; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_rclassifier: begin\n"); -#endif - //*** - p=gpriv->rclassifier[dscp]; - - if (p==NULL) - return; - - if (p->classref==classref) { - gpriv->rclassifier[dscp]=p->next; - kfree(p); - --gpriv->nrclassifier; - return; - } - - for (np=p->next; np!=NULL; p=np) { - if (np->classref==classref) { - p->next=np->next; - kfree(np); - --gpriv->nrclassifier; - return; - } - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_rclassifier: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete a classifier rule (mbms direction) -void nasrg_CLASS_del_mbmsclassifier(int mbms_ix, uint16_t classref) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *p,*np; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_mbmsclassifier: begin\n"); -#endif - //*** - p=gpriv->mbmsclassifier[mbms_ix]; - - if (p==NULL) - return; - - if (p->classref==classref) { - gpriv->mbmsclassifier[mbms_ix]=p->next; - kfree(p); - --gpriv->nmbmsclassifier; - return; - } - - for (np=p->next; np!=NULL; p=np) { - if (np->classref==classref) { - p->next=np->next; - kfree(np); - --gpriv->nmbmsclassifier; - return; - } - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_del_mbmsclassifier: end\n"); -#endif -} - -/* ORIGINAL VERSION -//--------------------------------------------------------------------------- -// Search the entity with the IPv4 address 'addr' -struct cx_entity *nasrg_CLASS_cx4(struct sk_buff *skb){ -//--------------------------------------------------------------------------- - uint8_t cxi; - #ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx4: begin\n"); - #endif - cxi=0; - return gpriv->cx+cxi; -//#endif -}*/ - -//--------------------------------------------------------------------------- -// Search the entity with the IPv4 address 'addr' -struct cx_entity *nasrg_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index) -{ - //--------------------------------------------------------------------------- - unsigned char cxi; - uint32_t daddr; - struct cx_entity *cx=NULL; - struct classifier_entity *pclassifier=NULL; - struct in_addr masked_addr; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx4: begin\n"); -#endif - - if (skb!=NULL) { - daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; - - if (daddr != INADDR_ANY) { -#ifdef NAS_DEBUG_CLASS - printk("SOURCE ADDR %d.%d.%d.%d",NIPADDR(ip_hdr(skb)->saddr)); - printk(" DEST ADDR %d.%d.%d.%d\n",NIPADDR(ip_hdr(skb)->daddr)); -#endif - - if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { - // TO BE CHECKED - *paddr_type = NAS_IPV4_ADDR_MC_SIGNALLING; - } else { - if (ipv4_is_lbcast(ip_hdr(skb)->daddr)) { - // TO BE CHECKED - *paddr_type = NAS_IPV4_ADDR_BROADCAST; - } else { - if (IN_CLASSA(ip_hdr(skb)->daddr) || IN_CLASSB(ip_hdr(skb)->daddr) || IN_CLASSC(ip_hdr(skb)->daddr)) { - *paddr_type = NAS_IPV4_ADDR_UNICAST; - - for (cxi=*cx_index; cxicx[cxi].sclassifier[dscp]; - - while (pclassifier!=NULL) { - // verify that this is an IPv4 classifier - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - nasrg_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); - - if (IN_ARE_ADDR_MASKED_EQUAL(&ip_hdr(skb)->daddr, &(pclassifier->daddr.ipv4), &masked_addr)) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx4: IP MASK MATCHED: found cx %d: %d.%d.%d.%d/%d\n",cxi, NIPADDR(pclassifier->daddr.ipv4), pclassifier->dplen); -#endif - return &gpriv->cx[cxi]; - } - } - - // goto to next classification rule for the connection - pclassifier = pclassifier->next; - } - } - } else { - *paddr_type = NAS_IPV4_ADDR_UNKNOWN; - } - } - } - } - } - - return cx; -} - -/* ORIGINAL VERSION -//--------------------------------------------------------------------------- -// Search the entity corresponding to destination address in IPv6 header -struct cx_entity *nasrg_CLASS_cx6(struct sk_buff *skb, int* paddr_type, int* pmbms_ix){ -//--------------------------------------------------------------------------- - struct cx_entity * cx=NULL; - uint8_t cxi; - uint32_t mc_addr_hdr, uni_ifid1, uni_ifid2; - //int addr_type = NASRG_ADDR_UNKNOWN; - - #ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: begin\n"); - #endif - if (!skb){ - printk("nasrg_CLASS_cx6 - input parameter skb is NULL \n"); - return cx; - } - *paddr_type = NASRG_ADDR_UNKNOWN; - //mc_addr_hdr = ntohl(skb->nh.ipv6h->daddr.in6_u.u6_addr32[0]); - mc_addr_hdr = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0]); - // First check if multicast [1st octet is FF] - if ((mc_addr_hdr & 0xFF000000) == 0xFF000000) { - // packet type according to the scope of the multicast packet - // we don't consider RPT bits in second octet [maybe done later if needed] - switch(mc_addr_hdr & 0x000F0000) { - case (0x00020000): - *paddr_type = NASRG_ADDR_MC_SIGNALLING; - #ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: multicast packet - signalling \n"); - #endif - break; - case (0x000E0000): - *paddr_type = NASRG_ADDR_MC_MBMS; - *pmbms_ix = 0; - cx=gpriv->cx; // MBMS associate to Mobile 0 - #ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: multicast packet - MBMS data \n"); - #endif - break; - default: - *paddr_type = NASRG_ADDR_UNKNOWN; - *pmbms_ix = NASRG_MBMS_SVCES_MAX; - } - // This is not multicast, so we should be able to identify the MT - }else{ - #ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: unicast packet\n"); - #endif - *paddr_type = NASRG_ADDR_UNICAST; - uni_ifid1 = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[2]); - uni_ifid2 = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[3]); - for (cxi=0; cxicx+cxi; - #ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_CLASS_cx6: Compared addresses \n"); - printk(" Daddr[2] %ul, Daddr[3] %ul\n", - ipv6_hdr(skb)->daddr.in6_u.u6_addr32[2],ipv6_hdr(skb)->daddr.in6_u.u6_addr32[3]); - printk(" ntohl Daddr[2] %ul, Daddr[3] %ul\n",uni_ifid1,uni_ifid2); - printk(" IIF[0] %ul, IIF[1] %ul\n",cx->iid6[0],cx->iid6[1]); - printk(" htonl IIF[0] %ul, IIF[1] %ul\n",htonl(cx->iid6[0]),htonl(cx->iid6[1])); - #endif - if (((cx->iid6[0] == uni_ifid1)&&(cx->iid6[1] == uni_ifid2)) - || ((htonl(cx->iid6[0]) == uni_ifid1)&&(htonl(cx->iid6[1]) == uni_ifid2))){ - return cx; - } - } - } - return cx; -}*/ - -//--------------------------------------------------------------------------- -// Search the entity with the IPv6 address 'addr' -// Navid: the ipv6 classifier is not fully tested -struct cx_entity *nasrg_CLASS_cx6(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index, int* pmbms_ix) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; - struct cx_entity *cx = NULL; - struct classifier_entity *sclassifier= NULL; - uint32_t mc_addr_hdr; - struct in6_addr masked_addr; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: begin\n"); -#endif - - if (skb) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: SOURCE ADDR %X:%X:%X:%X:%X:%X:%X:%X",NIP6ADDR(&(ipv6_hdr(skb)->saddr))); - printk(" DEST ADDR %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&(ipv6_hdr(skb)->daddr))); -#endif - mc_addr_hdr = ntohl(ipv6_hdr(skb)->daddr.in6_u.u6_addr32[0]); - - // First check if multicast [1st octet is FF] - if ((mc_addr_hdr & 0xFF000000) == 0xFF000000) { - // packet type according to the scope of the multicast packet - // we don't consider RPT bits in second octet [maybe done later if needed] - switch(mc_addr_hdr & 0x000F0000) { - case (0x00020000): - *paddr_type = NAS_IPV6_ADDR_MC_SIGNALLING; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: multicast packet - signalling \n"); -#endif - break; - - case (0x000E0000): - *paddr_type = NAS_IPV6_ADDR_MC_MBMS; - *pmbms_ix = 0; - cx=gpriv->cx; // MBMS associate to Mobile 0 -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: multicast packet - MBMS data \n"); -#endif - break; - - default: - printk("nasrg_CLASS_cx6: default multicast\n"); - *paddr_type = NAS_IPV6_ADDR_UNKNOWN; - *pmbms_ix = NASRG_MBMS_SVCES_MAX; - } - } else { - // This is not multicast, so we should be able to identify the MT - *paddr_type = NAS_IPV6_ADDR_UNICAST; - - for (cxi=*cx_index; cxicx[cxi].sclassifier[dscp]; - - while (sclassifier!=NULL) { - // verify that this is an IPv6 classifier - if ((sclassifier->version == NAS_VERSION_6) || (sclassifier->version == NAS_VERSION_DEFAULT)) { - /*LGif (IN6_IS_ADDR_UNSPECIFIED(&(sclassifier->daddr.ipv6))) { - printk("nas_CLASS_cx6: addr is null \n"); - sclassifier = sclassifier->next; - continue; - }*/ -#ifdef NAS_DEBUG_CLASS - printk("cx %d : DSCP %d %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, dscp, NIP6ADDR(&(sclassifier->daddr.ipv6))); -#endif //NAS_DEBUG_CLASS - - //if ((dst = (unsigned int*)&(((struct rt6_info *)skbdst)->rt6i_gateway)) == 0){ - // LG: STRANGE - if (IN6_IS_ADDR_UNSPECIFIED(&ipv6_hdr(skb)->daddr)) { - printk("nasrg_CLASS_cx6: dst addr is null \n"); - sclassifier = sclassifier->next; - continue; - } - - nasrg_create_mask_ipv6_addr(&masked_addr, sclassifier->dplen); - // Modified MW to check only the iid6 - masked_addr.s6_addr32[0] = 0x00000000; - masked_addr.s6_addr32[1] = 0x00000000; - - if (IN6_ARE_ADDR_MASKED_EQUAL(&ipv6_hdr(skb)->daddr, &(sclassifier->daddr.ipv6), &masked_addr)) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_cx6: found cx %d: %X:%X:%X:%X:%X:%X:%X:%X\n",cxi, NIP6ADDR(&(sclassifier->daddr.ipv6))); -#endif //NAS_DEBUG_CLASS - return &gpriv->cx[cxi]; - } - } - - // Go to next classifier entry for connection - sclassifier = sclassifier->next; - } - } - } - } - - //printk("nas_CLASS_cx6 NOT FOUND: %X:%X:%X:%X:%X:%X:%X:%X\n",NIP6ADDR(&ipv6_hdr(skb)->daddr)); - return cx; -} - -//--------------------------------------------------------------------------- -// Search the sending function for IP Packet -void nasrg_CLASS_send(struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *pclassifier, *sp; - uint8_t *protocolh = NULL; - uint8_t version; - uint8_t protocol, dscp; - uint16_t classref; - struct cx_entity *cx; - unsigned int i; -#ifdef NAS_DEBUG_CLASS - char sfct[10], sprotocol[10]; -#endif - struct net_device *dev = gdev; - unsigned char cx_index,no_connection; - int addr_type; - int mbms_ix; - struct in6_addr masked6_addr; - struct in_addr masked_addr; - // RARP vars - struct arphdr *rarp; - unsigned char *rarp_ptr; - /* s for "source", t for "target" */ - __be32 sip, tip; - unsigned char *sha, *tha; - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: begin -\n"); -#endif - - if (skb==NULL) { - printk("nasrg_CLASS_send - input parameter skb is NULL \n"); - return; - } - - //*** -#ifdef NAS_DEBUG_SEND - printk("nasrg_CLASS_send - Received IP packet to transmit, length %d\n", skb->len); -#endif -#ifdef NAS_DEBUG_SEND_DETAIL - - if ((skb->data) != NULL) { - if (skb->len<150) - nasrg_TOOL_print_buffer(skb->data,skb->len); - else - nasrg_TOOL_print_buffer(skb->data,150); - } - -#endif - //*** - // find all connections related to socket - cx_index = 0; - no_connection = 1; - cx = NULL; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: [before switch on IP protocol version] \n"); -#endif - - - // Get mobile connexion entity, protocol and dscp from IP packet - switch (ntohs(skb->protocol)) { - case ETH_P_IPV6: -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send : skb->protocol : IPv6 \n"); -#endif - version = NAS_VERSION_6; - addr_type = NAS_IPV6_ADDR_UNKNOWN; - protocolh = nasrg_TOOL_get_protocol6(ipv6_hdr(skb), &protocol); - dscp = nasrg_TOOL_get_dscp6 (ipv6_hdr(skb)); - cx = nasrg_CLASS_cx6 (skb, dscp, &addr_type, &cx_index, &mbms_ix); -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send - ETH_P_IPV6 skb %p dscp %d gpriv %p cx_index %p \n",skb, dscp, gpriv, &cx_index); -#endif - - // find in default DSCP a valid classification - if (cx == NULL) { - switch (addr_type) { - case NAS_IPV6_ADDR_MC_SIGNALLING: - case NAS_IPV6_ADDR_UNICAST: -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send - case NAS_IPV6_ADDR_MC_SIGNALLING | NAS_IPV6_ADDR_UNICAST\n"); -#endif //NAS_DEBUG_CLASS - - for (i=0; icx[i])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier!=NULL) { - if ((pclassifier->version == NAS_VERSION_6) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasrg_create_mask_ipv6_addr(&masked6_addr, pclassifier->dplen); - // Modified MW to let everything go (pb with signalling) - masked6_addr.s6_addr32[0] = 0x00000000; - masked6_addr.s6_addr32[1] = 0x00000000; -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send - cx %d : DSCP NAS_DSCP_DEFAULT %X:%X:%X:%X:%X:%X:%X:%X\n",i, NIP6ADDR(&(pclassifier->daddr.ipv6))); -#endif //NAS_DEBUG_CLASS - - if (IN6_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv6, &ipv6_hdr(skb)->daddr, &masked6_addr)) { - // then force dscp - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if(IN6_IS_ADDR_UNSPECIFIED(&pclassifier->daddr.ipv6)) { - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_IS_ADDR_UNSPECIFIED\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - } - - break; - - // MBMS is broken!!!! To be updated (these values will be over-ridden afterwards - case NAS_IPV6_ADDR_MC_MBMS: -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send - case NAS_IPV6_ADDR_MC_MBMS\n"); -#endif //NAS_DEBUG_CLASS - pclassifier = gpriv->mbmsclassifier[mbms_ix]; - printk("nasrg_CLASS_send: MBMS is broken!!!!\n\n\n"); - sp = gpriv->mbmsclassifier[mbms_ix]; - - if (sp!= NULL) { - classref=sp->classref; -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: classifier found for multicast service %d \n", mbms_ix); -#endif - } else { - printk("nasrg_CLASS_send: No corresponding multicast bearer, so the message is dropped\n"); - return; - } - - break; - - // should have found a valid classification rule - case NAS_IPV6_ADDR_UNKNOWN: - default: - printk("nasrg_CLASS_send: No corresponding address type\n"); - } - } - - break; - - case ETH_P_ARP: -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send : skb->protocol : ARP \n"); -#endif - version = NAS_VERSION_4; - addr_type = NAS_IPV4_ADDR_BROADCAST; - dscp = 0; - cx = NULL; - // Basic sanity checks can be done without the lock - rarp = (struct arphdr *)skb_network_header(skb); - - if (rarp) { - if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) { - printk("nasrg_CLASS_send: ARP PACKET WRONG ADDR LEN or WRONG ARP HEADER TYPE\n"); - break; - } - } else { - printk("nasrg_CLASS_send: ARP HEADER POINTER IS NULL\n"); - break; - } - - // If it's not Ethernet, delete it. - if (rarp->ar_pro != htons(ETH_P_IP)) { - printk("nasrg_CLASS_send: ARP PACKET PROTOCOL IS NOT ETHERNET\n"); - break; - } - - rarp_ptr = (unsigned char *) (rarp + 1); - sha = rarp_ptr; - rarp_ptr += dev->addr_len; - memcpy(&sip, rarp_ptr, 4); - rarp_ptr += 4; - tha = rarp_ptr; - rarp_ptr += dev->addr_len; - memcpy(&tip, rarp_ptr, 4); -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: ARP DEST IP transport IP = %d.%d.%d.%d\n",NIPADDR(tip)); -#endif - - for (i=0; icx[i])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier!=NULL) { - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasrg_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: MASK = %d.%d.%d.%d\n",NIPADDR(masked_addr.s_addr)); -#endif - - // - if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &tip, &masked_addr.s_addr)) { - // then force dscp - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n", pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if (INADDR_ANY == pclassifier->daddr.ipv4) { - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - } - - break; - - case ETH_P_IP: -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send : skb->protocol : IPv4 \n"); -#endif - version = NAS_VERSION_4; - addr_type = NAS_IPV4_ADDR_UNKNOWN; - dscp = nasrg_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb))); - cx = nasrg_CLASS_cx4(skb, dscp, &addr_type, &cx_index); - protocolh = nasrg_TOOL_get_protocol4((struct iphdr *)(skb_network_header(skb)), &protocol); - - // find in default DSCP a valid classification - if (cx == NULL) { - switch (addr_type) { - case NAS_IPV4_ADDR_MC_SIGNALLING: - case NAS_IPV4_ADDR_UNICAST: - case NAS_IPV4_ADDR_BROADCAST: - for (i=0; icx[i])->sclassifier[NAS_DSCP_DEFAULT]; - - while (pclassifier != NULL) { - if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - // ok found default classifier for this packet - nasrg_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send : MASK = %d.%d.%d.%d\n", NIPADDR(masked_addr.s_addr)); -#endif - - if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &ip_hdr(skb)->daddr, &masked_addr.s_addr)) { - // then force dscp - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } else { - if(INADDR_ANY == pclassifier->daddr.ipv4) { - cx = &gpriv->cx[i]; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); -#endif - dscp = NAS_DSCP_DEFAULT; - break; - } - } - } - - pclassifier = pclassifier->next; - } - } - - break; - - // should have found a valid classification rule - case NAS_IPV4_ADDR_UNKNOWN: - default: - printk("nasrg_CLASS_send: No corresponding address type\n"); - } - } - -#ifdef NAS_DEBUG_CLASS - - if (cx) - printk("nasrg_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %d\n",ntohs(skb->protocol),dscp,cx->lcr); - else - printk("nasrg_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, No valid connection\n",ntohs(skb->protocol),dscp); - -#endif - break; - - default: - printk("nasrg_CLASS_send: Unknown IP version protocol\n"); - version = 0; - return; - } - -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: [before if (cx != NULL)]\n"); -#endif - - //Next lines bypass classifiers to test the netlink socket - //#define DEBUG_NETLINKRG_TEST -#ifdef DEBUG_NETLINKRG_TEST - nasrg_COMMON_QOS_send_test_netlink(skb); - return; -#endif - - // If a valid connection for the DSCP/EXP with destination address - // is found scan all protocol-based classification rules - if (cx != NULL) { - classref = 0; - sp = NULL; - - if (cx->state!=NAS_CX_DCH) { -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: UE not connected, in state %d. Packet is dropped\n",cx->state); -#endif - return; - } - - if (addr_type==NAS_IPV6_ADDR_MC_MBMS) { - sp = gpriv->mbmsclassifier[mbms_ix]; - - if (sp!= NULL) { - classref=sp->classref; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: classifier found for multicast index %d, service %d\n", mbms_ix, gpriv->mbms_rb[mbms_ix].cnxid); -#endif - } else { - // Temp MEDIEVAL : use default classifier - sp = cx->sclassifier[NAS_DSCP_DEFAULT]; - - if (sp!= NULL) { - classref=sp->classref; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_CLASS_send: classifier for multicast service %d replaced by default %d\n", mbms_ix, classref); -#endif -#ifdef NAS_AUTO_MBMS - nasrg_ASCTL_start_default_mbms_service(); -#endif - } else { - printk("nasrg_CLASS_send: No corresponding multicast bearer, so the message is dropped\n"); - return; - } - } - } else { -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: DSCP %d version %d: looking for classifier entry\n",dscp, version); -#endif - - for (pclassifier=cx->sclassifier[dscp]; pclassifier!=NULL; pclassifier=pclassifier->next) { -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,pclassifier->classref,pclassifier->protocol,pclassifier->version); -#endif - - // normal rule checks that network protocol version matches - if ((pclassifier->version == version) || (pclassifier->version == NAS_VERSION_DEFAULT)) { - //printk("nasrg_CLASS_send: IP version are equals\n"); - sp=pclassifier; - classref=sp->classref; -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: classifier found for dscp %u \n", dscp); -#endif - break; - } - } - } - - if (sp!=NULL) { -#ifdef NAS_DEBUG_CLASS - - //char sfct[10], sprotocol[10]; - // classifier entity found. Print its parameters - if (sp->fct==nasrg_COMMON_QOS_send) - strcpy(sfct, "data xfer"); - - if (sp->fct==nasrg_CTL_send) - strcpy(sfct, "iocontrol"); - - if (sp->fct==nasrg_COMMON_del_send) - strcpy(sfct, "delete"); - - if (sp->fct==nasrg_ASCTL_DC_send_sig_data_request) - strcpy(sfct, "DC-SAP"); - - switch(protocol) { - case NAS_PROTOCOL_UDP: - strcpy(sprotocol, "udp"); - printk("udp packet\n"); - break; - - case NAS_PROTOCOL_TCP: - strcpy(sprotocol, "tcp"); - printk("tcp packet\n"); - break; - - case NAS_PROTOCOL_ICMP4: - strcpy(sprotocol, "icmp4"); - printk("icmp4 packet\n"); - break; - - case NAS_PROTOCOL_ICMP6: - strcpy(sprotocol, "icmp6"); - nasrg_TOOL_pk_icmp6((struct icmp6hdr*)protocolh); - break; - - default: - strcpy(sprotocol, "other L4"); - break; - } - - printk("nasrg_CLASS_send: (dscp %u, %s) received, (classref %u, fct %s, drb_id %u) classifier rule\n", - dscp, sprotocol, sp->classref, sfct, sp->rab_id); -#endif - - //forward packet to the correct entity - if (sp->fct!=NULL) { - sp->fct(skb, cx, sp); - } else { - printk("\n\nnasrg_CLASS_send: ERROR : CLASSIFIER FUNCTION IS NULL\n\n"); - } - - no_connection = 0; - // end : if classifier entry match found - } else { - printk("nasrg_CLASS_send: no corresponding item in the classifier list, so the message is dropped\n"); - printk("nasrg_CLASS_send: packet parameters: dscp %u, %s\n", dscp, sprotocol); - nasrg_COMMON_del_send(skb, cx, NULL); // Note MW: LG has commented this line. Why? - } - } // if connection found - -#ifdef NAS_DEBUG_CLASS - - if (no_connection == 1) { - printk("nasrg_CLASS_send: no corresponding connection, so the message is dropped\n"); - } - -#endif -#ifdef NAS_DEBUG_CLASS_DETAIL - printk("nasrg_CLASS_send: end\n"); -#endif -} diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_common.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_common.c deleted file mode 100644 index 6bfd77a17d..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_common.c +++ /dev/null @@ -1,628 +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 nasrg_common.c -* \brief Common functions for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasrg_variables.h" -#include "nasrg_proto.h" - -#include -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif - -//--------------------------------------------------------------------------- -// Receive data from FIFO (QOS or DC) -//void nasrg_COMMON_receive(uint16_t hlen, uint16_t dlen, int sap){ -void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap) -{ - //--------------------------------------------------------------------------- - struct sk_buff *skb; - struct ipversion *ipv; - unsigned int hard_header_len; - uint16_t *p_ether_type; - uint16_t ether_type; - -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: begin\n"); -#endif -#ifdef PDCP_USE_NETLINK - - // data_buffer is NULL if FIFOs - if (!data_buffer) { - printk("nasrg_COMMON_receive - input parameter data_buffer is NULL \n"); - return; - } - -#endif - - skb = dev_alloc_skb( payload_length + 2 ); - - if(!skb) { - printk("nasrg_COMMON_receive: low on memory\n"); - ++gpriv->stats.rx_dropped; - return; - } - - skb_reserve(skb,2); - -#ifndef PDCP_USE_NETLINK - bytes_read += rtf_get(sap, skb_put(skb, payload_length), payload_length); - - if (bytes_read != NAS_PDCPH_SIZE + payload_length) { - printk("nasrg_COMMON_receive: problem while reading rtf sap\n"); - kfree(skb->data); - dev_kfree_skb(skb); - return; - } - -#else - memcpy(skb_put(skb, payload_length), data_buffer, payload_length); - bytes_read += payload_length; -#endif - -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: received packet from PDCP, length %d\n", bytes_read); -#endif - - skb->dev = gdev; - hard_header_len = gdev->hard_header_len; - skb->mac_header = skb->data; - skb->pkt_type = PACKET_HOST; - skb->ip_summed = CHECKSUM_UNNECESSARY; - - ipv = (struct ipversion *)&(skb->data[hard_header_len]); - - switch (ipv->version) { - case 6: -#ifdef NAS_DEBUG_RECEIVE_BASIC - printk("nasrg_COMMON_receive: receive IPv6 message\n"); -#endif - skb->network_header = &skb->data[hard_header_len]; - // set protocol default value - skb->protocol = htons(ETH_P_IPV6); - // If type Ethernet, correct it -#ifdef NAS_DRIVER_TYPE_ETHERNET - skb->protocol = eth_type_trans(skb, gdev); -#endif - break; - - case 4: -#ifdef NAS_DEBUG_RECEIVE_BASIC - printk("nasrg_COMMON_receive: receive IPv4 message\n"); -#endif - -#ifdef NAS_DEBUG_RECEIVE - addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->saddr; - - if (addr) { - printk("nasrg_COMMON_receive: Source %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]); - } - - addr = (unsigned char *)&((struct iphdr *)&skb->data[hard_header_len])->daddr; - - if (addr) { - printk("nasrg_COMMON_receive Dest %d.%d.%d.%d\n",addr[0],addr[1],addr[2],addr[3]); - } - - printk("nasrg_COMMON_receive protocol %d\n",((struct iphdr *)&skb->data[hard_header_len])->protocol); -#endif - - skb->network_header = &skb->data[hard_header_len]; - // set protocol default value - skb->protocol = htons(ETH_P_IP); - // If type Ethernet, correct it -#ifdef NAS_DRIVER_TYPE_ETHERNET - skb->protocol = eth_type_trans(skb, gdev); -#endif - break; - - default: - printk("nasrg_COMMON_receive: Packet is not IPv4 or IPv6 (version=%d)\n", ipv->version); - -#ifdef NAS_DRIVER_TYPE_ETHERNET -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: ether_type=%04X\n", ether_type); -#endif - skb->protocol = eth_type_trans(skb, gdev); - // minus 1(short) instead of 2(bytes) because uint16_t* - p_ether_type = (uint16_t *)&(skb->mac_header[hard_header_len-2]); - ether_type = ntohs(*p_ether_type); -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: ether_type=%04X\n", ether_type); -#endif - - switch (ether_type) { - case ETH_P_ARP: - printk("nasrg_COMMON_receive: ether_type = ETH_P_ARP\n"); - skb->protocol = htons(ETH_P_ARP); - skb->network_header = &skb->mac_header[hard_header_len]; - break; - - default: - break; - } - -#endif - } - - ++gpriv->stats.rx_packets; - gpriv->stats.rx_bytes += bytes_read; -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: forwarding packet of size %d to kernel\n",skb->len); -#endif - - netif_rx(skb); -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_receive: end\n"); -#endif -} - -//--------------------------------------------------------------------------- -// Delete the data -void nasrg_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp) -{ - //--------------------------------------------------------------------------- - ++gpriv->stats.tx_dropped; -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (QoS SAP) -void nasrg_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - struct pdcp_data_req_header_t pdcph; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send - begin \n"); -#endif - - // if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR - // { - // gpriv->stats.tx_dropped ++; - // printk("NAS_QOS_SEND: No connected, so message are dropped \n"); - // return; - // } - if (!skb || !gc || !cx) { - printk("nasrg_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n"); - return; - } - - // End debug information - - if (gc->rb==NULL) { - gc->rb=nasrg_COMMON_search_rb(cx, gc->rab_id); - - if (gc->rb==NULL) { - ++gpriv->stats.tx_dropped; - printk("nasrg_COMMON_QOS_send: No corresponding Radio Bearer, so message is dropped, rab_id=%u \n", gc->rab_id); - return; - } - } - -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send #1 :"); - printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id); -#endif -#ifdef NAS_DEBUG_SEND_DETAIL - nasrg_TOOL_print_classifier(gc); -#endif - pdcph.data_size = skb->len; - //pdcph.rb_id = (gc->rb)->rab_id+(NAS_RB_MAX_NUM*cx->lcr); - pdcph.rb_id = ((gc->rb)->rab_id)-NAS_SIG_NUM_SRB; - pdcph.inst = 0; - -#ifdef PDCP_USE_NETLINK - bytes_wrote = nasrg_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len); -#endif -#else - //bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE); - bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len); -#endif -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != NAS_PDCPH_SIZE) { - printk("nasrg_COMMON_QOS_send: problem while writing PDCP's header\n"); - printk("PDCP rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_COMMON_QOS_send #2 :"); - printk("Header bytes written : %d\n", bytes_wrote); -#endif - -#ifdef PDCP_USE_NETLINK - bytes_wrote += nasrg_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP); -#else - //bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len); - bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len); -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) { - printk("nasrg_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion - printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send #3 :"); - printk(" %d bytes written to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id, NAS2PDCP_FIFO); -#endif - gpriv->stats.tx_bytes += skb->len; - gpriv->stats.tx_packets ++; -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_COMMON_QOS_send - end \n"); -#endif -} - -//--------------------------------------------------------------------------- -// Request the transfer of data (QoS SAP) -void nasrg_COMMON_QOS_send_test_netlink(struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct pdcp_data_req_header_t pdcph; - int bytes_wrote = 0; - - // Start debug information -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send - begin \n"); -#endif - - // if (cx->state!=NAS_STATE_CONNECTED) // <--- A REVOIR - // { - // gpriv->stats.tx_dropped ++; - // printk("NAS_QOS_SEND: No connected, so message are dropped \n"); - // return; - // } - if (!skb ) { - printk("nasrg_COMMON_QOS_send - input parameter skb|gc|cx is NULL \n"); - return; - } - - // End debug information - -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send #1 :"); - // printk("lcr %u, rab_id %u, rab_id %u\n", cx->lcr, (gc->rb)->rab_id, gc->rab_id); - // nasrg_TOOL_print_classifier(gc); -#endif - pdcph.data_size = skb->len; - //pdcph.rb_id = (gc->rb)->rab_id+(NAS_RB_MAX_NUM*cx->lcr); - pdcph.rb_id = 6; - pdcph.inst = 0; - -#ifdef PDCP_USE_NETLINK - bytes_wrote = nasrg_netlink_send((unsigned char *)&pdcph,NAS_PDCPH_SIZE, NASNL_DEST_PDCP); - //printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP via netlink\n", bytes_wrote,skb->len); -#else - //bytes_wrote = rtf_put(gpriv->sap[(gc->rb)->sapi], &pdcph, NAS_PDCPH_SIZE); - bytes_wrote = rtf_put(NAS2PDCP_FIFO, &pdcph, NAS_PDCPH_SIZE); - //printk("nasrg_COMMON_QOS_send - Wrote %d bytes (header for %d byte skb) to PDCP fifo\n", bytes_wrote,skb->len); -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != NAS_PDCPH_SIZE) { - printk("nasrg_COMMON_QOS_send: problem while writing PDCP's header\n"); - // printk("PDCP rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send #2 :"); - printk("Header bytes wrote : %d\n", bytes_wrote); -#endif - -#ifdef PDCP_USE_NETLINK - bytes_wrote += nasrg_netlink_send((unsigned char *)skb->data,skb->len, NASNL_DEST_PDCP); -#else - //bytes_wrote += rtf_put(gpriv->sap[(gc->rb)->sapi], skb->data, skb->len); - bytes_wrote += rtf_put(NAS2PDCP_FIFO, skb->data, skb->len); -#endif //PDCP_USE_NETLINK - - if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) { - printk("nasrg_COMMON_QOS_send: problem while writing PDCP's data\n"); // congestion - // printk("rb_id %d, SAP index %d, Wrote %d to fifo %d, Header Size %d \n", pdcph.rb_id , (gc->rb)->sapi, bytes_wrote, NAS2PDCP_FIFO, NAS_PDCPH_SIZE); - gpriv->stats.tx_dropped ++; - return; - } - -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send #3 :"); - printk(" %d bytes wrote to rb_id %d, sap %d \n", bytes_wrote, pdcph.rb_id, NAS2PDCP_FIFO); -#endif - gpriv->stats.tx_bytes += skb->len; - gpriv->stats.tx_packets ++; -#ifdef NAS_DEBUG_SEND - printk("nasrg_COMMON_QOS_send - end \n"); -#endif -} - -#ifndef PDCP_USE_NETLINK -//--------------------------------------------------------------------------- -void nasrg_COMMON_QOS_receive(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - uint8_t sapi; - struct pdcp_data_ind_header_t pdcph; - int bytes_read = 0; - // Start debug information -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_QOS_receive - begin \n"); -#endif - - if (!cx) { - printk("nasrg_COMMON_QOS_receive - input parameter cx is NULL \n"); - return; - } - - // End debug information - - // LG force the use of only 1 rt fifo - sapi = NAS_DRB_OUTPUT_SAPI; - - bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE); - - while (bytes_read>0) { - if (bytes_read != NAS_PDCPH_SIZE) { - printk("nasrg_COMMON_QOS_receive: problem while reading PDCP header\n"); - return; - } - - // data_buffer is NULL because FIFO should be read directly in the skbuff (LITE has an intermediary buffer) - nasrg_COMMON_receive(NAS_PDCPH_SIZE, pdcph.data_size, NULL, pdcph->rb_id, gpriv->sap[sapi]); - // check if another frame is in the FIFO, otherwise return - bytes_read = rtf_get(gpriv->sap[sapi], &pdcph, NAS_PDCPH_SIZE); - } - -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_QOS_receive - end \n"); -#endif -} -#else -//--------------------------------------------------------------------------- -void nasrg_COMMON_QOS_receive(struct nlmsghdr *nlh) -{ - //--------------------------------------------------------------------------- - - struct pdcp_data_ind_header_t *pdcph; - - // Start debug information -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_QOS_receive - begin \n"); -#endif - - if (!nlh) { - printk("nasrg_COMMON_QOS_receive - input parameter nlh is NULL \n"); - return; - } - - // End debug information - pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh); - -#ifdef NAS_DEBUG_RECEIVE - printk("nasrg_COMMON_QOS_receive - receive from PDCP, size %d, rab %d\\n", pdcph->data_size, pdcph->rb_id); -#endif //NAS_DEBUG_RECEIVE - - //void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - nasrg_COMMON_receive(NAS_PDCPH_SIZE + pdcph->data_size, pdcph->data_size, (unsigned char *)NLMSG_DATA(nlh) + NAS_PDCPH_SIZE, pdcph->rb_id, 0); -} -#endif //PDCP_USE_NETLINK - -//--------------------------------------------------------------------------- -struct cx_entity *nasrg_COMMON_search_cx(nasLocalConnectionRef_t lcr) -{ - //--------------------------------------------------------------------------- -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_search_cx - lcr %d\n",lcr); -#endif - - if (lcrcx+lcr; - else - return NULL; -} - -//--------------------------------------------------------------------------- -// Search a Radio Bearer -struct rb_entity *nasrg_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_search_rb - rab_id %d\n", rab_id); -#endif - - if (cx==NULL) { - printk("nasrg_COMMON_search_rb - input parameter cx is NULL \n"); - return NULL; - } - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->rab_id==rab_id) - return rb; - } - - return NULL; -} - -//--------------------------------------------------------------------------- -struct rb_entity *nasrg_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasQoSTrafficClass_t qos) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_add_rb - begin for rab_id %d , qos %d\n", rab_id, qos ); -#endif - - if (cx==NULL) { - printk("nasrg_COMMON_add_rb - input parameter cx is NULL \n"); - return NULL; - } - - rb=nasrg_COMMON_search_rb(cx, rab_id); - - if (rb==NULL) { - rb=(struct rb_entity *)kmalloc(sizeof(struct rb_entity), GFP_KERNEL); - - if (rb!=NULL) { - rb->retry=0; - rb->countimer=NAS_TIMER_IDLE; - rb->rab_id=rab_id; - // rb->rab_id=rab_id+(32*cx->lcr); -#ifdef NAS_DEBUG_DC - printk("nasrg_COMMON_add_rb: rb rab_id=%u, rab_id=%u, mt_id=%u\n",rb->rab_id,rab_id, cx->lcr); -#endif - // rb->dscp = NASRG_TEMP_2NDRAB_DSCP; //TEMP - rb->qos=qos; - rb->sapi=NAS_DRB_INPUT_SAPI; - // LG force the use of only one rt-fifo - // rb->sapi=NAS_BA_INPUT_SAPI; - rb->state=NAS_IDLE; - rb->next=cx->rb; - cx->rb=rb; - (cx->num_rb)++; - } else - printk("nasrg_COMMON_add_rb: no memory\n"); - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_add_rb - end \n" ); -#endif - return rb; -} - -//--------------------------------------------------------------------------- -// free the memory that has previously been allocated to rb and remove from linked list -void nasrg_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb, *curr_rb, *prev_rb; - struct classifier_entity *p; - uint16_t classref=0; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_del_rb - begin\n"); -#endif - - if (cx==NULL) { - printk("nasrg_COMMON_del_rb - input parameter cx is NULL \n"); - return; - } - - // End debug information - - // Clear the associated classifier - for (p=cx->sclassifier[dscp]; p!=NULL; p=p->next) { - if (p->classref>=classref) { - classref=p->classref; -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_del_rb: classifier found for dscp %u \n", dscp); -#endif - } - } - - nasrg_CLASS_del_sclassifier(cx, dscp, classref); - - // Now, delete the RB - curr_rb = NULL; - prev_rb = NULL; - - for (rb=cx->rb; rb!=NULL; rb=rb->next) { - if (rb->rab_id == rab_id) { - curr_rb = rb; - - if (prev_rb!=NULL) { - prev_rb->next = rb->next; - } else { - cx->rb=rb->next; - } - - break; - } else { - prev_rb = rb; - } - } - - if (curr_rb!= NULL) { - printk("nasrg_COMMON_del_rb: del rab_id %u\n", rb->rab_id); - kfree(rb); - (cx->num_rb)--; - } else { - printk("\n\n--nasrg_COMMON_del_rb: ERROR, invalid rab_id %u\n", rb->rab_id); - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_del_rb - end\n"); -#endif -} - -//--------------------------------------------------------------------------- -void nasrg_COMMON_flush_rb(struct cx_entity *cx) -{ - //--------------------------------------------------------------------------- - struct rb_entity *rb; - struct classifier_entity *gc; - uint8_t dscp; - - // Start debug information -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_flush_rb - begin\n"); -#endif - - if (cx==NULL) { - printk("nasrg_COMMON_flush_rb - input parameter cx is NULL \n"); - return; - } - - // End debug information - for (rb=cx->rb; rb!=NULL; rb=cx->rb) { - printk("nasrg_COMMON_flush_rb: del rab_id %u\n", rb->rab_id); - cx->rb=rb->next; - kfree(rb); - } - - cx->num_rb=0; - cx->rb=NULL; - - for(dscp=0; dscpsclassifier[dscp]; gc!=NULL; gc=gc->next) - gc->rb=NULL; - } - -#ifdef NAS_DEBUG_CLASS - printk("nasrg_COMMON_flush_rb - end\n"); -#endif -} diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_constant.h b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_constant.h deleted file mode 100644 index 7a0e69cc48..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_constant.h +++ /dev/null @@ -1,220 +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 nasrg_constant.h -* \brief Defines all constants for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASRGD_CST -#define _NASRGD_CST - -//Debug flags -#define NAS_DEBUG_DC -//#define NAS_DEBUG_DC_DETAIL -#define NAS_DEBUG_SEND -//#define NAS_DEBUG_SEND_DETAIL // detail of packet transmission -//#define NAS_DEBUG_RECEIVE -#define NAS_DEBUG_RECEIVE_BASIC -#define NAS_DEBUG_CLASS -//#define NAS_DEBUG_CLASS_DETAIL -#define NAS_DEBUG_GC -//#define NAS_DEBUG_DC_MEASURE -//#define NAS_DEBUG_TIMER -#define NAS_DEBUG_DEVICE -//#define NAS_DEBUG_INTERRUPT -//#define NAS_DEBUG_TOOL -//#define NAS_DEBUG_MBMS_PROT //Only one RT-FIFO is used -#define NETLINK_DEBUG -#define NAS_DEBUG_RRCNL // RRC netlink socket - -// Other flags -#define DEMO_3GSM -//#define NODE_RG -//#define NAS_AUTO_MBMS - -// Begin default RAB -// Parameters for the default RAB started after network attachment (needs DEMO_3GSM defined) -// RBId value to be synchronized with RAL-RG -#define NASRG_DEFAULTRAB_RBID 6 //MW-01/01/07- RBID 5 => MBMS, 6 => DEFAULTRAB, 7+ => others -// Only one of next lines must be active - other values in l3/rrc/rrc_qos.h -#define NASRG_DEFAULTRAB_QoS 2 //MW-01/01/07- RRC_QOS_CONV_64_64 -//#define NASRG_DEFAULTRAB_QoS 3 //MW-01/01/07- RRC_QOS_CONV_128_128 -//#define NASRG_DEFAULTRAB_QoS 4 //MW-01/01/07- RRC_QOS_CONV_256_256 -//#define NASRG_DEFAULTRAB_QoS 5 //MW-01/01/07- RRC_QOS_CONV_320_320 -//#define NASRG_DEFAULTRAB_QoS 11 //LG RRC_QOS_INTER_128_64 -// -#define NASRG_DEFAULTRAB_CLASSREF 1 //MW-01/01/07 -#define NASRG_DEFAULTRAB_DSCP 0 //MW-01/01/07 -#define NASRG_DEFAULTRAB_IPVERSION NAS_VERSION_DEFAULT //MW-01/01/07 -// End default RAB - -//Temp - hard coded -#define NASRG_OWN_CELLID 5 -#define NASRG_TEMP_2NDRAB_DSCP 5 -#define NASRG_TEMP_MBMS_SESSION_ID 1 -#define NASRG_TEMP_MBMS_DURATION 999 -#define NAS_DEFAULT_IPv6_PREFIX_LENGTH 128 // used to compare destination address with MT's - -// General Constants -#define NAS_MTU 1500 -#define NAS_TX_QUEUE_LEN 100 -#define NAS_ADDR_LEN 8 -#define NAS_INET6_ADDRSTRLEN 46 -#define NAS_INET_ADDRSTRLEN 16 - -#define NAS_RESET_RX_FLAGS 0 - -#define NAS_CX_MAX 3 //Identical to RRC constant -//#define NAS_CX_MULTICAST_ALLNODE 2 - -#define NASRG_MBMS_SVCES_MAX 4 // Identical to RRC constant - -#define NAS_RB_MAX_NUM 32 // maximum number of RBs per MT - 25.331 -#define NAS_RETRY_LIMIT_DEFAULT 5 - -#define NAS_MESSAGE_MAXLEN 1600 - -// UMTS -#define NAS_SIG_SRB3 3 -#define NAS_SIG_SRB4 3 // not used yet -//LTE -#define NAS_SIG_NUM_SRB 3 // number of srbs in LTE to send Rb_Id to PDCP - - -//peer-to-peer messages between NAS entities -#define NAS_CMD_OPEN_RB 1 -#define NAS_CMD_ENTER_SLEEP 2 -#define NAS_CMD_LEAVE_SLEEP 3 - -#define NAS_CX_RELEASE_UNDEF_CAUSE 1 - -// MT+RG NAS States -#define NAS_IDLE 0x01 -// Connection -#define NAS_CX_FACH 0x06 -#define NAS_CX_DCH 0x0A -#define NAS_CX_RECEIVED 0x10 -#define NAS_CX_CONNECTING 0x04 -#define NAS_CX_RELEASING 0x08 -#define NAS_CX_CONNECTING_FAILURE 0x14 -#define NAS_CX_RELEASING_FAILURE 0x18 -// Radio Bearers -#define NAS_RB_ESTABLISHING 0x24 -#define NAS_RB_RELEASING 0x28 -#define NAS_RB_ESTABLISHED 0x2A - - -#define NAS_TIMER_ESTABLISHMENT_DEFAULT 12 -#define NAS_TIMER_RELEASE_DEFAULT 2 -#define NAS_TIMER_IDLE UINT_MAX -#define NAS_TIMER_TICK HZ - -#define NAS_PDCPH_SIZE sizeof(struct pdcp_data_req_header_t) -#define NAS_IPV4_SIZE 20 -#define NAS_IPV6_SIZE 40 - -#define NAS_DIRECTION_SEND 0 -#define NAS_DIRECTION_RECEIVE 1 - -// function number -#define NAS_FCT_DEL_SEND 1 -#define NAS_FCT_QOS_SEND 2 -#define NAS_FCT_DC_SEND 3 -#define NAS_FCT_CTL_SEND 4 - -// type of IOCTL command -#define NASRG_IOCTL_RAL 0x89F0 - -// Error cause -#define NAS_ERROR_ALREADYEXIST 1 -#define NAS_ERROR_NOMEMORY 3 -#define NAS_ERROR_NOTMT 9 -#define NAS_ERROR_NOTRG 10 -#define NAS_ERROR_NOTIDLE 11 -#define NAS_ERROR_NOTCONNECTED 12 -#define NAS_ERROR_NORB 14 -#define NAS_ERROR_NOTCORRECTVALUE 32 -#define NAS_ERROR_NOTCORRECTLCR 33 -#define NAS_ERROR_NOTCORRECTDIR 34 -#define NAS_ERROR_NOTCORRECTDSCP 35 -#define NAS_ERROR_NOTCORRECTVERSION 36 -#define NAS_ERROR_NOTCORRECTRABI 37 - - -/**********************************************************/ -/* Constants related with IP protocols */ -/**********************************************************/ - -// Destination address types -#define NAS_IPV6_ADDR_UNICAST 1 -#define NAS_IPV6_ADDR_MC_SIGNALLING 2 -#define NAS_IPV6_ADDR_MC_MBMS 3 -#define NAS_IPV6_ADDR_UNKNOWN 4 - -#define NAS_IPV4_ADDR_UNICAST 5 -#define NAS_IPV4_ADDR_MC_SIGNALLING 6 -#define NAS_IPV4_ADDR_BROADCAST 7 -#define NAS_IPV4_ADDR_UNKNOWN 8 - -//#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0fc00000) Yan -#define NAS_TRAFFICCLASS_MASK __constant_htonl(0x0ff00000) - -// Network control codepoint 111000 + IP version 6 -#define NAS_FLOWINFO_NCONTROL __constant_htonl(0x6e000000) -// network control codepoint 111000 -#define NAS_DSCP_NCONTROL 56 //0x38 -// default codepoint 1000000 -#define NAS_DSCP_DEFAULT 64 -#define NAS_DSCP_MAX 65 - -#define NAS_PROTOCOL_DEFAULT 0 -#define NAS_PROTOCOL_TCP IPPROTO_TCP -#define NAS_PROTOCOL_UDP IPPROTO_UDP -#define NAS_PROTOCOL_ICMP4 IPPROTO_ICMP -#define NAS_PROTOCOL_ICMP6 IPPROTO_ICMPV6 - -#define NAS_PORT_DEFAULT __constant_htons(65535) -#define NAS_PORT_HTTP __constant_htons(80) - -#define NAS_VERSION_DEFAULT 0 -#define NAS_VERSION_4 4 -#define NAS_VERSION_6 6 //?MW - -/**********************************************************/ -/* Constants related with Netlink sockets */ -/**********************************************************/ -#define OAI_IP_DRIVER_NETLINK_ID 31 -#define NL_DEST_PID 1 - -// defined in rrc_nas_sap.h -//#define NAS_RRCNL_ID 30 -//#define NL_DEST_RRC_PID 2 - -#define NASNL_DEST_PDCP 0 -#define NASNL_DEST_RRC 1 - -#endif - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c deleted file mode 100644 index 8fe2d48e3f..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c +++ /dev/null @@ -1,549 +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 nasmt_device.c -* \brief Networking Device Driver for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef PDCP_USE_NETLINK -#ifdef RTAI -#include "rtai_posix.h" -#define RTAI_IRQ 30 //try to get this irq with RTAI -#endif // RTAI -#endif // PDCP_USE_NETLINK -//:::::::::::::::::::::::::::::::::::::::;; -#include "nasrg_variables.h" -#include "nasrg_proto.h" -//:::::::::::::::::::::::::::::::::::::::;; -//#include -#include -#include -#include -#include -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef NAS_DRIVER_TYPE_ETHERNET -#include -#endif -//:::::::::::::::::::::::::::::::::::::::;; -/* Global variables */ -struct net_device *gdev; -struct nas_priv *gpriv; -//int bytes_wrote; -//int bytes_read; -uint8_t NAS_RG_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x01}; -uint8_t NAS_NULL_IMEI[14]= {0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00}; - -uint16_t local_rg_cell_id; - -#ifdef PDCP_USE_NETLINK -extern void nasrg_netlink_release(void); -extern int nasrg_netlink_init(void); -#endif -extern void nasrg_ASCTL_timer(unsigned long data); - -#ifndef PDCP_USE_NETLINK -//--------------------------------------------------------------------------- -void *nasrg_interrupt(void) -{ - //--------------------------------------------------------------------------- - uint8_t cxi; -#ifdef NAS_DEBUG_INTERRUPT - printk("nasrg_interrupt - begin\n"); -#endif - - //spin_lock(&gpriv->lock); - for (cxi=0; cxicx+cxi); - - for (cxi=0; cxicx+cxi); - - //spin_unlock(&gpriv->lock); -#ifdef NAS_DEBUG_INTERRUPT - printk("nasrg_interrupt: end\n"); -#endif - // return 0; -} -#endif //NETLINK - -//--------------------------------------------------------------------------- -// Called by ifconfig when the device is activated by ifconfig -int nasrg_open(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - printk("nasrg_open: begin\n"); - - gpriv=netdev_priv(dev); - - // Address has already been set at init -#ifndef PDCP_USE_NETLINK - - if (gpriv->irq==-EBUSY) { - printk("nasrg_open: irq failure\n"); - return -EBUSY; - } - -#endif //NETLINK - - if(!netif_queue_stopped(dev)) - netif_start_queue(dev); - else - netif_wake_queue(dev); - - // - init_timer(&gpriv->timer); - (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; - (gpriv->timer).data=0L; - (gpriv->timer).function=nasrg_ASCTL_timer; - add_timer(&gpriv->timer); - // - printk("nasrg_open: name = %s, end\n", dev->name); - return 0; -} - -//--------------------------------------------------------------------------- -// Called by ifconfig when the device is desactivated by ifconfig -int nasrg_stop(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - struct nas_priv *priv = netdev_priv(dev); - printk("nasrg_stop: begin\n"); - del_timer(&priv->timer); - netif_stop_queue(dev); - - printk("nasrg_stop: name = %s, end\n", dev->name); - return 0; -} - -//--------------------------------------------------------------------------- -void nasrg_teardown(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - int cxi; -#ifndef PDCP_USE_NETLINK - struct nas_priv *priv = netdev_priv(dev); -#endif //PDCP_USE_NETLINK - - printk("nasrg_teardown: begin\n"); - - if (dev) { -#ifndef PDCP_USE_NETLINK - - if (priv->irq!=-EBUSY) { - *pt_nas_rg_irq=-1; - rt_free_srq(priv->irq); - } - -#endif //PDCP_USE_NETLINK - -#ifdef PDCP_USE_NETLINK - nasrg_netlink_release(); -#endif //PDCP_USE_NETLINK - - // for (sapi=0; sapisap[sapi]); - nasrg_CLASS_flush_rclassifier(); - nasrg_CLASS_flush_mbmsclassifier(); - - for (cxi=0; cxicx+cxi); - nasrg_CLASS_flush_sclassifier(gpriv->cx+cxi); - //for (sapi=0; sapicx[cxi].sap[sapi]); - } - } // check dev - else { - printk("nasmt_teardown: Device is null\n"); - } - - printk("nasrg_teardown: end\n"); -} - -//--------------------------------------------------------------------------- -int nasrg_set_config(struct net_device *dev, struct ifmap *map) -{ - //--------------------------------------------------------------------------- - printk("nasrg_set_config: begin\n"); - - if (dev->flags & IFF_UP) - return -EBUSY; - - if (map->base_addr != dev->base_addr) { - printk(KERN_WARNING "nasrg_set_config: Can't change I/O address\n"); - return -EOPNOTSUPP; - } - - if (map->irq != dev->irq) - dev->irq = map->irq; - - return 0; -} - -//--------------------------------------------------------------------------- -int nasrg_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_DEVICE - printk("nasrg_hard_start_xmit: begin\n"); -#endif - - if ((!skb )||(!dev)) { - printk("nasrg_hard_start_xmit - input parameter skb or dev is NULL \n"); - return -1; - } - - // End debug information - netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - netif_trans_update(dev); -#else - dev->trans_start = jiffies; -#endif -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_hard_start_xmit: step 1\n"); -#endif - nasrg_CLASS_send(skb); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_hard_start_xmit: step 2\n"); -#endif - dev_kfree_skb(skb); -#ifdef NAS_DEBUG_SEND_DETAIL - printk("nasrg_hard_start_xmit: step 3\n"); -#endif - netif_wake_queue(dev); -#ifdef NAS_DEBUG_DEVICE - printk("nasrg_hard_start_xmit: end\n"); -#endif - return 0; -} - -//--------------------------------------------------------------------------- -struct net_device_stats *nasrg_get_stats(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - struct nas_priv *npriv = netdev_priv(dev); - return &npriv->stats; -} - -//--------------------------------------------------------------------------- -// New function from LITE DRIVER -int nasrg_set_mac_address(struct net_device *dev, void *mac) -{ - //--------------------------------------------------------------------------- - struct sockaddr *addr = mac; - printk("nasrg_set_mac_address: begin\n"); - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - return 0; -} - -//--------------------------------------------------------------------------- -int nasrg_change_mtu(struct net_device *dev, int mtu) -{ - //--------------------------------------------------------------------------- - printk("nasrg_change_mtu: begin\n"); - - if ((mtu<50) || (mtu>1500)) - // if ((mtu<1280) || (mtu>1500)) - return -EINVAL; - - dev->mtu = mtu; - return 0; -} - -//--------------------------------------------------------------------------- -int nasrg_change_rx_flags(struct net_device *dev, int flags) -{ - //--------------------------------------------------------------------------- - //struct nas_priv *priv = netdev_priv(dev); - printk("nasrg_change_rx_flags %08X\n", flags); - gpriv->rx_flags ^= flags; - return 0; -} - -//--------------------------------------------------------------------------- -void nasrg_tx_timeout(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - /* Transmitter timeout, serious problems. */ - printk("nasrg_tx_timeout: begin\n"); - // ((struct nas_priv *)(dev->priv))->stats.tx_errors++; - (gpriv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) - netif_trans_update(dev); -#else - dev->trans_start = jiffies; -#endif - netif_wake_queue(dev); - printk("nasrg_tx_timeout: transmit timed out %s\n",dev->name); -} - -//--------------------------------------------------------------------------- -// Define pointers for the module -static const struct net_device_ops nasrg_netdev_ops = { - // ?? nasrg_ interrupt - // - .ndo_open = nasrg_open, - .ndo_stop = nasrg_stop, - .ndo_start_xmit = nasrg_hard_start_xmit, - .ndo_validate_addr = NULL, - .ndo_get_stats = nasrg_get_stats, - //#ifdef KERNEL_VERSION_GREATER_THAN_32 - // .ndo_set_multicast_list = NULL, - .ndo_set_mac_address = nasrg_set_mac_address, - .ndo_set_config = nasrg_set_config, - .ndo_do_ioctl = nasrg_CTL_ioctl, - .ndo_change_mtu = nasrg_change_mtu, - .ndo_tx_timeout = nasrg_tx_timeout, - .ndo_change_rx_flags = nasrg_change_rx_flags, - //#endif -}; -//--------------------------------------------------------------------------- - - -//--------------------------------------------------------------------------- -// Initialisation of the network device -void nasrg_init(struct net_device *dev) -{ - //--------------------------------------------------------------------------- - uint8_t cxi, dscpi; - - printk("nasrg_init: begin\n"); - - if (dev) { - gpriv=netdev_priv(dev); - - memset(gpriv, 0, sizeof(struct nas_priv)); - // Initialize function pointers - dev->netdev_ops = &nasrg_netdev_ops; - -#ifndef NAS_DRIVER_TYPE_ETHERNET - dev->type = ARPHRD_EURUMTS; - dev->features = NETIF_F_NO_CSUM; - dev->hard_header_len = 0; - dev->addr_len = NAS_ADDR_LEN; - dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; - dev->tx_queue_len = NAS_TX_QUEUE_LEN; - dev->mtu = NAS_MTU; -#endif - // Can be one of the following enum defined in include/linux/netdevice.h: - // enum netdev_state_t { - // __LINK_STATE_START, - // __LINK_STATE_PRESENT, - // __LINK_STATE_NOCARRIER, - // __LINK_STATE_LINKWATCH_PENDING, - // __LINK_STATE_DORMANT, - // }; - set_bit(__LINK_STATE_PRESENT, &dev->state); - -#ifdef NAS_DRIVER_TYPE_ETHERNET - // overwrite values written above ( header_ops,type,hard_header_len,mtu,addr_len,tx_queue_len,flags,broadcast) - printk("\nnasrg_init: WARNING Driver type ETHERNET\n"); - ether_setup(dev); -#endif - // - // Initialize private structure - gpriv->rx_flags = NAS_RESET_RX_FLAGS; - - gpriv->sap[NAS_GC_SAPI] = RRC_DEVICE_GC; - gpriv->sap[NAS_NT_SAPI] = RRC_DEVICE_NT; - gpriv->cx[0].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT0; - gpriv->cx[0].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT0; - gpriv->cx[1].sap[NAS_DC_INPUT_SAPI] = RRC_DEVICE_DC_INPUT1; - gpriv->cx[1].sap[NAS_DC_OUTPUT_SAPI] = RRC_DEVICE_DC_OUTPUT1; - // gpriv->sap[NAS_CO_INPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_INPUT; - // gpriv->sap[NAS_CO_OUTPUT_SAPI] = QOS_DEVICE_CONVERSATIONAL_OUTPUT; - gpriv->sap[NAS_DRB_INPUT_SAPI] = PDCP2PDCP_USE_RT_FIFO;//QOS_DEVICE_CONVERSATIONAL_INPUT; - gpriv->sap[NAS_DRB_OUTPUT_SAPI] = NAS2PDCP_FIFO;//QOS_DEVICE_STREAMING_INPUT; - // - gpriv->retry_limit=NAS_RETRY_LIMIT_DEFAULT; - gpriv->timer_establishment=NAS_TIMER_ESTABLISHMENT_DEFAULT; - gpriv->timer_release=NAS_TIMER_RELEASE_DEFAULT; - - for (dscpi=0; dscpirclassifier[dscpi]=NULL; - - gpriv->nrclassifier=0; - - // - for(cxi=0; cxicx[cxi].state=NAS_IDLE; - gpriv->cx[cxi].countimer=NAS_TIMER_IDLE; - gpriv->cx[cxi].retry=0; - gpriv->cx[cxi].lcr=cxi; - gpriv->cx[cxi].rb=NULL; - gpriv->cx[cxi].num_rb=0; - - // initialisation of the classifier - for (dscpi=0; dscpicx[cxi].sclassifier[dscpi]=NULL; - - gpriv->cx[cxi].nsclassifier=0; - // initialisation of the IP address - nasrg_TOOL_imei2iid(NAS_NULL_IMEI, (uint8_t *)gpriv->cx[cxi].iid6); - gpriv->cx[cxi].iid4=0; - } - - spin_lock_init(&gpriv->lock); - - nasrg_TOOL_RGimei2iid(NAS_RG_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address) - printk("nasrg_init: init IMEI to IID\n"); - nasrg_ASCTL_init(); - } else { - printk("\n\nnasmt_init: ERROR, Device is NULL!!\n"); - } - - printk("nasrg_init: end\n"); - return ; -} - -//--------------------------------------------------------------------------- -int init_module (void) -{ - //--------------------------------------------------------------------------- - int err; - int inst = 0; - struct nas_priv *priv; - char devicename[100]; - - printk("\n\n\n\nnasrg_init_module: begin \n"); - - // Initialize parameters shared with RRC -#ifndef PDCP_USE_NETLINK - - if (pt_nas_rg_irq==NULL) { - printk("nasrg_init_module: shared irq parameter not initialised\n"); - err = -EBUSY; - printk("nasrg_init_module: returning %d \n\n", err); - return err; - } - - printk("nasrg_init_module: pt_nas_rg_irq valid \n"); -#endif - - /* - if (pt_rg_own_cell_id==NULL){ - printk("nasrg_init_module: shared cell_id parameter not initialised\n"); - err = -EBUSY; - printk("nasrg_init_module: returning %d \n\n\n", err); - return err; - } - printk("nasrg_init_module: pt_rg_own_cell_id valid \n"); - *pt_rg_own_cell_id = NASRG_OWN_CELLID; - */ - local_rg_cell_id = NASRG_OWN_CELLID; - - // Allocate device structure - sprintf(devicename,"oai%d",inst); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) - gdev = alloc_netdev(sizeof(struct nas_priv), devicename, nasrg_init); -#else - gdev = alloc_netdev(sizeof(struct nas_priv), devicename, NET_NAME_PREDICTABLE, nasrg_init); -#endif - printk("nasrg_init_module: after alloc_netdev \n"); - priv = netdev_priv(gdev); - //// - // -#ifndef PDCP_USE_NETLINK - priv->irq=rt_request_srq(0, nasrg_interrupt, NULL); - - if (priv->irq == -EBUSY || priv->irq == -EINVAL) { - printk("nasrg_init_module: No interrupt resource available\n"); - - if (gdev) { - free_netdev(gdev); - printk("nasrg_init_module: free_netdev ..\n"); - } - - return -EBUSY; - } else - printk("nasrg_init_module: Interrupt %d, ret = %d \n", priv->irq , ret); - - if (pt_nas_rg_irq==NULL) { - printk("nasmt_init_module: shared irq parameter has been reset\n"); - } else { - *pt_nas_rg_irq=priv->irq; - } - -#endif - // - ////// -#ifdef PDCP_USE_NETLINK - - if ((err=nasrg_netlink_init()) < 0) - printk("nasrg_init_module: NETLINK failed\n"); - - printk("nasrg_init_module: NETLINK INIT successful\n"); -#endif //NETLINK - - err= register_netdev(gdev); - - if (err) { - printk("nasrg_init_module: error %i registering device %s\n", err, gdev->name); - } else { - printk("nasrg_init_module: registering device %s, ifindex = %d\n\n",gdev->name, gdev->ifindex); - } - - return err; -} - -//--------------------------------------------------------------------------- -void cleanup_module(void) -{ - //--------------------------------------------------------------------------- - printk("nasrg_cleanup_module: begin\n"); - unregister_netdev(gdev); - nasrg_teardown(gdev); - free_netdev(gdev); - printk("nasrg_cleanup_module: end\n\n\n\n"); -} - -//--------------------------------------------------------------------------- -// Replaced by init_module and cleanup_module -//module_init (nasrg_init_module); -//module_exit (nasrg_cleanup_module); -//--------------------------------------------------------------------------- - -#define DRV_NAME "oai_nasrg" -#define DRV_VERSION "3.0.1"DRV_NAME -#define DRV_DESCRIPTION "OPENAIR CELLULAR LTE NASRG (eNodeB) Device Driver" -#define DRV_COPYRIGHT "-Copyright(c) GNU GPL Eurecom 2013" -#define DRV_AUTHOR "Michelle Wetterwald "DRV_COPYRIGHT - -// MODULE_LICENSE("GPL"); -// MODULE_DESCRIPTION("LTE Driver for eNodeB, playing as Non Access Stratum"); -// MODULE_AUTHOR("Michelle Wetterwald "); diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.c deleted file mode 100644 index 3c8f5d3cc6..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.c +++ /dev/null @@ -1,906 +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 nasrg_iocontrol.c -* \brief I/O control functions for upper layers of driver for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#include "nasrg_variables.h" -#include "nasrg_iocontrol.h" -#include "nasrg_proto.h" - -//#include -#include -#include -#include - -// Statistic -/////////////////////////////////////////////////////////////////////////////// - -//--------------------------------------------------------------------------- -void nasrg_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep) -{ - //--------------------------------------------------------------------------- - msgrep->rx_packets=gpriv->stats.rx_packets; - msgrep->tx_packets=gpriv->stats.tx_packets; - msgrep->rx_bytes=gpriv->stats.rx_bytes; - msgrep->tx_bytes=gpriv->stats.tx_bytes; - msgrep->rx_errors=gpriv->stats.rx_errors; - msgrep->tx_errors=gpriv->stats.tx_errors; - msgrep->rx_dropped=gpriv->stats.rx_dropped; - msgrep->tx_dropped=gpriv->stats.tx_dropped; -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_statistic_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_statistic_reply msgrep; - printk("nasrg_ioCTL_statistic: stat requested\n"); - nasrg_set_msg_statistic_reply(&msgrep); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_statistic: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Connections List -//--------------------------------------------------------------------------- -void nasrg_set_msg_cx_list_reply(uint8_t *msgrep) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - nasLocalConnectionRef_t lcr; - struct nas_msg_cx_list_reply *list; - msgrep[0]=NAS_CX_MAX; - list=(struct nas_msg_cx_list_reply *)(msgrep+1); - - for(lcr=0; lcrstate; - list[lcr].cellid=cx->cellid; - list[lcr].iid4=cx->iid4; - list[lcr].iid6[0]=cx->iid6[0]; - list[lcr].iid6[1]=cx->iid6[1]; - list[lcr].num_rb=cx->num_rb; - list[lcr].nsclassifier=cx->nsclassifier; - printk("nasrg_set_msg_cx_list: nsc=%u\n",cx->nsclassifier); - } -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_cx_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1]; - printk("nasrg_ioCTL_cx_list: connection list requested\n"); - nasrg_set_msg_cx_list_reply(msgrep); - - if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1)) { - printk("nasrg_ioCTL_cx_list: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasrg_ioCTL_cx_list: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Connection Establishment -//--------------------------------------------------------------------------- -void nasrg_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep, struct nas_msg_cx_establishment_request *msgreq) -{ - //--------------------------------------------------------------------------- - msgrep->status=-NAS_ERROR_NOTMT; -} -//--------------------------------------------------------------------------- -int nasrg_ioCTL_cx_establishment_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_cx_establishment_request msgreq; - struct nas_msg_cx_establishment_reply msgrep; - printk("nasrg_ioCTL_cx_establishment: connection establishment requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_cx_establishment: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_cx_establishment_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_cx_establishment: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Connection Release -//--------------------------------------------------------------------------- -void nasrg_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep, struct nas_msg_cx_release_request *msgreq) -{ - //--------------------------------------------------------------------------- - msgrep->status=-NAS_ERROR_NOTMT; -} - -//--------------------------------------------------------------------------- -// Request the release of a connection -int nasrg_ioCTL_cx_release_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_cx_release_request msgreq; - struct nas_msg_cx_release_reply msgrep; - - printk("nasrg_set_msg_cx_release: connection release requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_set_msg_cx_release: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_cx_release_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_set_msg_cx_release: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasrg_set_msg_cx_release: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer List -//--------------------------------------------------------------------------- -void nasrg_set_msg_rb_list_reply(uint8_t *msgrep, struct nas_msg_rb_list_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - cx=nasrg_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { - uint8_t rbi; - struct rb_entity *rb; - struct nas_msg_rb_list_reply *list; - - if (cx->num_rb > NAS_LIST_RB_MAX) - msgrep[0] = NAS_LIST_RB_MAX; - else - msgrep[0] = cx->num_rb; - - list=(struct nas_msg_rb_list_reply *)(msgrep+1); - - // list all radio bearers - for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbinext, ++rbi) { - list[rbi].state=rb->state; - list[rbi].rab_id=rb->rab_id; - list[rbi].sapi=rb->sapi; - list[rbi].qos=rb->qos; - list[rbi].cnxid=rb->cnxid; - } - - // check if mt0 requested and multicast bearer started, then add it to the list - if ((msgreq->lcr==0)&&(gpriv->mbms_rb[0].mbms_rbId!=0)) { - printk("MT %d, MBMS bearer rb_id %d\n", msgreq->lcr, gpriv->mbms_rb[0].mbms_rbId); - //++rbi; - ++msgrep[0]; - list[rbi].state=gpriv->mbms_rb[0].state; - list[rbi].rab_id=gpriv->mbms_rb[0].mbms_rbId; - list[rbi].sapi=gpriv->mbms_rb[0].sapi; - list[rbi].qos=gpriv->mbms_rb[0].qos; - list[rbi].cnxid=gpriv->mbms_rb[0].cnxid; - printk("rab_id cnxid Sapi QoS State\n"); - printk("%u %u %u %u ", list[rbi].rab_id,list[rbi].cnxid, list[rbi].sapi, list[rbi].qos); - nasrg_TOOL_print_state(list[rbi].state); - printk("\n"); - } - } else - msgrep[0]=0; -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_rb_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1]; - struct nas_msg_rb_list_request msgreq; - printk("nasrg_ioCTL_rb_list: Radio Bearer list requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_rb_list: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_rb_list_reply(msgrep, &msgreq); - - if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1)) { - printk("nasrg_ioCTL_rb_list: copy_to_user failure\n"); - return -EFAULT; - } - - printk("nasrg_ioCTL_rb_list: end\n"); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer Establishment -//--------------------------------------------------------------------------- -void nasrg_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep, struct nas_msg_rb_establishment_request *msgreq) -{ - //--------------------------------------------------------------------------- - if ((msgreq->rab_id<5)||(msgreq->rab_id>(NAS_RB_MAX_NUM-1))) - msgrep->status=-NAS_ERROR_NOTCORRECTRABI; - else { - struct cx_entity *cx; - cx=nasrg_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { //not multicast - struct rb_entity *rb; - rb=nasrg_COMMON_add_rb(cx, msgreq->rab_id, msgreq->qos); - - if (rb!=NULL) { - rb->cnxid = msgreq->cnxid; - rb->dscp = msgreq->dscp_dl; - rb->dscp_ul = msgreq->dscp_ul; - msgrep->status=nasrg_ASCTL_DC_send_rb_establish_request(cx, rb); - } else { - msgrep->status=-NAS_ERROR_NOMEMORY; - } - } else { //no MT found - if (msgreq->mcast_flag) { //multicast - int mbms_ix=0; // should allocate index based on Service_id /cnxid / MC IP address - // - gpriv->mbms_rb[mbms_ix].cnxid = msgreq->cnxid; - gpriv->mbms_rb[mbms_ix].serviceId = msgreq->cnxid; - gpriv->mbms_rb[mbms_ix].sessionId = NASRG_TEMP_MBMS_SESSION_ID; //Temp hard coded - gpriv->mbms_rb[mbms_ix].mbms_rbId = msgreq->rab_id; - gpriv->mbms_rb[mbms_ix].sapi = NAS_DC_INPUT_SAPI; -#ifdef NAS_DEBUG_MBMS_PROT - gpriv->mbms_rb[mbms_ix].sapi = NAS_DRB_INPUT_SAPI; //Only one RT-FIFO is used -#endif - gpriv->mbms_rb[mbms_ix].qos = msgreq->qos; - gpriv->mbms_rb[mbms_ix].dscp = msgreq->dscp_dl; - gpriv->mbms_rb[mbms_ix].duration = NASRG_TEMP_MBMS_DURATION; //Temp hard coded - memcpy ((char *)&(gpriv->mbms_rb[mbms_ix].mcast_address),(char *)&(msgreq->mcast_group), 16); - msgrep->status=nasrg_ASCTL_GC_send_mbms_bearer_establish_req(mbms_ix); - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - } - - msgrep->cnxid = msgreq->cnxid; - } - } -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_rb_establishment_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_rb_establishment_request msgreq; - struct nas_msg_rb_establishment_reply msgrep; - printk("nasrg_ioCTL_rb_establishment: Radio bearer establishment requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_rb_establishment: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_rb_establishment_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_rb_establishment: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Radio Bearer Release -//--------------------------------------------------------------------------- -void nasrg_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep, struct nas_msg_rb_release_request *msgreq) -{ - //--------------------------------------------------------------------------- - if (msgreq->lcrrab_id!=NASRG_DEFAULTRAB_RBID) { - struct rb_entity *rb; - struct cx_entity *cx; - cx=nasrg_COMMON_search_cx(msgreq->lcr); - rb=nasrg_COMMON_search_rb(cx, msgreq->rab_id); - - if ((rb!=NULL)&&(cx!=NULL)) { - uint8_t dscp; - msgrep->status=nasrg_ASCTL_DC_send_rb_release_request(cx, rb); - dscp=rb->dscp; - nasrg_COMMON_del_rb(cx, msgreq->rab_id, dscp); - } else - msgrep->status=-NAS_ERROR_NOTCONNECTED; - - msgrep->cnxid = msgreq->cnxid; - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTRABI; - } - } else { - if (msgreq->mcast_flag) { // multicast - int mbms_ix=0; // should search mbms_ix based on cnxid - msgrep->status=nasrg_ASCTL_GC_send_mbms_bearer_release_req(mbms_ix); - msgrep->cnxid = msgreq->cnxid; - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - } - } -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_rb_release_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_rb_release_request msgreq; - struct nas_msg_rb_release_reply msgrep; - printk("nasrg_ioCTL_rb_release: Radio bearer release requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_rb_release: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_rb_release_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_rb_release: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Classifier List -//--------------------------------------------------------------------------- -void nasrg_set_msg_class_list_reply(uint8_t *msgrep, struct nas_msg_class_list_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - struct classifier_entity *gc; - struct nas_msg_class_list_reply *list; - uint8_t cli; - list=(struct nas_msg_class_list_reply *)(msgrep+1); - - switch(msgreq->dir) { - case NAS_DIRECTION_SEND: - cx=nasrg_COMMON_search_cx(msgreq->lcr); - - if (cx==NULL) { - msgrep[0]=0; - return; - } - - gc=cx->sclassifier[msgreq->dscp]; - break; - - case NAS_DIRECTION_RECEIVE: - cx=NULL; - gc=gpriv->rclassifier[msgreq->dscp]; - break; - - default: - cx=NULL; - msgrep[0]=0; - return; - } - - for (cli=0; (gc!=NULL)&&(clinext, ++cli) { - list[cli].classref=gc->classref; - list[cli].lcr=msgreq->lcr; - list[cli].dir=msgreq->dir; - list[cli].dscp=msgreq->dscp; - list[cli].rab_id=gc->rab_id; - list[cli].version=gc->version; - - switch(gc->version) { - case 4: - list[cli].saddr.ipv4 = gc->saddr.ipv4; - list[cli].daddr.ipv4 = gc->daddr.ipv4; - break; - - case 6: - list[cli].saddr.ipv6 = gc->saddr.ipv6; - list[cli].daddr.ipv6 = gc->daddr.ipv6; - break; - } - - list[cli].protocol=gc->protocol; - list[cli].sport=ntohs(gc->sport); - list[cli].dport=ntohs(gc->dport); - list[cli].splen=gc->splen; - list[cli].dplen=gc->dplen; - list[cli].fct=nasrg_TOOL_invfct(gc); - } - - msgrep[0]=cli; -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_class_list_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1]; - struct nas_msg_class_list_request msgreq; - printk("nasrg_ioCTL_class_list: classifier list requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_class_list: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_class_list_reply(msgrep, &msgreq); - - if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1)) { - printk("nasrg_ioCTL_class_list: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Request the addition of a classifier rule -//--------------------------------------------------------------------------- -void nasrg_set_msg_class_add_reply(struct nas_msg_class_add_reply *msgrep, struct nas_msg_class_add_request *msgreq) -{ - //--------------------------------------------------------------------------- - struct classifier_entity *gc; - - if (msgreq->dscp>NAS_DSCP_DEFAULT) { - printk("nasrg_set_msg_class_add: Incoherent parameter value\n"); - msgrep->status=-NAS_ERROR_NOTCORRECTDSCP; - return; - } - - if (msgreq->dir==NAS_DIRECTION_SEND) { - struct cx_entity *cx; - cx=nasrg_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) { - printk("nasrg_set_msg_class_add: DSCP %d, Classref %d\n",msgreq->dscp, msgreq->classref ); - gc=nasrg_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref); - printk("nasrg_set_msg_class_add: %p %p\n" , msgreq, gc); - - if (gc==NULL) { - msgrep->status=-NAS_ERROR_NOMEMORY; - return; - } - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - return; - } - - gc->rab_id=msgreq->rab_id; - gc->rb=nasrg_COMMON_search_rb(cx, gc->rab_id); - } else { - if (msgreq->dir==NAS_DIRECTION_RECEIVE) { - gc=nasrg_CLASS_add_rclassifier(msgreq->dscp, msgreq->classref); - - if (gc==NULL) { - msgrep->status=-NAS_ERROR_NOMEMORY; - return; - } - } else { - msgrep->status=-NAS_ERROR_NOTCORRECTDIR; - return; - } - } - - nasrg_TOOL_fct(gc, msgreq->fct); - gc->version=msgreq->version; - - switch(gc->version) { - case 4: - gc->saddr.ipv4=msgreq->saddr.ipv4; - gc->daddr.ipv4=msgreq->daddr.ipv4; - gc->splen=msgreq->splen; - gc->dplen=msgreq->dplen; - break; - - case 6: - gc->saddr.ipv6=msgreq->saddr.ipv6; - gc->daddr.ipv6=msgreq->daddr.ipv6; - gc->splen=msgreq->splen; - gc->dplen=msgreq->dplen; - break; - - case 0: - gc->saddr.ipv6.s6_addr32[0]=0; - gc->daddr.ipv6.s6_addr32[1]=0; - gc->saddr.ipv6.s6_addr32[2]=0; - gc->daddr.ipv6.s6_addr32[3]=0; - gc->splen=0; - gc->dplen=0; - break; - - default: - msgrep->status=-NAS_ERROR_NOTCORRECTVERSION; - kfree(gc); - return; - } - - gc->protocol=msgreq->protocol; - gc->sport=htons(msgreq->sport); - gc->dport=htons(msgreq->dport); - msgrep->status=0; -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_class_add_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_class_add_request msgreq; - struct nas_msg_class_add_reply msgrep; - printk("nasrg_ioCTL_class_add: Add classifier components requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_class_add: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_class_add_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_class_add: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// Request the deletion of a classifier rule -//--------------------------------------------------------------------------- -void nasrg_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep, struct nas_msg_class_del_request *msgreq) -{ - //--------------------------------------------------------------------------- - if (msgreq->dscp>NAS_DSCP_DEFAULT) { - printk("nasrg_set_msg_class_del: Incoherent parameter value\n"); - msgrep->status=-NAS_ERROR_NOTCORRECTDSCP; - return; - } - - if (msgreq->dir==NAS_DIRECTION_SEND) { - struct cx_entity *cx; - cx=nasrg_COMMON_search_cx(msgreq->lcr); - - if (cx!=NULL) - nasrg_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref); - else { - msgrep->status=-NAS_ERROR_NOTCORRECTLCR; - return; - } - } else { - if (msgreq->dir==NAS_DIRECTION_RECEIVE) - nasrg_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref); - else { - msgrep->status=-NAS_ERROR_NOTCORRECTDIR; - return; - } - } - - msgrep->status=0; -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_class_del_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_class_del_request msgreq; - struct nas_msg_class_del_reply msgrep; - printk("nasrg_ioCTL_class_del: Del classifier components requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_class_del: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_class_del_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_class_del: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// UE Multicast Join -//--------------------------------------------------------------------------- -void nasrg_set_ue_multicast_join_reply(struct nas_msg_mt_mcast_reply *msgrep, struct nas_msg_mt_mcast_join *msgreq) -{ - //--------------------------------------------------------------------------- - if (msgreq->ue_idue_id); - cx->requested_joined_services[0] = msgreq->cnxid; - msgrep->ue_id = msgreq->ue_id; - msgrep->result = nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx); - msgrep->cnxid = msgreq->cnxid; - } else { - msgrep->result=-NAS_ERROR_NOTCORRECTLCR; - } -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_ue_multicast_join_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_mt_mcast_join msgreq; - struct nas_msg_mt_mcast_reply msgrep; - printk("nasrg_ioCTL_ue_multicast_join: UE multicast join requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_ue_multicast_join: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_ue_multicast_join_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_ue_multicast_join: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// UE Multicast Leave -//--------------------------------------------------------------------------- -void nasrg_set_ue_multicast_leave_reply(struct nas_msg_mt_mcast_reply *msgrep, struct nas_msg_mt_mcast_leave *msgreq) -{ - //--------------------------------------------------------------------------- - if (msgreq->ue_idue_id); - cx->requested_left_services[0] = msgreq->cnxid; - msgrep->ue_id = msgreq->ue_id; - msgrep->result = nasrg_ASCTL_DC_send_mbms_ue_notify_req(cx); - msgrep->cnxid = msgreq->cnxid; - } else { - msgrep->result=-NAS_ERROR_NOTCORRECTLCR; - } -} - -//--------------------------------------------------------------------------- -int nasrg_ioCTL_ue_multicast_leave_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_mt_mcast_leave msgreq; - struct nas_msg_mt_mcast_reply msgrep; - printk("nasrg_ioCTL_ue_multicast_leave: UE multicast leave requested\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_ue_multicast_leave: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_ue_multicast_leave_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_ue_multicast_leave: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// ENB Measures -// Messages for triggering measurement -//--------------------------------------------------------------------------- -void nasrg_set_msg_eNBmeasure_trigger_reply(struct nas_msg_enb_measure_trigger_reply *msgrep, struct nas_msg_enb_measure_trigger *msgreq) -{ - //--------------------------------------------------------------------------- - struct cx_entity *cx; - int lcr=0; // Temp lcr->mt =0 (should be GC uplink) - - cx=nasrg_COMMON_search_cx(lcr); - - if (msgreq->cell_id != cx->cellid) - printk("\nERROR : invalid cell_id received\n\n"); - - if (nasrg_ASCTL_DC_send_eNBmeasurement_req(cx)>0) - msgrep->status = 0; - else - msgrep->status = NAS_ERROR_NOTCORRECTVALUE ; -} -//--------------------------------------------------------------------------- -int nasrg_ioCTL_eNBmeasure_trigger_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_enb_measure_trigger msgreq; - struct nas_msg_enb_measure_trigger_reply msgrep; - printk("nasrg_ioCTL_eNBmeasure_trigger_request: Measures triggered\n"); - - if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))) { - printk("nasrg_ioCTL_eNBmeasure_trigger_request: copy_from_user failure\n"); - return -EFAULT; - } - - nasrg_set_msg_eNBmeasure_trigger_reply(&msgrep, &msgreq); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_eNBmeasure_trigger_request: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// ENb Measurement -// Messages for Measurement retrieval -//--------------------------------------------------------------------------- -void nasrg_set_msg_eNBmeasure_retrieve_reply(struct nas_msg_enb_measure_retrieve *msgrep) -{ - //--------------------------------------------------------------------------- - int i; - - msgrep->cell_id = gpriv->measured_cell_id; - msgrep->num_UEs = gpriv->num_UEs; - - for (i=0; i num_UEs; i++) { - msgrep->measures[i].rlcBufferOccupancy = gpriv->rlcBufferOccupancy[i]; - msgrep->measures[i].scheduledPRB = gpriv->scheduledPRB[i]; - msgrep->measures[i].totalDataVolume = gpriv->totalDataVolume[i]; - //clean variables - gpriv->rlcBufferOccupancy[i] = 0; - gpriv->scheduledPRB[i] = 0; - gpriv->totalDataVolume[i] = 0; - } - - msgrep->totalNumPRBs = gpriv->totalNumPRBs; - //clean variable - gpriv->totalNumPRBs = 0; -} -//--------------------------------------------------------------------------- -int nasrg_ioCTL_eNBmeasure_retrieve_request(struct nas_ioctl *gifr) -{ - //--------------------------------------------------------------------------- - struct nas_msg_enb_measure_retrieve msgrep; - printk("nasrg_ioCTL_eNBmeasure_retrieve_request: Measurement requested\n"); - - nasrg_set_msg_eNBmeasure_retrieve_reply(&msgrep); - - if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))) { - printk("nasrg_ioCTL_eNBmeasure_retrieve_request: copy_to_user failure\n"); - return -EFAULT; - } - - return 0; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// IOCTL command -//--------------------------------------------------------------------------- -int nasrg_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - //--------------------------------------------------------------------------- - struct nas_ioctl *gifr; - int r; - printk("nasrg_CTL_ioctl: begin\n"); - spin_lock(&gpriv->lock); - - switch(cmd) { - case NASRG_IOCTL_RAL: - gifr=(struct nas_ioctl *)ifr; - - switch(gifr->type) { - case NAS_MSG_STATISTIC_REQUEST: - r=nasrg_ioCTL_statistic_request(gifr); - break; - - case NAS_MSG_CX_ESTABLISHMENT_REQUEST: - r=nasrg_ioCTL_cx_establishment_request(gifr); - break; - - case NAS_MSG_CX_RELEASE_REQUEST: - r=nasrg_ioCTL_cx_release_request(gifr); - break; - - case NAS_MSG_CX_LIST_REQUEST: - r=nasrg_ioCTL_cx_list_request(gifr); - break; - - case NAS_MSG_RB_ESTABLISHMENT_REQUEST: - r=nasrg_ioCTL_rb_establishment_request(gifr); - break; - - case NAS_MSG_RB_RELEASE_REQUEST: - r=nasrg_ioCTL_rb_release_request(gifr); - break; - - case NAS_MSG_RB_LIST_REQUEST: - r=nasrg_ioCTL_rb_list_request(gifr); - break; - - case NAS_MSG_CLASS_ADD_REQUEST: - r=nasrg_ioCTL_class_add_request(gifr); - break; - - case NAS_MSG_CLASS_LIST_REQUEST: - r=nasrg_ioCTL_class_list_request(gifr); - break; - - case NAS_MSG_CLASS_DEL_REQUEST: - r=nasrg_ioCTL_class_del_request(gifr); - break; - - case NAS_RG_MSG_MT_MCAST_JOIN: - r=nasrg_ioCTL_ue_multicast_join_request(gifr); - break; - - case NAS_RG_MSG_MT_MCAST_LEAVE: - r=nasrg_ioCTL_ue_multicast_leave_request(gifr); - break; - - case NAS_MSG_ENB_MEAS_TRIGGER: - r=nasrg_ioCTL_eNBmeasure_trigger_request(gifr); - break; - - case NAS_MSG_ENB_MEAS_RETRIEVE: - r=nasrg_ioCTL_eNBmeasure_retrieve_request(gifr); - break; - - default: - printk("nasrg_CTL_ioctl: unkwon request type, type=%x\n", gifr->type); - r=-EFAULT; - } - - break; - - default: - printk("nasrg_CTL_ioctl: Unknown ioctl command, cmd=%x\n", cmd); - r=-EFAULT; - } - - spin_unlock(&gpriv->lock); - printk("nasrg_CTL_ioctl: end\n"); - return r; -} - -//--------------------------------------------------------------------------- -void nasrg_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - printk("nasrg_CTL_send - void \n"); -} - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.h b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.h deleted file mode 100644 index bd7baac3b6..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_iocontrol.h +++ /dev/null @@ -1,251 +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 nasrg_iocontrol.h -* \brief I/O control constnats and structures for upper layers of driver for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef NASRGD_CTL_H -#define NASRGD_CTL_H - -#include -#include -#include -#include - -#define NAS_MSG_MAXLEN 1100 - -// type of CTL message -#define NAS_MSG_STATISTIC_REQUEST 1 -#define NAS_MSG_STATISTIC_REPLY 2 -#define NAS_MSG_ECHO_REQUEST 3 -#define NAS_MSG_ECHO_REPLY 4 -#define NAS_MSG_CX_ESTABLISHMENT_REQUEST 5 -#define NAS_MSG_CX_ESTABLISHMENT_REPLY 6 -#define NAS_MSG_CX_RELEASE_REQUEST 7 -#define NAS_MSG_CX_RELEASE_REPLY 8 -#define NAS_MSG_CX_LIST_REQUEST 9 -#define NAS_MSG_CX_LIST_REPLY 10 -#define NAS_MSG_RB_ESTABLISHMENT_REQUEST 11 -#define NAS_MSG_RB_ESTABLISHMENT_REPLY 12 -#define NAS_MSG_RB_RELEASE_REQUEST 13 -#define NAS_MSG_RB_RELEASE_REPLY 14 -#define NAS_MSG_RB_LIST_REQUEST 15 -#define NAS_MSG_RB_LIST_REPLY 16 -#define NAS_MSG_CLASS_ADD_REQUEST 17 -#define NAS_MSG_CLASS_ADD_REPLY 18 -#define NAS_MSG_CLASS_DEL_REQUEST 19 -#define NAS_MSG_CLASS_DEL_REPLY 20 -#define NAS_MSG_CLASS_LIST_REQUEST 21 -#define NAS_MSG_CLASS_LIST_REPLY 22 -#define NAS_MSG_NEIGHBOUR_REQUEST 23 -#define NAS_MSG_NEIGHBOUR_REPLY 24 -//MBMS -#define NAS_RG_MSG_MT_MCAST_JOIN 30 -#define NAS_RG_MSG_MT_MCAST_LEAVE 31 -#define NAS_RG_MSG_MT_MCAST_REPLY 32 -// ENB MEASURES (MEDIEVAL DEMO 3) -#define NAS_MSG_ENB_MEAS_TRIGGER 33 -#define NAS_MSG_ENB_MEAS_RETRIEVE 34 - - -// Max number of entry of a message list -#define NAS_LIST_CX_MAX 32 -#define NAS_LIST_RB_MAX 32 -#define NAS_LIST_CLASS_MAX 32 - -typedef uint16_t nasMsgType_t; - -struct nas_ioctl { - char name[IFNAMSIZ]; - nasMsgType_t type; - char *msg; -}; - -//**** -struct nas_msg_statistic_reply { - uint32_t rx_packets; - uint32_t tx_packets; - uint32_t rx_bytes; - uint32_t tx_bytes; - uint32_t rx_errors; - uint32_t tx_errors; - uint32_t rx_dropped; - uint32_t tx_dropped; -}; - -//**** -struct nas_msg_cx_list_reply { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t state; - nasCellID_t cellid; // cell identification - uint32_t iid6[2]; // IPv6 interface identification - uint8_t iid4; // IPv4 interface identification - uint16_t num_rb; - uint16_t nsclassifier; -}; -//**** -struct nas_msg_cx_establishment_reply { - int status; -}; -struct nas_msg_cx_establishment_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasCellID_t cellid; // Cell identification -}; -//**** -struct nas_msg_cx_release_reply { - int status; -}; -struct nas_msg_cx_release_request { - nasLocalConnectionRef_t lcr; // Local Connection reference -}; - -//**** -struct nas_msg_rb_list_reply { - nasRadioBearerId_t rab_id; - nasSapId_t sapi; - nasQoSTrafficClass_t qos; - uint8_t state; - uint32_t cnxid; -}; -struct nas_msg_rb_list_request { - nasLocalConnectionRef_t lcr; // Local Connection reference -}; -//**** -struct nas_msg_rb_establishment_reply { - int status; - uint32_t cnxid; -}; -struct nas_msg_rb_establishment_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; - nasQoSTrafficClass_t qos; - uint16_t dscp_ul; - uint16_t dscp_dl; - uint16_t mcast_flag; - uint8_t mcast_group[16]; - uint32_t cnxid; -}; - -//**** -struct nas_msg_rb_release_reply { - int status; - uint32_t cnxid; -}; -struct nas_msg_rb_release_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; - uint16_t mcast_flag; - uint32_t cnxid; -}; - -//**** -struct nas_msg_class_add_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - nasRadioBearerId_t rab_id; - uint8_t dir; // direction (send or receive) - uint8_t dscp; // codepoint - uint8_t fct; - uint16_t classref; - uint8_t version; - union { - struct in6_addr ipv6; - uint32_t ipv4; - } saddr; // IP source address - uint8_t splen; // prefix length - union { - struct in6_addr ipv6; - uint32_t ipv4; - } daddr; // IP destination address - uint8_t dplen; // prefix length - uint8_t protocol; // high layer protocol type - uint16_t sport; // source port - uint16_t dport; // destination port -}; -struct nas_msg_class_add_reply { - int status; -}; -//**** -struct nas_msg_class_del_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t dir; // direction (send or receive) - uint8_t dscp; // codepoint - uint16_t classref; -}; -struct nas_msg_class_del_reply { - int status; -}; -//**** -#define nas_msg_class_list_reply nas_msg_class_add_request -struct nas_msg_class_list_request { - nasLocalConnectionRef_t lcr; // Local Connection reference - uint8_t dir; - uint8_t dscp; -}; - -//**** -struct nas_msg_neighbour_cell_list_reply { - nasCellID_t cellid; // cell identification - uint32_t iid6[4]; // IPv6 address of access router -}; - -//MBMS -//**** -struct nas_msg_mt_mcast_join { - nasLocalConnectionRef_t ue_id; - uint32_t cnxid; - nasRadioBearerId_t rab_id; -}; - -struct nas_msg_mt_mcast_leave { - nasLocalConnectionRef_t ue_id; - uint32_t cnxid; - nasRadioBearerId_t rab_id; -}; - -struct nas_msg_mt_mcast_reply { - nasLocalConnectionRef_t ue_id; - uint32_t cnxid; - int result; -}; -//**** - -//MEDIEVAL DEMO 3 -//**** -struct nas_msg_enb_measure_trigger { - nasCellID_t cell_id; -}; -struct nas_msg_enb_measure_trigger_reply { - int status; -}; - -struct nas_msg_enb_measure_retrieve { - nasCellID_t cell_id; - nasNumConnUEs_t num_UEs; - nasENbMeasures_t measures[MAX_MEASURE_UE]; - nasENbMeasure_t totalNumPRBs; -}; - - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_netlink.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_netlink.c deleted file mode 100644 index d0a3516567..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_netlink.c +++ /dev/null @@ -1,246 +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 nasrg_netlink.c -* \brief Netlink socket functions for OpenAirInterface CELLULAR version - MT -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -//#include -#include -#include -#include -#include -#include -#include - -#include - -#include "nasrg_variables.h" -#include "nasrg_proto.h" - -static struct sock *nas_nl_sk = NULL; -static struct sock *nas_rrcnl_sk = NULL; - -//static int exit_netlink_thread=0; -static DEFINE_MUTEX(nasrg_mutex); - -// This can also be implemented using thread to get the data from PDCP without blocking. -//--------------------------------------------------------------------------- -// Function for transfer with PDCP (from NASLITE) -static void nasrg_nl_data_ready (struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct nlmsghdr *nlh = NULL; - - // Start debug information -#ifdef NETLINK_DEBUG - printk("nasrg_nl_data_ready - begin \n"); -#endif - - if (!skb) { - printk("nasrg_nl_data_ready - input parameter skb is NULL \n"); - return; - } - - // End debug information - -#ifdef NETLINK_DEBUG - printk("nasrg_nl_data_ready - Received socket from PDCP\n"); -#endif //NETLINK_DEBUG - nlh = (struct nlmsghdr *)skb->data; - nasrg_COMMON_QOS_receive(nlh); -} - -//--------------------------------------------------------------------------- -// Function for transfer with RRC -static void nasrg_rrcnl_data_ready (struct sk_buff *skb) -{ - //--------------------------------------------------------------------------- - struct nlmsghdr *nlh = NULL; - char target_sap; - uint8_t cxi; - - // Start debug information -#ifdef NAS_DEBUG_RRCNL - printk("nasrg_rrcnl_data_ready - begin \n"); -#endif - - if (!skb) { - printk("nasrg_rrcnl_data_ready - input parameter skb is NULL \n"); - return; - } - - // End debug information - - nlh = (struct nlmsghdr *)skb->data; - //pdcph = (struct pdcp_data_ind_header_t *)NLMSG_DATA(nlh); - //nasrg_TOOL_print_buffer((char *)NLMSG_DATA(nlh), 48); - - target_sap = ((char*)NLMSG_DATA(nlh))[0]; -#ifdef NAS_DEBUG_RRCNL - printk("nasrg_rrcnl_data_ready - Received on socket from RRC, SAP %d\n", target_sap); -#endif //NAS_DEBUG_RRCNL - - switch (target_sap) { - case RRC_NAS_DC0_OUT: - //printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n"); - cxi = 0; - nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]); - break; - - case RRC_NAS_DC1_OUT: - //printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n"); - cxi = 1; - nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]); - break; - - case RRC_NAS_DC2_OUT: - //printk("nasrg_rrcnl_data_ready - Calling nasrg_ASCTL_DC_receive\n"); - cxi = 2; - nasrg_ASCTL_DC_receive(gpriv->cx+cxi, &((char*)NLMSG_DATA(nlh))[1]); - break; - - default: - printk("nasrg_rrcnl_data_ready - Invalid SAP value received\n"); - } - -} - -//--------------------------------------------------------------------------- -int nasrg_netlink_init(void) -{ - //--------------------------------------------------------------------------- - printk("nasrg_netlink_init - begin \n"); - - nas_nl_sk = netlink_kernel_create(&init_net,OAI_IP_DRIVER_NETLINK_ID, 0, nasrg_nl_data_ready, - &nasrg_mutex, // NULL - THIS_MODULE); - - if (!nas_nl_sk) { - printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket\n"); - // TEMP printk("nasrg_netlink_init - netlink_kernel_create failed for PDCP socket %d\n", errno); - return(-1); - } - - nas_rrcnl_sk = netlink_kernel_create(&init_net,NAS_RRCNL_ID, 0, nasrg_rrcnl_data_ready, - &nasrg_mutex, // NULL - THIS_MODULE); - - if (!nas_rrcnl_sk) { - printk("nasrg_rrcnl_init - netlink_kernel_create failed for RRC socket\n"); - return(-1); - } - - return(0); -} - -//--------------------------------------------------------------------------- -void nasrg_netlink_release(void) -{ - //--------------------------------------------------------------------------- - printk("nasrg_netlink_release - begin \n"); - - //exit_netlink_thread=1; - printk("nasrg_netlink_release - Releasing netlink sockets\n"); - - if(nas_nl_sk) { - netlink_kernel_release(nas_nl_sk); - } - - if(nas_rrcnl_sk) { - netlink_kernel_release(nas_rrcnl_sk); - } - -} - -//--------------------------------------------------------------------------- -int nasrg_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination) -{ - //--------------------------------------------------------------------------- - struct sk_buff *nl_skb; - struct nlmsghdr *nlh; - int status; - // Start debug information -#ifdef NETLINK_DEBUG - printk("nasrg_netlink_send - begin \n"); -#endif - - if (!data_buffer) { - printk("nasrg_netlink_send - ERROR - input parameter data is NULL \n"); - return(0); - } - - if (!nas_nl_sk || !nas_rrcnl_sk) { - printk("nasrg_netlink_send - ERROR - socket is NULL\n"); - return(0); - } - - // End debug information - - nl_skb = alloc_skb(NLMSG_SPACE(data_length),GFP_ATOMIC); - - if (!nl_skb) { - printk("nasrg_netlink_send - ERROR - could not allocate skbuffer\n"); - return(0); - } - - nlh = (struct nlmsghdr *)nl_skb->data; - - // printk("nasrg_netlink_send Sending %d bytes (%d)\n",data_length,NLMSG_SPACE(data_length)); - skb_put(nl_skb, NLMSG_SPACE(data_length)); - memcpy(NLMSG_DATA(nlh), data_buffer, data_length); - nlh->nlmsg_len = NLMSG_SPACE(data_length); - - nlh->nlmsg_pid = 0; /* from kernel */ - NETLINK_CB(nl_skb).pid = 0; - - // destination 0 = PDCP, 1 = RRC - if (destination== NASNL_DEST_PDCP) { -#ifdef NETLINK_DEBUG - printk("nasrg_netlink_send - Sending to PDCP - nl_skb %p, nl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_nl_sk, nlh, nlh->nlmsg_len); -#ifdef NAS_DEBUG_SEND_DETAIL - nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),48); -#endif -#endif //DEBUG_NETLINK - status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT); - } else { -#ifdef NAS_DEBUG_RRCNL - printk("nasrg_netlink_send - Sending to RRC - nl_skb %p, nas_rrcnl_sk %p, nlh %p, nlh->nlmsg_len %d\n", nl_skb, nas_rrcnl_sk, nlh, nlh->nlmsg_len); - nasrg_TOOL_print_buffer(NLMSG_DATA(nlh),data_length); -#endif //NAS_DEBUG_RRCNL - status = netlink_unicast(nas_rrcnl_sk, nl_skb, NL_DEST_RRC_PID, MSG_DONTWAIT); - } - - if (status < 0) { - printk("nasrg_netlink_send - SEND status is %d\n",status); - return(0); - } else { -#ifdef NETLINK_DEBUG - printk("nasrg_netlink_send - SEND status is %d, data_length %d\n",status, data_length); -#endif - return data_length; - } -} - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_proto.h b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_proto.h deleted file mode 100644 index 9053c88a56..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_proto.h +++ /dev/null @@ -1,135 +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 nasrg_proto.h -* \brief Function prototypes for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASRGD_PROTO_H -#define _NASRGD_PROTO_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include - -// #include "rrc_nas_primitives.h" -// #include "protocol_vars_extern.h" -// #include "as_sap.h" -// #include "rrc_qos.h" -// #include "rrc_sap.h" - -// nasrg_netlink.c -void nasrg_netlink_release(void); -int nasrg_netlink_init(void); -int nasrg_netlink_send(unsigned char *data_buffer, unsigned int data_length, int destination); - -// nasrg_common.c -//void nasrg_COMMON_receive(uint16_t hlen, uint16_t dlength, int sap); -void nasrg_COMMON_receive(uint16_t bytes_read, uint16_t payload_length, void *data_buffer, int rb_id, int sap); - -void nasrg_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -void nasrg_COMMON_QOS_send_test_netlink(struct sk_buff *skb); -void nasrg_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -#ifndef PDCP_USE_NETLINK -void nasrg_COMMON_QOS_receive(struct cx_entity *cx); -#else -void nasrg_COMMON_QOS_receive(struct nlmsghdr *nlh); -#endif -struct rb_entity *nasrg_COMMON_add_rb(struct cx_entity *cx, nasRadioBearerId_t rabi, nasQoSTrafficClass_t qos); -struct rb_entity *nasrg_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t rabi); -struct cx_entity *nasrg_COMMON_search_cx(nasLocalConnectionRef_t lcr); -void nasrg_COMMON_del_rb(struct cx_entity *cx, nasRadioBearerId_t rab_id, nasIPdscp_t dscp); -void nasrg_COMMON_flush_rb(struct cx_entity *cx); - -//nasrg_ascontrol.c -void nasrg_ASCTL_init(void); -void nasrg_ASCTL_timer(unsigned long data); -void nasrg_ASCTL_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -//int nasrg_ASCTL_DC_receive(struct cx_entity *cx); -int nasrg_ASCTL_DC_receive(struct cx_entity *cx, char *buffer); -// -int nasrg_ASCTL_DC_send_cx_establish_confirm(struct cx_entity *cx, uint8_t response); -int nasrg_ASCTL_DC_send_rb_establish_request(struct cx_entity *cx, struct rb_entity *rb); -int nasrg_ASCTL_DC_send_rb_release_request(struct cx_entity *cx, struct rb_entity *rb); -int nasrg_ASCTL_GC_send_mbms_bearer_establish_req(int mbms_ix ); -int nasrg_ASCTL_GC_send_mbms_bearer_release_req(int mbms_ix); -int nasrg_ASCTL_DC_send_mbms_ue_notify_req(struct cx_entity *cx); -int nasrg_ASCTL_DC_send_eNBmeasurement_req(struct cx_entity *cx); - -void nasrg_ASCTL_start_default_mbms_service(void); - -// nasrg_iocontrol.c -void nasrg_CTL_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); -int nasrg_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -// nasrg_classifier.c -void nasrg_CLASS_send(struct sk_buff *skb); -struct classifier_entity *nasrg_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref); -struct classifier_entity *nasrg_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref); -struct classifier_entity *nasrg_CLASS_add_mbmsclassifier(int mbms_ix, uint16_t classref); -void nasrg_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref); -void nasrg_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref); -void nasrg_CLASS_del_mbmsclassifier(int mbms_ix, uint16_t classref); -void nasrg_CLASS_flush_sclassifier(struct cx_entity *cx); -void nasrg_CLASS_flush_rclassifier(void); -void nasrg_CLASS_flush_mbmsclassifier(void); - -// nasrg_tool.c -uint8_t nasrg_TOOL_invfct(struct classifier_entity *gc); -void nasrg_TOOL_fct(struct classifier_entity *gc, uint8_t fct); -void nasrg_TOOL_imei2iid(uint8_t *imei, uint8_t *iid); -void nasrg_TOOL_RGimei2iid(uint8_t *imei, uint8_t *iid); -uint8_t nasrg_TOOL_get_dscp6(struct ipv6hdr *iph); -uint8_t nasrg_TOOL_get_dscp4(struct iphdr *iph); -uint8_t *nasrg_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol); -uint8_t *nasrg_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol); -char *nasrg_TOOL_get_udpmsg(struct udphdr *udph); -uint16_t nasrg_TOOL_udpcksum(struct in6_addr *saddr, struct in6_addr *daddr, uint8_t proto, uint32_t udplen, void *data); -int nasrg_TOOL_network6(struct in6_addr *addr, struct in6_addr *prefix, uint8_t plen); -int nasrg_TOOL_network4(uint32_t *addr, uint32_t *prefix, uint8_t plen); - -void nasrg_TOOL_pk_icmp6(struct icmp6hdr *icmph); - -void nasrg_TOOL_pk_all(struct sk_buff *skb); -void nasrg_TOOL_pk_ipv6(struct ipv6hdr *iph); -void nasrg_TOOL_print_state(uint8_t state); -void nasrg_TOOL_print_buffer(unsigned char * buffer,int length); -void nasrg_TOOL_print_rb_entity(struct rb_entity *rb); -void nasrg_TOOL_print_classifier(struct classifier_entity *gc); - -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_sap.h b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_sap.h deleted file mode 100644 index e2835adf7d..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_sap.h +++ /dev/null @@ -1,77 +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 nasmt_sap.h -* \brief SAP constants for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASRGD_SAP_H -#define _NASRGD_SAP_H - - -// RT-FIFO identifiers ** must be identical to Access Stratum as_sap.h and rrc_sap.h - -#define RRC_DEVICE_GC RRC_SAPI_RG_GCSAP -#define RRC_DEVICE_NT RRC_SAPI_RG_NTSAP -#define RRC_DEVICE_DC_INPUT0 RRC_SAPI_RG_DCSAP0_IN -#define RRC_DEVICE_DC_INPUT1 RRC_SAPI_RG_DCSAP1_IN -#define RRC_DEVICE_DC_OUTPUT0 RRC_SAPI_RG_DCSAP0_OUT -#define RRC_DEVICE_DC_OUTPUT1 RRC_SAPI_RG_DCSAP1_OUT -// -//#define QOS_DEVICE_CONVERSATIONAL_INPUT QOS_SAPI_CONVERSATIONAL_INPUT_RG -//#define QOS_DEVICE_CONVERSATIONAL_OUTPUT QOS_SAPI_CONVERSATIONAL_OUTPUT_RG - -#define PDCP2PDCP_USE_RT_FIFO 21 -#define NAS2PDCP_FIFO 22 - -//FIFO indexes in control blocks -#define NAS_DC_INPUT_SAPI 0 -#define NAS_DC_OUTPUT_SAPI 1 -#define NAS_SAPI_CX_MAX 2 - -#define NAS_GC_SAPI 0 -#define NAS_NT_SAPI 1 -#define NAS_DRB_INPUT_SAPI 2 //NAS_CO_INPUT_SAPI -#define NAS_DRB_OUTPUT_SAPI 3 //NAS_CO_OUTPUT_SAPI -#define NAS_SAPI_MAX 4 - -//#define NAS_QOS_CONVERSATIONAL UMTS_TRAFFIC_CONVERSATIONAL -// - -/* Defined in RRC -#define RRC_NAS_GC_IN 0 -#define RRC_NAS_GC_OUT 1 -#define RRC_NAS_NT_IN 2 -#define RRC_NAS_NT_OUT 3 -#define RRC_NAS_DC0_IN 4 -#define RRC_NAS_DC0_OUT 5 -#define RRC_NAS_DC1_IN 6 -#define RRC_NAS_DC1_OUT 7 -#define RRC_NAS_DC2_IN 8 -#define RRC_NAS_DC2_OUT 9 -*/ -#endif - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_tool.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_tool.c deleted file mode 100644 index 54324cf63f..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_tool.c +++ /dev/null @@ -1,478 +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 "nasrg_variables.h" -#include "nasrg_proto.h" - -//--------------------------------------------------------------------------- -// -void nasrg_TOOL_fct(struct classifier_entity *gc, uint8_t fct) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_fct - begin \n"); -#endif - - if (gc==NULL) { - printk("nasrg_TOOL_fct - input parameter gc is NULL \n"); - return; - } - - // End debug information - switch(fct) { - case NAS_FCT_QOS_SEND: - gc->fct=nasrg_COMMON_QOS_send; - break; - - case NAS_FCT_CTL_SEND: - gc->fct=nasrg_CTL_send; - break; - - case NAS_FCT_DC_SEND: - gc->fct=nasrg_ASCTL_DC_send_sig_data_request; - break; - - case NAS_FCT_DEL_SEND: - gc->fct=nasrg_COMMON_del_send; - break; - - default: - gc->fct=nasrg_COMMON_del_send; - } -} - -//--------------------------------------------------------------------------- -uint8_t nasrg_TOOL_invfct(struct classifier_entity *gc) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_invfct - begin \n"); -#endif - - if (gc==NULL) { - printk("nasrg_TOOL_invfct - input parameter gc is NULL \n"); - return 0; - } - - // End debug information - if (gc->fct==nasrg_COMMON_QOS_send) - return NAS_FCT_QOS_SEND; - - if (gc->fct==nasrg_CTL_send) - return NAS_FCT_CTL_SEND; - - if (gc->fct==nasrg_COMMON_del_send) - return NAS_FCT_DEL_SEND; - - if (gc->fct==nasrg_ASCTL_DC_send_sig_data_request) - return NAS_FCT_DC_SEND; - - return 0; -} - -//--------------------------------------------------------------------------- -uint8_t nasrg_TOOL_get_dscp6(struct ipv6hdr *iph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_get_dscp6 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasrg_TOOL_get_dscp6 - input parameter iph is NULL \n"); - return 0; - } - - // End debug information - // return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>22; //Yan - return (ntohl(((*(__u32 *)iph)&NAS_TRAFFICCLASS_MASK)))>>20; -} - -//--------------------------------------------------------------------------- -uint8_t nasrg_TOOL_get_dscp4(struct iphdr *iph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_get_dscp4 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasrg_TOOL_get_dscp4 - input parameter iph is NULL \n"); - return 0; - } - - // End debug information - return ((iph->tos)>>5)<<3; -} - -//--------------------------------------------------------------------------- -uint8_t *nasrg_TOOL_get_protocol6(struct ipv6hdr *iph, uint8_t *protocol) -{ - //--------------------------------------------------------------------------- - uint16_t size; - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_get_protocol6 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasrg_TOOL_get_protocol6 - input parameter iph is NULL \n"); - return NULL; - } - - if (protocol==NULL) { - printk("nasrg_TOOL_get_protocol6 - input parameter protocol is NULL \n"); - return NULL; - } - - // End debug information - - *protocol=iph->nexthdr; - size=NAS_IPV6_SIZE; - - while (1) { - switch(*protocol) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_ICMPV6: - return (uint8_t *)((uint8_t *)iph+size); - - case IPPROTO_HOPOPTS: - case IPPROTO_ROUTING: - case IPPROTO_DSTOPTS: - *protocol=((uint8_t *)iph+size)[0]; - size+=((uint8_t *)iph+size)[1]*8+8; - break; - - case IPPROTO_FRAGMENT: - *protocol=((uint8_t *)iph+size)[0]; - size+=((uint8_t *)iph+size)[1]+8; - break; - - case IPPROTO_NONE: - case IPPROTO_AH: - case IPPROTO_ESP: - default: - return NULL; - } - } -} - -//--------------------------------------------------------------------------- -uint8_t *nasrg_TOOL_get_protocol4(struct iphdr *iph, uint8_t *protocol) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_get_protocol4 - begin \n"); -#endif - - if (iph==NULL) { - printk("nasrg_TOOL_get_protocol4 - input parameter iph is NULL \n"); - return NULL; - } - - if (protocol==NULL) { - printk("nasrg_TOOL_get_protocol4 - input parameter protocol is NULL \n"); - return NULL; - } - - // End debug information - *protocol=iph->protocol; - - switch(*protocol) { - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_ICMP: - return (uint8_t *)((uint8_t *)iph+iph->tot_len); - - default: - return NULL; - } -} - -//--------------------------------------------------------------------------- -// Convert the IMEI to iid -void nasrg_TOOL_imei2iid(uint8_t *imei, uint8_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_imei2iid - begin \n"); -#endif - - if (imei==NULL) { - printk("nasrg_TOOL_imei2iid - input parameter imei is NULL \n"); - return; - } - - if (iid==NULL) { - printk("nasrg_TOOL_imei2iid - input parameter iid is NULL \n"); - return; - } - - // End debug information - memset(iid, 0, NAS_ADDR_LEN); - iid[0] = 0x03; -#ifdef NAS_DRIVER_TYPE_ETHERNET - iid[0] = 0x02; -#endif - iid[1] = 16*imei[0]+imei[1]; - iid[2] = 16*imei[2]+imei[3]; - iid[3] = 16*imei[4]+imei[5]; - iid[4] = 16*imei[6]+imei[7]; -#ifdef NAS_DRIVER_TYPE_ETHERNET - iid[3] = 0xff; - iid[4] = 0xfe; -#endif - iid[5] = 16*imei[8]+imei[9]; - iid[6] = 16*imei[10]+imei[11]; - iid[7] = 16*imei[12]+imei[13]; -} - -//--------------------------------------------------------------------------- -// Convert the RG IMEI to iid -void nasrg_TOOL_RGimei2iid(uint8_t *imei, uint8_t *iid) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_RGimei2iid - begin \n"); -#endif - - if (!imei || !iid) { - printk("nasrg_TOOL_RGimei2iid - input parameter imei or iid is NULL \n"); - return; - } - - // End debug information - memset(iid, 0, NAS_ADDR_LEN); - iid[0] = 0x00; // to be compatible between link local and global - iid[1] = 16*imei[0]+imei[1]; - iid[2] = 16*imei[2]+imei[3]; - iid[3] = 16*imei[4]+imei[5]; - iid[4] = 16*imei[6]+imei[7]; - iid[5] = 16*imei[8]+imei[9]; - iid[6] = 16*imei[10]+imei[11]; - iid[7] = 16*imei[12]+imei[13]; -} - -//--------------------------------------------------------------------------- -void nasrg_TOOL_pk_icmp6(struct icmp6hdr *icmph) -{ - //--------------------------------------------------------------------------- - // Start debug information -#ifdef GRAAL_DEBUG_TOOL - printk("nasrg_TOOL_pk_icmp6 - begin \n"); -#endif - - if (!icmph) { - printk("nasrg_TOOL_pk_icmp6 - input parameter icmph is NULL \n"); - return; - } - - // End debug information - printk("ICMPv6:\t type= %d, code = %d\n", icmph->icmp6_type, icmph->icmp6_code); - - switch(icmph->icmp6_type) { - case ICMPV6_DEST_UNREACH: - printk("Destination unreachable\n"); - break; - - case ICMPV6_PKT_TOOBIG: - printk("Packet too big\n"); - break; - - case ICMPV6_TIME_EXCEED: - printk("Time exceeded\n"); - break; - - case ICMPV6_PARAMPROB: - printk("Parameter problem\n"); - break; - - case ICMPV6_ECHO_REQUEST: - printk("Echo request\n"); - break; - - case ICMPV6_ECHO_REPLY: - printk("Echo reply\n"); - break; - - case ICMPV6_MGM_QUERY: - printk("Multicast listener query\n"); - break; - - case ICMPV6_MGM_REPORT: - printk("Multicast listener report\n"); - break; - - case ICMPV6_MGM_REDUCTION: - printk("Multicast listener done\n"); - break; - - case NDISC_ROUTER_SOLICITATION: - printk("Router solicitation\n"); - break; - - case NDISC_ROUTER_ADVERTISEMENT: - printk("Router advertisment\n"); - break; - - case NDISC_NEIGHBOUR_SOLICITATION: - printk("Neighbour solicitation\n"); - break; - - case NDISC_NEIGHBOUR_ADVERTISEMENT: - printk("Neighbour advertisment\n"); - break; - - case NDISC_REDIRECT: - printk("redirect message\n"); - break; - } -} - - -//--------------------------------------------------------------------------- -void nasrg_TOOL_print_state(uint8_t state) -{ - //--------------------------------------------------------------------------- - switch(state) { - case NAS_IDLE: - printk("NAS_IDLE\n"); - return; - - case NAS_CX_FACH: - printk("NAS_CX_FACH\n"); - return; - - case NAS_CX_DCH: - printk("NAS_CX_DCH\n"); - return; - - case NAS_CX_RECEIVED: - printk("NAS_CX_RECEIVED\n"); - return; - - case NAS_CX_CONNECTING: - printk("NAS_CX_CONNECTING\n"); - return; - - case NAS_CX_RELEASING: - printk("NAS_CX_RELEASING\n"); - return; - - case NAS_CX_CONNECTING_FAILURE: - printk("NAS_CX_CONNECTING_FAILURE\n"); - return; - - case NAS_CX_RELEASING_FAILURE: - printk("NAS_CX_RELEASING_FAILURE\n"); - return; - - case NAS_RB_ESTABLISHING: - printk("NAS_RB_ESTABLISHING\n"); - return; - - case NAS_RB_RELEASING: - printk("NAS_RB_RELEASING\n"); - return; - - case NAS_RB_ESTABLISHED: - printk("NAS_RB_ESTABLISHED\n"); - return; - - default: - printk(" Unknown state\n"); - } -} - -//----------------------------------------------------------------------------- -// Print the content of a buffer in hexadecimal -void nasrg_TOOL_print_buffer(unsigned char * buffer,int length) -{ - //----------------------------------------------------------------------------- - int i; - - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_print_buffer - begin \n"); -#endif - - if (buffer==NULL) { - printk("\n nasrg_TOOL_print_buffer - input parameter buffer is NULL \n"); - return; - } - - // End debug information - printk("Buffer content: "); - - for (i=0; irab_id, rb->sapi, rb->qos, rb->dscp); - printk("state %d, retry %d, countimer %d\n",rb->state, rb->retry, rb->countimer); -}; - -//----------------------------------------------------------------------------- -void nasrg_TOOL_print_classifier(struct classifier_entity *gc) -{ - //----------------------------------------------------------------------------- - // Start debug information -#ifdef NAS_DEBUG_TOOL - printk("nasrg_TOOL_print_classifier - begin \n"); -#endif - - if (gc==NULL) { - printk("\n nasrg_TOOL_print_classifier - input parameter gc is NULL \n"); - return; - } - - // End debug information - printk("\nClassifier content: classref %d, version %d, splen %d, dplen %d,\n", gc->classref, gc->version, gc->splen, gc->dplen); - printk("protocol %d, sport %d, dport %d, rab_id %d\n", gc->protocol, gc->sport, gc->dport, gc->rab_id); - nasrg_TOOL_print_rb_entity(gc->rb); -}; - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_variables.h b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_variables.h deleted file mode 100644 index 7c2b69459c..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_variables.h +++ /dev/null @@ -1,214 +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 nasrg_variables.h -* \brief Variable and structure definitions for OpenAirInterface CELLULAR version - RG -* \author michelle.wetterwald, navid.nikaein, raymond.knopp, Lionel Gauthier -* \company Eurecom -* \email: michelle.wetterwald@eurecom.fr, raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr -*/ -/*******************************************************************************/ -#ifndef _NASRGD_VAR_H -#define _NASRGD_VAR_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -//#include -#include -#include -#include -#include -#include -#include - -#include "rrc_nas_primitives.h" -#include "rrc_qos_classes.h" -#include "rrc_nas_sap.h" - -#include "nasrg_constant.h" -#include "nasrg_sap.h" - -struct cx_entity; - -struct rb_entity { - // uint16_t default_rab; - uint32_t cnxid; - nasRadioBearerId_t rab_id; //ue_rbId - nasRadioBearerId_t rg_rbId; - nasRadioBearerId_t mbms_rbId; - nasSapId_t sapi; - nasQoSTrafficClass_t qos; - nasQoSTrafficClass_t RadioQosClass; - nasIPdscp_t dscp; //this is DL dscp - nasIPdscp_t dscp_ul; - uint8_t state; - uint8_t result; - uint8_t retry; - uint32_t countimer; - //for MBMS - uint16_t serviceId; - uint16_t sessionId; - uint16_t duration; - uint8_t mcast_address[16]; - // - struct rb_entity *next; -}; - -struct classifier_entity { - uint32_t classref; // classifier identity - uint8_t version; // IP version 4 or 6 - union { - struct in6_addr ipv6; - uint32_t ipv4; - } saddr; // IP source address - uint8_t splen; // IP prefix size - union { - struct in6_addr ipv6; - uint32_t ipv4; - } daddr; // IP destination address - uint8_t dplen; // IP prefix size - uint8_t protocol; // layer 4 protocol type (tcp, udp, ...) - uint16_t sport; // source port - uint16_t dport; // destination port - struct rb_entity *rb; - nasRadioBearerId_t rab_id; // RAB identification - void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc); - struct classifier_entity *next; -}; - - -struct cx_entity { - int sap[NAS_SAPI_CX_MAX]; - uint8_t state; // state of the connection - nasLocalConnectionRef_t lcr; // Local connection reference - nasCellID_t cellid; // cell identification - uint32_t countimer; // timeout's counter - uint8_t retry; // number of retransmissions - struct classifier_entity *sclassifier[NAS_DSCP_MAX]; // send classifiers table - uint16_t nsclassifier; - uint32_t iid6[2]; // IPv6 interface identification - uint8_t iid4; // IPv4 interface identification - struct rb_entity *rb; // RB entities for RABs - uint16_t num_rb; - // MW - 17/5/05 - int ue_id; - int rrc_state; - // MBMS - int requested_joined_services[NASRG_MBMS_SVCES_MAX]; - int requested_left_services[NASRG_MBMS_SVCES_MAX]; - int joined_services[NASRG_MBMS_SVCES_MAX]; -}; - -//struct mbms_rb_entity{ -// uint32_t cnxid; -// nasRadioBearerId_t mbms_rbId; -// nasSapId_t sapi; -// nasQoSTrafficClass_t qos; -// nasQoSTrafficClass_t RadioQosClass; -// uint8_t state; -// uint8_t result; -// uint8_t retry; -// uint32_t countimer; -// -// uint16_t serviceId; -// uint16_t sessionId; -// uint16_t duration; -//}; -// - -struct nas_priv { - int irq; - int rx_flags; - struct timer_list timer; - spinlock_t lock; - struct net_device_stats stats; - uint8_t retry_limit; - uint32_t timer_establishment; - uint32_t timer_release; - struct cx_entity cx[NAS_CX_MAX]; - struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier - int nrclassifier; - uint32_t next_sclassref; - int sap[NAS_SAPI_MAX]; - uint8_t xbuffer[NAS_MAX_LENGTH]; // transmission buffer - uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer - // MW - 17/5/05 - int broadcast_counter; - int SIB18_counter; - // MBMS - struct rb_entity mbms_rb[NASRG_MBMS_SVCES_MAX]; - struct classifier_entity *mbmsclassifier[NASRG_MBMS_SVCES_MAX]; // mbms classifier - int nmbmsclassifier; - uint32_t next_mbmsclassref; - //Added for demo 3 - MW - nasCellID_t measured_cell_id; - uint16_t num_UEs; - uint32_t rlcBufferOccupancy[NAS_CX_MAX]; - uint32_t scheduledPRB[NAS_CX_MAX]; - uint32_t totalDataVolume[NAS_CX_MAX]; - uint32_t totalNumPRBs; -}; - -struct ipversion { -#if defined(__LITTLE_ENDIAN_BITFIELD) - uint8_t reserved:4, - version:4; -#else - uint8_t version:4, - reserved:4; -#endif -}; - -typedef struct pdcp_data_req_header_t { - unsigned int rb_id; - unsigned int data_size; - int inst; -} pdcp_data_req_header_t; - -typedef struct pdcp_data_ind_header_t { - unsigned int rb_id; - unsigned int data_size; - int inst; -} pdcp_data_ind_header_t; -// -extern struct nas_priv *gpriv; -extern struct net_device *gdev; -//extern int bytes_wrote; -//extern int bytes_read; - -extern uint8_t NAS_RG_IMEI[14]; -extern uint8_t NAS_NULL_IMEI[14]; - -//global variables shared with RRC -extern int *pt_nas_rg_irq; -//extern uint16_t *pt_rg_own_cell_id; -extern uint16_t local_rg_cell_id; -#endif diff --git a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/Makefile b/openair2/NAS/DRIVER/CELLULAR/NETLTEST/Makefile deleted file mode 100755 index eec82de367..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# Lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - -# You can modify the below as well, but probably -# won't need to. - -#CC = egcs - -#UPDIR := $(shell /bin/pwd) -#GRAAL_DIR =$(UPDIR)/.. -#RRC_DIR =$(UPDIR)/../../../AS/L3/RRC - -CELL_UPDIR := $(shell /bin/pwd) -NAS_DIR := $(OPENAIR2_DIR)/NAS/DRIVER/CELLULAR/NASMT -RRC_DIR := $(OPENAIR2_DIR)/RRC/CELLULAR -EXTRA_CFLAGS += -I$(RRC_DIR) -DNODE_MT - -CFLAGS = -Wall -g -I$(NAS_DIR) -I$(RRC_DIR) - -COMPILE = $(CC) $(CFLAGS) -c - -OBJS = netltest.o - -EXECUTABLE = netltest - -# "all" is the default target. Simply make it point to myprogram. - -all: $(EXECUTABLE) - -# Define the components of the program, and how to link them together. -# These components are defined as dependencies; that is, they must be -# made up-to-date before the code is linked. - -$(EXECUTABLE): $(OBJS) - $(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJS) - -# Add any special rules here. - -# Specify that all .o files depend on .c files, and indicate how -# the .c files are converted (compiled) to the .o files. - -%.o: %.c - $(COMPILE) -o $@ $< - -clean: - -rm $(OBJS) $(EXECUTABLE) diff --git a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest b/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest deleted file mode 100755 index f44ea64b09..0000000000 Binary files a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest and /dev/null differ diff --git a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest.c b/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest.c deleted file mode 100644 index 84de51a68d..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/netltest.c +++ /dev/null @@ -1,213 +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 - */ - -//----------------------------------------------------------------------------- -// For FIFOS / NETLINK interface -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/******************** -// RRC definitions - ********************/ -#include "nasmt_constant.h" -#include "rrc_nas_sap.h" -#include "rrc_constant.h" -//----------------------------------------------------------------------------- -//#define MAX_PAYLOAD 4096 /* this sould cover the max mtu size*/ -struct nlmsghdr *rrcnl_nlh; -int rrcnl_sock_fd; -struct sockaddr_nl rrcnl_src_addr, rrcnl_dest_addr; -struct iovec rrcnl_iov; -struct msghdr rrcnl_msg; - -//----------------------------------------------------------------------------- -typedef unsigned int sdu_size_t; -typedef unsigned int rb_id_t; - -typedef struct pdcp_data_req_header_t { - rb_id_t rb_id; - sdu_size_t data_size; - int inst; -} pdcp_data_req_header_t; - -typedef struct pdcp_data_ind_header_t { - rb_id_t rb_id; - sdu_size_t data_size; - int inst; -} pdcp_data_ind_header_t; - -#define MAX_PAYLOAD 1024 /* maximum payload size*/ -struct sockaddr_nl src_addr, dest_addr; -struct nlmsghdr *nlh = NULL; -struct iovec iov; -int sock_fd; -struct msghdr msg; -#define OAI_IP_DRIVER_NETLINK_ID 31 -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -void foo( int sig ) -{ - //----------------------------------------------------------------------------- - printf("I got cntl-C, closing socket\n"); - close(sock_fd); - close(rrcnl_sock_fd); - exit(-1); -} - -//----------------------------------------------------------------------------- -int main() -{ - //----------------------------------------------------------------------------- - struct sigaction newaction; - int i=0; - int ret; - int len, count; - - newaction.sa_handler = foo; - - // register cntl-C handler - if ( sigaction( SIGINT, &newaction, NULL ) == -1) - perror("Could not install the new signal handler"); - - // create both sockets - sock_fd = socket(PF_NETLINK, SOCK_RAW,OAI_IP_DRIVER_NETLINK_ID); - printf("Opened socket with fd %d\n",sock_fd); - ret = fcntl(sock_fd,F_SETFL,O_NONBLOCK); - printf("fcntl returns %d\n",ret); - - rrcnl_sock_fd = socket(PF_NETLINK, SOCK_RAW, NAS_RRCNL_ID); - printf("rrc_ue_netlink_init - Opened socket with fd %d\n", rrcnl_sock_fd); - ret = fcntl(rrcnl_sock_fd,F_SETFL,O_NONBLOCK); - printf("rrc_ue_netlink_init - fcntl returns %d\n",ret); - - // set src addresses blocks - memset(&src_addr, 0, sizeof(src_addr)); - src_addr.nl_family = AF_NETLINK; - src_addr.nl_pid = 1;//getpid(); /* self pid */ - src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); - printf("bind returns %d\n",ret); - - memset(&rrcnl_src_addr, 0, sizeof(rrcnl_src_addr)); - rrcnl_src_addr.nl_family = AF_NETLINK; - rrcnl_src_addr.nl_pid = NL_DEST_RRC_PID;//getpid(); /* self pid */ - rrcnl_src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(rrcnl_sock_fd, (struct sockaddr*)&rrcnl_src_addr, sizeof(rrcnl_src_addr)); - printf("rrc_ue_netlink_init - bind returns %d\n",ret); - - // set dest addresses blocks - memset(&dest_addr, 0, sizeof(dest_addr)); - dest_addr.nl_family = AF_NETLINK; - dest_addr.nl_pid = 0; /* For Linux Kernel */ - dest_addr.nl_groups = 0; /* unicast */ - - memset(&rrcnl_dest_addr, 0, sizeof(rrcnl_dest_addr)); - rrcnl_dest_addr.nl_family = AF_NETLINK; - rrcnl_dest_addr.nl_pid = 0; /* For Linux Kernel */ - rrcnl_dest_addr.nl_groups = 0; /* unicast */ - - // set nlh - nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); - /* Fill the netlink message header */ - nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); - nlh->nlmsg_pid = 1;//getpid(); /* self pid */ - nlh->nlmsg_flags = 0; - - rrcnl_nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(RRC_NAS_MAX_SIZE)); - //memset(rrcnl_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); - /* Fill the netlink message header */ - rrcnl_nlh->nlmsg_len = NLMSG_SPACE(RRC_NAS_MAX_SIZE); - rrcnl_nlh->nlmsg_pid = NL_DEST_RRC_PID;//getpid(); /* self pid */ - rrcnl_nlh->nlmsg_flags = 0; - - // set iov - iov.iov_base = (void *)nlh; - iov.iov_len = nlh->nlmsg_len; - memset(&msg,0,sizeof(msg)); - msg.msg_name = (void *)&dest_addr; - msg.msg_namelen = sizeof(dest_addr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - rrcnl_iov.iov_base = (void *)rrcnl_nlh; - rrcnl_iov.iov_len = rrcnl_nlh->nlmsg_len; - memset(&rrcnl_msg,0,sizeof(rrcnl_msg)); - rrcnl_msg.msg_name = (void *)&rrcnl_dest_addr; - rrcnl_msg.msg_namelen = sizeof(rrcnl_dest_addr); - rrcnl_msg.msg_iov = &rrcnl_iov; - rrcnl_msg.msg_iovlen = 1; - - /* Read message from kernel */ - memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); - - /* Read message from kernel */ - memset(rrcnl_nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); - - while (1) { - len = recvmsg(sock_fd, &msg, 0); - count = recvmsg(rrcnl_sock_fd, &rrcnl_msg, 0); - - if (len<0) { - // exit(-1); - } else { - printf("Received PDCP socket with length %d (nlmsg_len = %d)\n",len,nlh->nlmsg_len); - } - - if (count<0) { - // exit(-1); - } else { - printf("Received RRC socket with length %d (nlmsg_len = %d)\n",count,rrcnl_nlh->nlmsg_len); - } - - /* usleep(1000); - i=i+1; - if ((i % 100) == 0) - printf("%d\n",i);*/ - usleep(50); - i=i+1; - - if ((i % 1000) == 0) - printf("%d\n",i); - - /* - for (i=0;inlmsg_len - sizeof(struct nlmsghdr);i++) { - printf("%x ", - ((unsigned char *)NLMSG_DATA(nlh))[i]); - } - */ - } - - /* Close Netlink Socket */ - return 0; -} - - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/nettestPDCP.c b/openair2/NAS/DRIVER/CELLULAR/NETLTEST/nettestPDCP.c deleted file mode 100644 index 121d3bba8b..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/NETLTEST/nettestPDCP.c +++ /dev/null @@ -1,149 +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 -#include -#include -#include -#include -#include -#include - -typedef unsigned int sdu_size_t; -typedef unsigned int rb_id_t; - -typedef struct pdcp_data_req_header_t { - rb_id_t rb_id; - sdu_size_t data_size; - int inst; -} pdcp_data_req_header_t; - -typedef struct pdcp_data_ind_header_t { - rb_id_t rb_id; - sdu_size_t data_size; - int inst; -} pdcp_data_ind_header_t; - -#define MAX_PAYLOAD 1024 /* maximum payload size*/ -struct sockaddr_nl src_addr, dest_addr; -struct nlmsghdr *nlh = NULL; -struct iovec iov; -int sock_fd; -struct msghdr msg; - - -void foo( int sig ) -{ - - printf("I got cntl-C, closing socket\n"); - - - close(sock_fd); - exit(-1); -} - - -#define OAI_IP_DRIVER_NETLINK_ID 31 - -void main() -{ - - - struct sigaction newaction; - int i=0; - int ret; - int len; - - newaction.sa_handler = foo; - - if ( sigaction( SIGINT, &newaction, NULL ) == -1) - perror("Could not install the new signal handler"); - - sock_fd = socket(PF_NETLINK, SOCK_RAW,OAI_IP_DRIVER_NETLINK_ID); - - printf("Opened socket with fd %d\n",sock_fd); - - ret = fcntl(sock_fd,F_SETFL,O_NONBLOCK); - printf("fcntl returns %d\n",ret); - - memset(&src_addr, 0, sizeof(src_addr)); - src_addr.nl_family = AF_NETLINK; - src_addr.nl_pid = 1;//getpid(); /* self pid */ - src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(sock_fd, (struct sockaddr*)&src_addr, - sizeof(src_addr)); - printf("bind returns %d\n",ret); - - memset(&dest_addr, 0, sizeof(dest_addr)); - dest_addr.nl_family = AF_NETLINK; - dest_addr.nl_pid = 0; /* For Linux Kernel */ - dest_addr.nl_groups = 0; /* unicast */ - - nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); - /* Fill the netlink message header */ - nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); - nlh->nlmsg_pid = 1;//getpid(); /* self pid */ - nlh->nlmsg_flags = 0; - - iov.iov_base = (void *)nlh; - iov.iov_len = nlh->nlmsg_len; - memset(&msg,0,sizeof(msg)); - msg.msg_name = (void *)&dest_addr; - msg.msg_namelen = sizeof(dest_addr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - - /* Read message from kernel */ - memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); - - while (1) { - len = recvmsg(sock_fd, &msg, 0); - - - if (len<0) { - - // exit(-1); - } else { - printf("Received socket with length %d (nlmsg_len = %d)\n",len,nlh->nlmsg_len); - } - - usleep(1000); - i=i+1; - - if ((i % 100) == 0) - printf("%d\n",i); - - /* - for (i=0;inlmsg_len - sizeof(struct nlmsghdr);i++) { - printf("%x ", - ((unsigned char *)NLMSG_DATA(nlh))[i]); - } - */ - } - - /* Close Netlink Socket */ - -} - - - - diff --git a/openair2/NAS/DRIVER/CELLULAR/readme.txt b/openair2/NAS/DRIVER/CELLULAR/readme.txt deleted file mode 100755 index fd4411a25b..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/readme.txt +++ /dev/null @@ -1,157 +0,0 @@ - --------------------------------- - | UMTS-TDD (TD-CDMA) NAS driver | - --------------------------------- - - - -1 - COMPILATION ---------------- -Pre-Req : - - RTAI installed and running - - IPv6 patched as described below (see 4 - Patching IPv6) - -From RHODOS26 directory: - - - make nasrg : creates the NAS RG driver (nasrg.ko) and copies it to the RHODOS26/bin directory - - - make cleannasrg : deletes all object and temporary files from the nasrg directory - - - make nasmt : creates the NAS MT driver (nasmt.ko) and copies it to the RHODOS26/bin directory - - - make cleannasmt : deletes all object and temporary files from the nasmt directory - - -2 - OPERATION - RG side ------------------------ - -A1 - Compile the Access Stratum (for IF mode) - -Pre-Req : RTAI installed and running - ICC 8.0 installed and running - - > make rgif - > make asrguserif - > make rrmumts - -A2 - Compile the Access Stratum (for RF mode) - -Pre-Req : RTAI installed and running - ICC 8.0 installed and running - - > make guimakefiles - > make rgrf - > make asrguserrfa2 - > make rrmumts - - -B - Start the Access Stratum - - (as root ) > cd <..>RHODOS26/bin - - (first install) > create_rtfifos - (first install) > mknod -m 666 /dev/daq0 c 127 1 - (after cleanas) > cp -../src/rrm_umts/congestion_control/resources_manager/rrm_master.properties . - - (-- ) > ./start_rtos - (-- ) > ./runrgif [for IF] [or ./runrga2 for RF] - - ==> to check correct operation: - (as root ) cat /dev/rtf62 - (as root ) tail -f /var/log/messages - -C - Start the NAS Driver - - (as root ) > cd <..>RHODOS26/bin - (-- ) > insmod nasrg.ko - (-- ) > ./access_router.up - -D - Stop the NAS Driver and the Access Stratum - - (-- ) > ./access_router.down - (-- ) > rmmod nasrg - (-- ) > on Acccess stratum window - (-- ) > ./stop_rtos - -E - Clean Access Stratum compilation - - > make cleanas - -3 - OPERATION - MT side ------------------------ - -A1 - Compile the Access Stratum (for IF mode) - -Pre-Req : RTAI installed and running - ICC 8.0 installed and running - file RHODOS26/src/access_stratum/l1/low/control/mmx.h copied in /usr/include - - > make mtif - > make asmtuserif - > make fpgatest - -A2 - Compile the Access Stratum (for RF mode) - -Pre-Req : RTAI installed and running - ICC 8.0 installed and running - file RHODOS26/src/access_stratum/l1/low/control/mmx.h copied in /usr/include - - > make guimakefiles - > make mtrf - > make asmtuserrf - > make fpgatest - - -B - Start the Access Stratum - - (as root ) > cd <..>RHODOS26/bin - - (first install) > create_rtfifos - (first install) > mknod -m 666 /dev/daq0 c 127 1 - - (-- ) > ./start_rtos - (-- ) > ./runrgif [for IF] [or ./runrga2 for RF] - - ==> to check correct operation: - (as root ) cat /dev/rtf62 - (as root ) tail -f /var/log/messages - -C - Start the NAS Driver - - (as root ) > cd <..>RHODOS26/bin - (-- ) > insmod nasmt.ko - (-- ) > ./mobile_node.up - -D - Stop the NAS Driver and the Access Stratum - - (-- ) > ./mobile_node.down - (-- ) > rmmod nasmt - (-- ) > on Acccess stratum window - (-- ) > ./stop_rtos - -E - Clean Access Stratum compilation - - > make cleanas - - -4 - Patching IPv6 ------------------------ - -For Linux with 2.6.xx kernel version (xx = 10 or 81): - -- move RHODOS26/non_access_stratum/driver/src/addrconf.c.26.xx to /usr/src/linux/net/ipv6/addrconf.c -- move RHODOS26/non_access_stratum/driver/src/if_arp.h.26.xx to /usr/src/linux/include/linux/if_arp.h -- recompile IPv6 (inside the kernel or as a module, as usual) - -5 - Start the MT connection ------------------------ - -You can use either the RAL-UMTS (RAL-CDMA) -- see corresponding documentation -- - -* OR * - -the tool provided with the driver (directory RHODOS26/src/non_access_stratum/driver/mt_tools). -Install the tool, update the Cell_id field if needed and click on the "Attach" button. - - - \ No newline at end of file diff --git a/openair2/NAS/DRIVER/CELLULAR/start_mt_cellular b/openair2/NAS/DRIVER/CELLULAR/start_mt_cellular deleted file mode 100755 index c89f19e9c0..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/start_mt_cellular +++ /dev/null @@ -1,13 +0,0 @@ -#xterm -hold "tail -f /var/log/messages" & -insmod ./NASMT/nascellmt.ko nas_IMEI=3,5,6,0,1,4,9,1,5,0,0,0,0,0 -#insmod ./NASMT/nascellmt.ko -sleep 2 -ifconfig oai0 10.0.1.2 netmask 255.255.255.0 broadcast 10.0.1.255 -#ifconfig oai0 add 2001:660:382:14:335:600:8014:9150/64 -#./bin/mobile_node.up -#sleep 3 -#./CTL_TOOL/gioctl cx add 0 5 -#xterm -hold -e ./bin/IALdummy & -#sleep 1 -#xterm -hold -e ./bin/tdcdma_gui & -#lsmod diff --git a/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_noradvd b/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_noradvd deleted file mode 100755 index 3d51140dcd..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_noradvd +++ /dev/null @@ -1,17 +0,0 @@ - -#xterm -hold -e ant -buildfile rrm_umts.xml run & -#sleep 2 -insmod ./NASRG/nascellrg.ko -sleep 2 -#bin/access_router_noradvd.up -sysctl -w net.ipv6.conf.default.dad_transmits=0 -#sysctl -w net.ipv6.conf.all.forwarding=1 -#sysctl -w net.ipv4.conf.all.forwarding=1 - -#ifconfig oai0 192.168.14.100 -ifconfig oai0 10.0.1.3 netmask 255.255.255.0 broadcast 10.0.1.255 -ifconfig oai0 add 2001:660:382:14::1/64 -#ifconfig graal0 192.168.14.100 -#ifconfig graal0 add 2001:690:2380:7777::1/64 -#ifconfig graal0 add 2001:660:382:14::1/64 -#lsmod \ No newline at end of file diff --git a/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_radvd b/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_radvd deleted file mode 100755 index f57fb7712d..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/start_rg_cellular_radvd +++ /dev/null @@ -1,17 +0,0 @@ - -#xterm -hold -e ant -buildfile rrm_umts.xml run & -#sleep 2 -insmod ./NASRG/nascellrg.ko -sleep 2 -#bin/access_router_noradvd.up -sysctl -w net.ipv6.conf.default.dad_transmits=0 -sysctl -w net.ipv6.conf.all.forwarding=1 -#sysctl -w net.ipv4.conf.all.forwarding=1 - -#ifconfig oai0 192.168.14.100 -ifconfig oai0 10.0.1.3 netmask 255.255.255.0 broadcast 10.0.1.255 -ifconfig oai0 add 2001:660:382:14::1/64 - -#lsmod -sleep 4s -radvd diff --git a/openair2/NAS/DRIVER/CELLULAR/stop_mt_cellular b/openair2/NAS/DRIVER/CELLULAR/stop_mt_cellular deleted file mode 100755 index e7325cf40f..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/stop_mt_cellular +++ /dev/null @@ -1,5 +0,0 @@ -#killall -qw tdcdma_gui -#killall -qw IALdummy -#./bin/mobile_node.down -rmmod -w nascellmt - diff --git a/openair2/NAS/DRIVER/CELLULAR/stop_rg_cellular b/openair2/NAS/DRIVER/CELLULAR/stop_rg_cellular deleted file mode 100755 index 88d17a7e6b..0000000000 --- a/openair2/NAS/DRIVER/CELLULAR/stop_rg_cellular +++ /dev/null @@ -1,2 +0,0 @@ -ifconfig oai0 down -rmmod -w nascellrg diff --git a/openair2/NAS/Makefile.inc b/openair2/NAS/Makefile.inc deleted file mode 100644 index a06e8f690a..0000000000 --- a/openair2/NAS/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -NAS_UE_DIR = $(OPENAIR2_TOP)/NAS - -NAS_UE_OBJS = - -NAS_UE_incl = \ - -I$(NAS_UE_DIR) diff --git a/openair2/NAS/SIMU_CELLULAR/Makefile b/openair2/NAS/SIMU_CELLULAR/Makefile deleted file mode 100755 index 26af978a4e..0000000000 --- a/openair2/NAS/SIMU_CELLULAR/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# lines starting with the pound sign are comments. -# -# These things are options that you might need -# to tweak. - - -# You can modify the below as well, but probably -# won't need to. - -include $(OPENAIR_DIR)/common/utils/Makefile.inc -#UPDIR := /homes/mwett/rh_mw/RHODOS -COMMON_DIR = $(OPENAIR2_DIR)/COMMON -RRC_CELL_DIR = $(OPENAIR2_DIR)/RRC/CELLULAR -NAS_SIMU_DIR = $(OPENAIR2_DIR)/NAS/SIMU_CELLULAR -#ASN1_DIR = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES -ASN1_DIR = $(OPENAIR2_DIR) - -#UPDIR := $(EURECOM_SRC_PATH) -#GRAAL_DIR =$(UPDIR)/non_access_stratum/driver/nasmt -#RRC_DIR =$(UPDIR)/access_stratum/l3/rrc - -#CFLAGS += -Wall -g -DDEBUG_RRC_STATE -DUSER_MODE -DNODE_RG -DNODE_MT -CFLAGS += -std=gnu99 -I$(KERNEL_DIR) -DUSER_MODE -DNB_ANTENNAS_RX=1 - -ifdef CELL_RRM -CFLAGS += -DNODE_RG -OBJ +=rrm_fifo_standalone.o nasrg_simu_meas.o -else -ifdef MASTER -CFLAGS += -DNODE_RG -OBJ +=nasrg_simu_main.o nasrg_simu_control.o nasrg_simu_rrm_fifo.o nasrg_simu_meas.o -else -CFLAGS += -DNODE_MT -OBJ +=nasmt_simu_main.o nasmt_simu_control.o -endif -endif - -ifdef CELLULAR -CFLAGS += -DCELLULAR -DNO_RRM -I$(COMMON_DIR) -I$(RRC_CELL_DIR) -I$(NAS_SIMU_DIR) -I$(ASN1_DIR) -endif - - -$(OBJ) : %.o : %.c - $(CC) $(CFLAGS) -c -o $@ $< -pthread - -all: nasmt_simu nasrg_simu - -nasmt_sim : $(OBJ) - $(CC) -o nasmt_simu $(OBJ) $(CFLAGS) -lm -lrt -pthread - mv nasmt_simu $(OPENAIR_TARGETS)/SIMU/USER - -nasrg_sim : $(OBJ) - $(CC) -o nasrg_simu $(OBJ) $(CFLAGS) -lm -lrt -pthread - mv nasrg_simu $(OPENAIR_TARGETS)/SIMU/USER - -cell_rrm : $(OBJ) - $(CC) -o cell_rrm $(OBJ) $(CFLAGS) -lm -lrt -pthread - mv cell_rrm $(OPENAIR_TARGETS)/SIMU/USER - -clean: - -rm $(OBJ) $(EXECUTABLE) - diff --git a/openair2/NAS/SIMU_CELLULAR/nas_simu_proto.h b/openair2/NAS/SIMU_CELLULAR/nas_simu_proto.h deleted file mode 100644 index 86ab7a1ec5..0000000000 --- a/openair2/NAS/SIMU_CELLULAR/nas_simu_proto.h +++ /dev/null @@ -1,54 +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 __NAS_CONTROL_H__ -#define __NAS_CONTROL_H__ - -#ifdef NODE_MT -//----------------------------------------------------------------------------- -void nas_ue_control_init (void); -//int nas_ue_DC_attach(void); -//int nas_ue_DC_attach_complete(void); -int nas_ue_GC_Rcve_FIFO (void); -int nas_ue_NT_Rcve_FIFO (void); -int nas_ue_DC_Rcve_FIFO (void); -#endif - -#ifdef NODE_RG -//----------------------------------------------------------------------------- -void nas_rg_control_init (void); -//int nas_rg_DC_ConnectMs(void) ; -int nas_rg_DC_Rcve_FIFO (int time); - -int nasrg_rrm_socket_init(void); -void nasrg_rrm_fifos_init (void); -void nasrg_rrm_to_rrc_write (void); -void nasrg_rrm_from_rrc_read (void); - -int nasrg_meas_loop (int time, int UE_Id); -void nas_rg_print_buffer (char *buffer, int length); -/*void nasrg_print_meas_report (char *rrc_rrm_meas_payload, uint16_t type); -void nasrg_print_bs_meas_report (char *rrc_rrm_meas_payload, uint16_t type);*/ -void nasrg_print_meas_report (char *rrc_rrm_meas_payload, unsigned short type); -void nasrg_print_bs_meas_report (char *rrc_rrm_meas_payload, unsigned short type); -#endif - -#endif diff --git a/openair2/NAS/SIMU_CELLULAR/nasrg_simu_meas.c b/openair2/NAS/SIMU_CELLULAR/nasrg_simu_meas.c deleted file mode 100644 index a192b82d72..0000000000 --- a/openair2/NAS/SIMU_CELLULAR/nasrg_simu_meas.c +++ /dev/null @@ -1,646 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "openair_types.h" -#include "rrc_constant.h" - -#include "rrc_msg_constant.h" -#include "rrc_rrm_primitives.h" -#include "rrc_msg_ies.h" - -#include "nas_simu_proto.h" - -extern int rrc_rg_rrm_in_fifo; - -int sim_counter=0; - -/* Mobile Station */ -//------------------------------------------------------------------- -void nasrg_meas_if_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Intra-Frequency - rrm_control->type = IX_ifM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount16; - rrm_control->period = int2000; -} - -//------------------------------------------------------------------- -void nasrg_meas_if_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Intra-Frequency - rrm_control->type = IX_ifM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; -} - -//------------------------------------------------------------------- -void nasrg_meas_tv_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Traffic Volume - rrm_control->type = IX_tvM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount_inf; - rrm_control->period = int2000; -} - -//------------------------------------------------------------------- -void nasrg_meas_tv_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Traffic Volume - rrm_control->type = IX_tvM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; -} - -//------------------------------------------------------------------- -void nasrg_meas_q_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Quality - rrm_control->type = IX_qM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount2; //for test - //rrm_control->amount = amount_inf; // for execution - rrm_control->period = int3000; -} - -//------------------------------------------------------------------- -void nasrg_meas_q_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Quality - rrm_control->type = IX_qM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; -} - -//------------------------------------------------------------------- -void nasrg_meas_int_ue_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Internal UE - rrm_control->type = IX_iueM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount8; - rrm_control->period = int1000; -} - -//------------------------------------------------------------------- -void nasrg_meas_int_ue_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Internal UE - rrm_control->type = IX_iueM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 0; - rrm_control->UE_Id = UE_Id; -} - - -/* Base Station */ -//------------------------------------------------------------------- -void nasrg_meas_bs_tv_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Traffic Volume - rrm_control->type = IX_tvbM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount_inf; - rrm_control->period = int4000; -} - -//------------------------------------------------------------------- -void nasrg_meas_bs_tv_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Traffic Volume - rrm_control->type = IX_tvbM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = UE_Id; -} - -//------------------------------------------------------------------- -void nasrg_meas_bs_q_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Quality - rrm_control->type = IX_qbM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = UE_Id; - rrm_control->amount = amount2; - rrm_control->period = int3000; -} - -//------------------------------------------------------------------- -void nasrg_meas_bs_q_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Quality - rrm_control->type = IX_qbM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = UE_Id; -} - -//------------------------------------------------------------------- -void nasrg_meas_int_bs_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Internal BS - rrm_control->type = IX_ibsM; - // measurementCommand SETUP - rrm_control->command = MC_setup; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = maxUsers; //should not be set - rrm_control->amount = amount16; - rrm_control->period = int4000; -} - -//------------------------------------------------------------------- -void nasrg_meas_int_bs_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - // measurement identity Internal BS - rrm_control->type = IX_ibsM; - // measurementCommand RELEASE - rrm_control->command = MC_release; - rrm_control->BaseStation = 1; - rrm_control->UE_Id = maxUsers; //should not be set -} - -//------------------------------------------------------------------- -void nasrg_send_meas_request_to_rrc (int ue_id, struct rrc_rrm_measure_ctl *rrm_control) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - measurement_request meas_request; - int count =0; - - printf ("[NASRG_MEAS_TEST] RPC_MEASUREMENT_REQUEST --> RRC\n "); - memset ((char*)& rpc_mess, 0, sizeof (rpc_message)); - memset ((char*)& meas_request, 0, sizeof (measurement_request)); - //build header - rpc_mess.type = RPC_MEASUREMENT_REQUEST; - rpc_mess.length = sizeof (measurement_request); - // build content - meas_request.measurement_type = rrm_control->type; - meas_request.measurement_command = rrm_control->command; - // different conding between RRM and RRC - // Mobile terminal RRC = 0, RRM = 1 - // Base Station RRC = 1, RRM = 2 - meas_request.equipment_type = rrm_control->BaseStation + 1; - meas_request.equipment_id = rrm_control->UE_Id; - meas_request.amount = rrm_control->amount; - meas_request.period = rrm_control->period; - - // send to RRC - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & meas_request, sizeof (measurement_request)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } - -#ifdef DEBUG_NAS_MEAS_SIMU - nas_rg_print_buffer ((char *) & rpc_mess, sizeof (rpc_message)); - nas_rg_print_buffer ((char *) & meas_request, sizeof (meas_request)); -#endif -} - -//------------------------------------------------------------------- -// in case not rrc_rg_meas_loop (time,UE_Id); -int nasrg_rrm_meas_stop (int time, int UE_Id) -{ - //------------------------------------------------------------------- - struct rrc_rrm_measure_ctl control; - - // Measurement Control - Stop Quality previously sent by RRM - nasrg_meas_q_release (UE_Id, &control); - //rrc_rrm_measure_request (control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - return 0; -} -//------------------------------------------------------------------- -// rrc_rg_meas_loop (time,UE_Id); -int nasrg_meas_loop (int time, int UE_Id) -{ - //------------------------------------------------------------------- - struct rrc_rrm_measure_ctl control; - - sim_counter++; - // if (time % 5 == 0) { -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n[NASRG_MEAS_TEST] Simu Measurement Time : %d, counter : %d\n", time, sim_counter); -#endif - - // } - if (sim_counter == 8) { - // Measurement Control - Stop Quality previously sent by RRM -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] NAS sends Measurement Control (Stop Quality) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_q_release (UE_Id, &control); - //rrc_rrm_measure_request (control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Intra-Frequency - // if (sim_counter == 140) { - if (sim_counter == 16) { - // Measurement Control - Start Intra-frequency -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Start Intra-freq) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_if_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 700) { - if (sim_counter == 70) { - // Measurement Control - Stop Intra-frequency -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Stop Intra-freq) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_if_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Traffic Volume - // if (sim_counter == 100) { - if (sim_counter == 12) { - // Measurement Control - Start Traffic Volume -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Start Traffic Volume) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_tv_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 990) { - if (sim_counter == 92) { - // Measurement Control - Stop Traffic Volume -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Stop Traffic Volume) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_tv_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Quality - // if (sim_counter == 503) { - if (sim_counter == 50) { - // Measurement Control - Start Quality -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Start Quality) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_q_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 995) { - if (sim_counter == 96) { - // Measurement Control - Stop Quality -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Stop Quality) message at time : %d\n\n", sim_counter); -#endif - // setup if measurement for MT - nasrg_meas_q_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Internal UE - // if (sim_counter == 210) { - if (sim_counter == 20) { - // Measurement Control - Start Internal UE -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Start Int UE) message at time : %d\n\n", sim_counter); -#endif - // setup int_ue measurement for MT - nasrg_meas_int_ue_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 999) { - if (sim_counter == 98) { - // Measurement Control - Stop Internal UE -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG sends Measurement Control (Stop Int UE) message at time : %d\n\n", sim_counter); -#endif - nasrg_meas_int_ue_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Internal BS - // if (sim_counter == 105) { - if (sim_counter == 14) { - // Measurement Control - Start Internal BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG starts internal Measurement (Int BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_int_bs_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 980) { - if (sim_counter == 86) { - // Measurement Control - Stop Internal BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG stops internal Measurement (Int BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_int_bs_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Traffic Volume BS - // if (sim_counter == 220) { - if (sim_counter == 22) { - // Measurement Control - Start Traffic Volume BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG starts internal Measurement (Traffic Volume BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_bs_tv_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 900) { - if (sim_counter == 80) { - // Measurement Control - Stop Traffic Volume BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG stops internal Measurement (Traffic Volume BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_bs_tv_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // Quality BS - // if (sim_counter == 625) { - if (sim_counter == 62) { - // Measurement Control - Start Quality BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG starts internal Measurement (Quality BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_bs_q_setup (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - // if (sim_counter == 989) { - if (sim_counter == 90) { - // Measurement Control - Stop Quality BS -#ifdef DEBUG_NAS_MEAS_SIMU - printf ("\n\n[NASRG_MEAS_TEST] RG stops internal Measurement (Quality BS) at time : %d\n\n", sim_counter); -#endif - nasrg_meas_bs_q_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - } - - return sim_counter; -} - -//----------------------------------------------------------------------------- -//void rrc_rg_print_meas_report (struct rrc_rg_mt_meas_rep *p){ -void nasrg_print_meas_report (char *rrc_rrm_meas_payload, uint16_t type) -{ - //----------------------------------------------------------------------------- - int i, j; - char *payload[20] = - { "pl0", "pl4", "pl8", "pl16", "pl32", "pl64", "pl128", "pl256", "pl512", "pl1024", "pl2k", "pl4k", "pl8k", "pl16k", "pl32k", "pl64k", "pl128k", "pl256k", "pl512k", "pl1024k" }; - char *average[20] = { - "pla0", "pla4", "pla8", "pla16", "pla32", "pla64", "pla128", "pla256", "pla512", "pla1024", "pla2k", - "pla4k", "pla8k", "pla16k", "pla32k", "pla64k", "pla128k", "pla256k", "pla512k","pla1024k" - }; - char *variance[14] = { "plv0", "plv4", "plv8", "plv16", "plv32", "plv64", "plv128", "plv256", "plv512", "plv1024", "plv2k", "plv4k", "plv8k", "plv16k" }; - - printf ("\n[NASRG-MEAS] ************** MT Measurement Report Message *****************\n"); - - switch (type) { - case RPC_L1_MEASUREMENT_MT_INTRA_FREQUENCY_REPORT: { - struct rrc_rrm_meas_report_mt_if *p; - p = (struct rrc_rrm_meas_report_mt_if *)rrc_rrm_meas_payload; - printf ("Intra Frequency Measurement\t Number of cells: %d\n", p->if_num_cells); - - for (i = 0; i < p->if_num_cells; i++) { - printf ("[NASRG-MEAS] Cell number: %d\tCell Identity: %d\tCell Parameters Id: %d\tP-CCPCH RSCP: %d\tPathloss: %d\n", i, p->if_cell_id[i], p->if_cell_parms_id[i], p->if_BCH_RSCP[i], p->if_pathloss[i]); - printf ("\tTimeslot ISCP for each slot:\t"); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d: %d, ", j, p->if_slot_iscp[i][j]); - - printf ("\n"); - } - } - break; - - case RPC_L1_MEASUREMENT_MT_TRAFFIC_VOLUME_REPORT: { - struct rrc_rrm_meas_report_mt_tv *p; - p = (struct rrc_rrm_meas_report_mt_tv *)rrc_rrm_meas_payload; - printf ("Traffic Volume Measurement -\t Number of RBs: %d\n", p->tv_num_rbs); - - for (i = 0; i < p->tv_num_rbs; i++) - printf ("[NASRG-MEAS] RB_Id : %d\t, RLC_BufferPayload : %s\t, Average : %s\t, Variance : %s\n", - p->tv_rbid[i], payload[p->tv_rb_payload[i]], average[p->tv_rb_average[i]], variance[p->tv_rb_variance[i]]); - } - break; - - case RPC_L1_MEASUREMENT_MT_QUALITY_REPORT: { - struct rrc_rrm_meas_report_mt_q *p; - p = (struct rrc_rrm_meas_report_mt_q *)rrc_rrm_meas_payload; - printf ("Quality Measurement -\t Number of Transport Channels : %d, Number of TFCS : %d\n", p->q_num_TrCH, p->q_num_tfcs); - printf ("[NASRG-MEAS] BLER for each Transport Channel:\t"); - - for (i = 0; i < p->q_num_TrCH; i++) - printf ("%d: %d, ", p->q_dl_TrCH_id[i], p->q_dl_TrCH_BLER[i]); - - printf ("\n"); - printf ("[NASRG-MEAS] SIR for each TFCS for each slot:\n"); - - for (i = 0; i < p->q_num_tfcs; i++) { - printf ("%d: ", p->q_tfcs_id[i]); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d, ", p->q_sir[i][j]); - - printf ("\n"); - } - } - break; - - case RPC_L1_MEASUREMENT_MT_INTERNAL_REPORT: { - struct rrc_rrm_meas_report_mt_int *p; - p = (struct rrc_rrm_meas_report_mt_int *)rrc_rrm_meas_payload; - printf ("UE internal Measurement\t Timing Advance: %d\n", p->int_timing_advance); - printf ("[NASRG-MEAS] Transmitted Power for each slot:\t"); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d: %d, ", j, p->int_xmit_power[j]); - - printf ("\n"); - } - break; - } - - printf ("[NASRG-MEAS] *****END********* Measurement Report Message *******\n\n"); -} - -//----------------------------------------------------------------------------- -void nasrg_print_bs_meas_report (char *rrc_rrm_meas_payload, uint16_t type) -{ - //----------------------------------------------------------------------------- - int i, j; - char *payload[20] = - { "pl0", "pl4", "pl8", "pl16", "pl32", "pl64", "pl128", "pl256", "pl512", "pl1024", "pl2k", "pl4k", "pl8k", "pl16k", "pl32k", "pl64k", "pl128k", "pl256k", "pl512k", "pl1024k" }; - char *average[20] = { - "pla0", "pla4", "pla8", "pla16", "pla32", "pla64", "pla128", "pla256", "pla512", "pla1024", "pla2k", - "pla4k", "pla8k", "pla16k", "pla32k", "pla64k", "pla128k", "pla256k", "pla512k", "pla1024k" - }; - char *variance[14] = { "plv0", "plv4", "plv8", "plv16", "plv32", "plv64", "plv128", "plv256", "plv512", "plv1024", "plv2k", "plv4k", "plv8k", "plv16k" }; - - printf ("\n[NASRG-MEAS] ************** BS Measurement Report Message *****************\n"); - - switch (type) { - case RPC_L1_MEASUREMENT_RG_TRAFFIC_VOLUME_REPORT: { - struct rrc_rrm_meas_report_bs_tv *p; - p = (struct rrc_rrm_meas_report_bs_tv *)rrc_rrm_meas_payload; - printf ("Traffic Volume Measurement -\t Number of RBs: %d\n", p->tv_num_rbs); - - for (i = 0; i < p->tv_num_rbs; i++) - printf ("[NASRG-MEAS] RB_Id : %d\t, RLC_BufferPayload : %s\t, Average : %s\t, Variance : %s\n", - p->tv_rbid[i], payload[p->tv_rb_payload[i]], average[p->tv_rb_average[i]], variance[p->tv_rb_variance[i]]); - } - break; - - case RPC_L1_MEASUREMENT_RG_QUALITY_REPORT: { - struct rrc_rrm_meas_report_bs_q *p; - p = (struct rrc_rrm_meas_report_bs_q *)rrc_rrm_meas_payload; - printf ("Quality Measurement -\t Number of Transport Channels : %d, Number of TFCS : %d\n", p->q_num_TrCH, p->q_num_tfcs); - printf ("[NASRG-MEAS] BLER for each Transport Channel:\t"); - - for (i = 0; i < p->q_num_TrCH; i++) - printf ("%d: %d, ", p->q_dl_TrCH_id[i], p->q_dl_TrCH_BLER[i]); - - printf ("\n"); - printf ("[NASRG-MEAS] SIR for each TFCS for each slot:\n"); - - for (i = 0; i < p->q_num_tfcs; i++) { - printf ("%d: ", p->q_tfcs_id[i]); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d, ", p->q_sir[i][j]); - - printf ("\n"); - } - } - break; - - case RPC_L1_MEASUREMENT_RG_INTERNAL_REPORT: { - struct rrc_rrm_meas_report_bs_int *p; - p = (struct rrc_rrm_meas_report_bs_int *)rrc_rrm_meas_payload; - printf ("BS internal Measurement\n"); - - for (i = 0; i < numANTENNAS; i++) { - printf ("[NASRG-MEAS] Transmitted Power for each slot on antenna %d : ", i); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d: %d, ", j, p->int_xmit_power[i][j]); - - printf ("\n"); - } - - for (i = 0; i < JRRM_SLOTS_PER_FRAME; i++) { - printf ("[NASRG-MEAS] RSCP for each channel on slot %d : ", i); - - for (j = 0; j < MAXCH; j++) - printf ("%d: %d, ", j, p->int_rscp[i][j]); - - printf ("\n"); - } - - for (i = 0; i < numANTENNAS; i++) { - printf ("[NASRG-MEAS] RSSI RF for each slot on antenna %d : ", i); - - for (j = 0; j < JRRM_SLOTS_PER_FRAME; j++) - printf ("%d: %d, ", j, p->int_rssi_rf[i][j]); - - printf ("\n"); - } - - for (i = 0; i < NUMSPARE; i++) { - printf ("[NASRG-MEAS] Spare value : %d: %d\n", i, p->int_spare[i]); - } - } - break; - } - - printf ("[NASRG-MEAS] *****END********* Measurement Report Message *******\n\n"); -} - diff --git a/openair2/NAS/SIMU_CELLULAR/rrm_fifo_standalone.c b/openair2/NAS/SIMU_CELLULAR/rrm_fifo_standalone.c deleted file mode 100644 index e9cefdd926..0000000000 --- a/openair2/NAS/SIMU_CELLULAR/rrm_fifo_standalone.c +++ /dev/null @@ -1,378 +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 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// -#include -#include -#include -//----------------------------------------------------------------------------- -#include "openair_types.h" -#include "rrc_constant.h" -#include "nas_simu_proto.h" - -#include "rrc_rrm_sap.h" -#include "rrc_msg_constant.h" -#include "rrc_rrm_primitives.h" - -void nasrg_meas_q_setup (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control); -void nasrg_meas_q_release (int UE_Id, struct rrc_rrm_measure_ctl *rrm_control); -void nasrg_send_meas_request_to_rrc (int ue_id, struct rrc_rrm_measure_ctl *rrm_control); -//----------------------------------------------------------------------------- -int rrc_rg_rrm_in_fifo; -int rrc_rg_rrm_out_fifo; -int tXmit_id; -#define RRM_MSG_MAX_LENGTH 1500 -struct rrc_rrm_measure_ctl control; - -//----------------------------------------------------------------------------- -// Open FIFOs for RG RRC SAPs -void nasrg_rrm_fifos_init (void) -{ - //----------------------------------------------------------------------------- - int write_flag = O_WRONLY | O_NONBLOCK | O_NDELAY; - int read_flag = O_RDONLY | O_NONBLOCK | O_NDELAY; - - // Open FIFOs - - while ((rrc_rg_rrm_in_fifo = open (RRM_INPUT_SAPI, write_flag)) < 0) { - printf ("%s returned value %d\n", RRM_INPUT_SAPI, rrc_rg_rrm_in_fifo); - fflush(stdout); - sleep (1); - } - - while ((rrc_rg_rrm_out_fifo = open (RRM_OUTPUT_SAPI, read_flag)) < 0) { - printf ("%s returned value %d\n", RRM_OUTPUT_SAPI, rrc_rg_rrm_out_fifo); - fflush(stdout); - sleep (1); - } - - printf ("FIFO RRM_INPUT_SAPI, %d\n", rrc_rg_rrm_in_fifo); - printf ("FIFO RRM_OUTPUT_SAPI, %d\n", rrc_rg_rrm_out_fifo); -} - -//------------------------------------------------------------------- -void rrm_connection_response (void) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - connection_response response; - int count=0; - char *sim_data = "Void configuration\0"; - - printf ("[CELL-RRM] RPC_CONNECTION_RESPONSE --> RRC\n "); - rpc_mess.type = RPC_CONNECTION_RESPONSE; - rpc_mess.length = sizeof (connection_response)+ strlen (sim_data); - response.equipment_id = 0; - response.status = STATUS_CONNECTION_ACCEPTED; - - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & confirm, sizeof (add_user_confirm)); - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & response, sizeof (connection_response)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) sim_data, strlen (sim_data)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } -} - -//------------------------------------------------------------------- -void rrm_add_user_response (char *rcve_buffer) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - add_user_response response; - add_user_request *request; - int count=0; - char *sim_data = "Void configuration\0"; - - request = (add_user_request *)rcve_buffer; - printf ("[CELL-RRM] RPC_ADD_USER_RESPONSE --> RRC\n "); - rpc_mess.type = RPC_ADD_USER_RESPONSE; - rpc_mess.length = sizeof (add_user_response)+ strlen (sim_data); - response.equipment_id = 0; - response.user_id = request->user_id; - response.tx_id = request->tx_id; - response.status = ADD_USER_SUCCESSFUL; - - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & confirm, sizeof (add_user_confirm)); - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & response, sizeof (add_user_response)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) sim_data, strlen (sim_data)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } -} - -//------------------------------------------------------------------- -void rrm_remove_user_response (char *rcve_buffer) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - remove_user_response response; - remove_user_request *request; - int count=0; - char *sim_data = "Void configuration\0"; - - request = (remove_user_request *)rcve_buffer; - printf ("[CELL-RRM] RPC_REMOVE_USER_RESPONSE --> RRC\n "); - rpc_mess.type = RPC_REMOVE_USER_RESPONSE; - rpc_mess.length = sizeof (remove_user_response)+ strlen (sim_data); - response.equipment_id = 0; - response.user_id = request->user_id; - response.tx_id = request->tx_id; - response.status = REMOVE_USER_SUCCESSFUL; - - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & confirm, sizeof (add_user_confirm)); - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & response, sizeof (remove_user_response)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) sim_data, strlen (sim_data)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } - - /* Not sure it is really needed here - usleep (5000); //wait 5ms - // stop q measurement for MT - nasrg_meas_q_release (UE_Id, &control); - nasrg_send_meas_request_to_rrc (UE_Id, &control); - */ -} - -//------------------------------------------------------------------- -void rrm_add_radio_access_bearer_response (char *rcve_buffer) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - add_radio_access_bearer_response response; - add_radio_access_bearer_request *request; - int count=0; - char *sim_data = "Void configuration\0"; - - request = (add_radio_access_bearer_request *)rcve_buffer; - printf ("[CELL-RRM] RPC_ADD_RADIO_ACCESS_BEARER_RESPONSE --> RRC\n "); - rpc_mess.type = RPC_ADD_RADIO_ACCESS_BEARER_RESPONSE; - rpc_mess.length = sizeof (add_radio_access_bearer_response)+ strlen (sim_data); - response.user_id = request->user_id; - response.rab_id = request->rab_id; - response.tx_id = request->tx_id; - response.status = ADD_RADIO_ACCESS_BEARER_SUCCESSFUL; - - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & confirm, sizeof (add_user_confirm)); - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & response, sizeof (add_radio_access_bearer_response)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) sim_data, strlen (sim_data)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } -} - -//------------------------------------------------------------------- -void rrm_add_measurement_request (char *rcve_buffer) -{ - //------------------------------------------------------------------- - add_radio_access_bearer_confirm *confirm; - - confirm = (add_radio_access_bearer_confirm *)rcve_buffer; - printf ("[CELL-RRM] RPC_L1_MEASUREMENT_MT_QUALITY_REPORT --> RRC\n "); - - // TEMP removed the Meas request (causes bothe messages to be received together by RRC RG - // usleep (20000); //wait 5ms - // setup q measurement for MT - nasrg_meas_q_setup (confirm->user_id, &control); - nasrg_send_meas_request_to_rrc (confirm->user_id, &control); - -} - - -//------------------------------------------------------------------- -void rrm_remove_radio_access_bearer_response (char *rcve_buffer) -{ - //------------------------------------------------------------------- - rpc_message rpc_mess; - remove_radio_access_bearer_response response; - remove_radio_access_bearer_request *request; - int count=0; - char *sim_data = "Void configuration\0"; - - request = (remove_radio_access_bearer_request *)rcve_buffer; - printf ("[CELL-RRM] RPC_REMOVE_RADIO_ACCESS_BEARER_RESPONSE --> RRC\n "); - rpc_mess.type = RPC_REMOVE_RADIO_ACCESS_BEARER_RESPONSE; - rpc_mess.length = sizeof (remove_radio_access_bearer_response)+ strlen (sim_data); - response.user_id = request->user_id; - response.rab_id = request->rab_id; - response.tx_id = request->tx_id; - response.status = REMOVE_RADIO_ACCESS_BEARER_SUCCESSFUL; - - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - //count = rtf_put (protocol_bs->rrc.rc_rrm.output_fifo, (uint8_t *) & confirm, sizeof (add_user_confirm)); - count = write(rrc_rg_rrm_in_fifo, (uint8_t *) & rpc_mess, sizeof (rpc_message)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) & response, sizeof (remove_radio_access_bearer_response)); - count += write(rrc_rg_rrm_in_fifo, (uint8_t *) sim_data, strlen (sim_data)); - - if (count > 0) { - printf ("RRM message sent successfully on RRM FIFO, length: %d\n", count); - } else { - printf ("RRM FIFO transmit failed"); - } - - usleep (20000); //wait 5ms - // stop q measurement for MT - nasrg_meas_q_release (request->user_id, &control); - nasrg_send_meas_request_to_rrc (request->user_id, &control); -} - - -//----------------------------------------------------------------------------- -// Check if anything in RRC FIFO and send it to RRM -void nasrg_rrm_from_rrc_read (void) -{ - //----------------------------------------------------------------------------- - char rcve_buffer[RRM_MSG_MAX_LENGTH]; - int rpc_header_size=0; - int count = 0; - rpc_message *rrc_rrm_mess; - char *rrc_rrm_meas_payload; - - memset (rcve_buffer, 0, RRM_MSG_MAX_LENGTH - 1); - rpc_header_size = sizeof (rpc_message); - rrc_rrm_mess = (rpc_message *) rcve_buffer; - - if ((count = read (rrc_rg_rrm_out_fifo, rcve_buffer, rpc_header_size)) > 0) { - //printf("\n RRM FIFO %d, bytes count %d", rrc_rg_rrm_out_fifo, count); -#ifdef DEBUG_RRC_RRM_INTF - printf ("\n [DEBUG]Message Received in RRM FIFO %d , length %d, type %d \n", rrc_rg_rrm_out_fifo, rrc_rrm_mess->length, rrc_rrm_mess->type); -#endif - //get the rest of the primitive - count += read (rrc_rg_rrm_out_fifo, &(rcve_buffer[rpc_header_size]), rrc_rrm_mess->length ); - - switch (rrc_rrm_mess->type) { - case RPC_CONNECTION_REQUEST: - printf ("\n[CELL-RRM]Received RPC_CONNECTION_REQUEST, length %d\n", rrc_rrm_mess->length); - rrm_connection_response(); - break; - - case RPC_ADD_USER_REQUEST: - printf ("\n[CELL-RRM]Received RPC_ADD_USER_REQUEST, length %d\n", rrc_rrm_mess->length); - rrm_add_user_response(&(rcve_buffer[rpc_header_size])); - break; - - case RPC_REMOVE_USER_REQUEST: - printf ("\n[CELL-RRM]Received RPC_REMOVE_USER_REQUEST, length %d\n", rrc_rrm_mess->length); - rrm_remove_user_response(&(rcve_buffer[rpc_header_size])); - break; - - case RPC_ADD_RADIO_ACCESS_BEARER_REQUEST: - printf ("\n[CELL-RRM]Received RPC_ADD_RADIO_ACCESS_BEARER_REQUEST, length %d\n", rrc_rrm_mess->length); - rrm_add_radio_access_bearer_response(&(rcve_buffer[rpc_header_size])); - break; - - case RPC_REMOVE_RADIO_ACCESS_BEARER_REQUEST: - printf ("\n[CELL-RRM]Received RPC_REMOVE_RADIO_ACCESS_BEARER_REQUEST, length %d\n", rrc_rrm_mess->length); - rrm_remove_radio_access_bearer_response(&(rcve_buffer[rpc_header_size])); - break; - - case RPC_ADD_USER_CONFIRM: - printf ("\n[CELL-RRM]Received RPC RPC_ADD_USER_CONFIRM , length %d\n", rrc_rrm_mess->length); - break; - - case RPC_ADD_RADIO_ACCESS_BEARER_CONFIRM: - printf ("\n[CELL-RRM]Received RPC RPC_ADD_RADIO_ACCESS_BEARER_CONFIRM , length %d\n", rrc_rrm_mess->length); - //rrm_add_measurement_request(&(rcve_buffer[rpc_header_size])); - break; - - case RPC_L1_MEASUREMENT_RG_INTERNAL_REPORT: - case RPC_L1_MEASUREMENT_RG_QUALITY_REPORT: - case RPC_L1_MEASUREMENT_RG_TRAFFIC_VOLUME_REPORT: - rrc_rrm_meas_payload = (char *)rcve_buffer +12; //12 = rpc_header + equipment_id - //nas_rg_print_buffer (rrc_rrm_meas_payload, rrc_rrm_mess->length); - nasrg_print_bs_meas_report (rrc_rrm_meas_payload,rrc_rrm_mess->type); - break; - - case RPC_L1_MEASUREMENT_MT_INTERNAL_REPORT: - case RPC_L1_MEASUREMENT_MT_QUALITY_REPORT: - case RPC_L1_MEASUREMENT_MT_TRAFFIC_VOLUME_REPORT: - case RPC_L1_MEASUREMENT_MT_INTRA_FREQUENCY_REPORT: - rrc_rrm_meas_payload = (char *)rcve_buffer +12; //12 = rpc_header + equipment_id - //nas_rg_print_buffer (rrc_rrm_meas_payload, rrc_rrm_mess->length); - nasrg_print_meas_report (rrc_rrm_meas_payload,rrc_rrm_mess->type); - break; - - default: - break; - } - - fflush(stdout); - } -} - - -//----------------------------------------------------------------------------- -int main (int argc, char **argv) -{ - //----------------------------------------------------------------------------- - int time = 0; - // int rc, sd_rrm; - // fd_set readfds; - // struct timeval tv; - tXmit_id =0; - nasrg_rrm_fifos_init (); - printf ("[RRM] RRM FIFOs ready\n"); - fflush(stdout); - - while (1) { - usleep (100000); - time ++; - //printf ("\n[RRM_TEST] Simu Measurement Time at Main: %d\n", time); - - // check RRM FIFO - nasrg_rrm_from_rrc_read(); - } -} diff --git a/openair2/NETWORK_DRIVER/LITE/Makefile b/openair2/NETWORK_DRIVER/LITE/Makefile deleted file mode 100755 index 76ba3b5bdb..0000000000 --- a/openair2/NETWORK_DRIVER/LITE/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# NASMESH Driver makefile -# -include $(OPENAIR_DIR)/common/utils/Makefile.inc -NAS_UPDIR := $(shell /bin/pwd) - -KERNEL_ARCH:=$(shell echo `uname -m`) -SET_X64:=$(shell if [ $(KERNEL_ARCH) = 'x86_64' ]; then echo true ; fi) - -#################################################### -# EXTRA COMPILER FLAGS -#################################################### -EXTRA_CFLAGS = -I$(OPENAIR2_DIR)/COMMON -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) - -ifdef ADDRCONF -EXTRA_CFLAGS += -DADDRCONF -endif - -ifdef OAI_NW_DRIVER_TYPE_ETHERNET -EXTRA_CFLAGS += -DOAI_NW_DRIVER_TYPE_ETHERNET -endif - -ifdef OAI_NW_DRIVER_USE_NETLINK -EXTRA_CFLAGS += -DOAI_NW_DRIVER_USE_NETLINK -else -EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall -endif - -ccflags-y= $(CFLAGS) $(EXTRA_CFLAGS) -CFLAGS= - -ifdef LOOPBACK -EXTRA_CFLAGS += -DLOOPBACK_TEST -endif - -ifdef ADDRESS_FIX -EXTRA_CFLAGS += -DNAS_ADDRESS_FIX -endif - -#################################################### -# LOADABLE MODULE GOALS -#################################################### -obj-m += oai_nw_drv.o -oai_nw_drv-objs += device.o -oai_nw_drv-objs += common.o -oai_nw_drv-objs += ioctl.o -oai_nw_drv-objs += classifier.o -oai_nw_drv-objs += tool.o -ifdef OAI_NW_DRIVER_USE_NETLINK -oai_nw_drv-objs += netlink.o -endif - -#################################################### -# REVOIR LE CLEAN -#################################################### - -#netlink.ko: - #make $(x)$(y) PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR) M=`pwd` modules - -#oai_nw_drv.ko: -# make V=1 -C $(KERNEL_DIR) M=`pwd` modules -print: - @echo subversion : $(SUBVERSION) -clean: - rm -f *.ko - rm -f .*.ko.cmd - rm -f .*.o.cmd - rm -f *.o - rm -f *.mod.c - find . -name *.ko -delete - find . -name .*.o -delete - find . -name *.o -delete - find . -name *.mod.c -delete diff --git a/openair2/NETWORK_DRIVER/LITE/device.c b/openair2/NETWORK_DRIVER/LITE/device.c index fe60d82c15..854c3bcc99 100644 --- a/openair2/NETWORK_DRIVER/LITE/device.c +++ b/openair2/NETWORK_DRIVER/LITE/device.c @@ -28,13 +28,6 @@ */ /*******************************************************************************/ -#ifndef OAI_NW_DRIVER_USE_NETLINK -#ifdef RTAI -#include "rtai_posix.h" -#define RTAI_IRQ 30 //try to get this irq with RTAI -#endif // RTAI -#endif // OAI_NW_DRIVER_USE_NETLINK - #include "constant.h" #include "local.h" #include "proto_extern.h" @@ -519,23 +512,12 @@ int init_module (void) #ifndef OAI_NW_DRIVER_USE_NETLINK -#ifdef RTAI //with RTAI you have to indicate which irq# you want - - pdcp_2_oai_nw_drv_irq=rt_request_srq(0, oai_nw_drv_interrupt, NULL); - -#endif - if (pdcp_2_oai_nw_drv_irq == -EBUSY || pdcp_2_oai_nw_drv_irq == -EINVAL) { printk("[OAI_IP_DRV][%s] No interrupt resource available\n", __FUNCTION__); return -EBUSY; } else printk("[OAI_IP_DRV][%s] Interrupt %d\n", __FUNCTION__, pdcp_2_oai_nw_drv_irq); - //rt_startup_irq(RTAI_IRQ); - - //rt_enable_irq(RTAI_IRQ); - - #endif //NETLINK for (inst=0; instirq, NULL); - // END V1 - rt_free_srq(pdcp_2_oai_nw_drv_irq); -#endif // Start IRQ linux //free_irq(priv->irq, NULL); // End IRQ linux diff --git a/openair2/NETWORK_DRIVER/MESH/Makefile b/openair2/NETWORK_DRIVER/MESH/Makefile deleted file mode 100755 index f4bf87f318..0000000000 --- a/openair2/NETWORK_DRIVER/MESH/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# NASMESH Driver makefile -# -include $(OPENAIR_DIR)/common/utils/Makefile.inc -NAS_UPDIR := $(shell /bin/pwd) - -#################################################### -# NASMESH compilation flags -#################################################### -#RTAI=1 - -#################################################### -# D E B U G F L A G S -#################################################### - -#################################################### -# EXTRA COMPILER FLAGS -#################################################### -#EXTRA_CFLAGS = -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,) -EXTRA_CFLAGS += -I$(OPENAIR2_DIR) -ifdef PDCP_USE_NETLINK -EXTRA_CFLAGS += -DPDCP_USE_NETLINK -else -EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall -endif - -ifdef LOOPBACK -EXTRA_CFLAGS += -DLOOPBACK_TEST -endif - -ifdef ADDRESS_FIX -EXTRA_CFLAGS += -DNAS_ADDRESS_FIX -endif -ifdef NAS_DEBUG_RECEIVE -EXTRA_CFLAGS += -DNAS_DEBUG_RECEIVE -endif - -ifdef NAS_DEBUG_SEND -EXTRA_CFLAGS += -DNAS_DEBUG_SEND -endif - -ccflags-y := $(CFLAGS) $(EXTRA_CFLAGS) -CFLAGS= - -#################################################### -# LOADABLE MODULE GOALS -#################################################### -obj-m += nasmesh.o -nasmesh-objs += device.o -nasmesh-objs += common.o -nasmesh-objs += ioctl.o -nasmesh-objs += classifier.o -nasmesh-objs += tool.o -nasmesh-objs += mesh.o -ifdef PDCP_USE_NETLINK -nasmesh-objs += netlink.o -endif - -#################################################### -# REVOIR LE CLEAN -#################################################### - -#netlink.ko: -# make PDCP_USE_NETLINK=1 V=1 -C $(KERNEL_DIR) M=`pwd` modules - -#nasmesh.ko: -# make V=1 -C $(KERNEL_DIR) M=`pwd` modules - -clean: - rm -f $(nasmesh-objs) $(obj-m) -# make -C $(KERNEL_DIR) modules diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index 0eb7530ee6..d380b8a4d8 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -28,12 +28,8 @@ * \email: navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr */ -//#include "nas_common.h" #include "local.h" #include "proto_extern.h" -#ifdef RTAI -#include "rtai_fifos.h" -#endif //#define NAS_DEBUG_RECEIVE 1 //#define NAS_DEBUG_SEND 1 diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index f9bc592bce..086ec3909c 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -28,13 +28,6 @@ */ /*******************************************************************************/ -#ifndef PDCP_USE_NETLINK -#ifdef RTAI -#include "rtai_posix.h" -#define RTAI_IRQ 30 //try to get this irq with RTAI -#endif // RTAI -#endif // PDCP_USE_NETLINK - #include "constant.h" #include "local.h" #include "proto_extern.h" @@ -116,6 +109,7 @@ void *nas_interrupt(void) printk("INTERRUPT: end\n"); #endif // return 0; + return NULL; } #endif //NETLINK @@ -449,23 +443,12 @@ int init_module (void) #ifndef PDCP_USE_NETLINK -#ifdef RTAI //with RTAI you have to indicate which irq# you want - - pdcp_2_nas_irq=rt_request_srq(0, nas_interrupt, NULL); - -#endif - if (pdcp_2_nas_irq == -EBUSY || pdcp_2_nas_irq == -EINVAL) { printk("[NAS][INIT] No interrupt resource available\n"); return -EBUSY; } else printk("[NAS][INIT]: Interrupt %d\n", pdcp_2_nas_irq); - //rt_startup_irq(RTAI_IRQ); - - //rt_enable_irq(RTAI_IRQ); - - #endif //NETLINK for (inst=0; instirq, NULL); - // END V1 - rt_free_srq(pdcp_2_nas_irq); -#endif // Start IRQ linux // free_irq(priv->irq, NULL); // End IRQ linux diff --git a/openair2/NETWORK_DRIVER/UE_IP/Makefile b/openair2/NETWORK_DRIVER/UE_IP/Makefile deleted file mode 100755 index fbcf85fabb..0000000000 --- a/openair2/NETWORK_DRIVER/UE_IP/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# UE IP Driver makefile -# -NAS_UPDIR := $(shell /bin/pwd) - -KERNEL_ARCH=$(shell echo `uname -m`) -SET_X64=$(shell if [ $(KERNEL_ARCH) = 'x86_64' ]; then echo true ; fi) - -#################################################### -# EXTRA COMPILER FLAGS -#################################################### -EXTRA_CFLAGS = -I$(OPENAIR2_DIR)/COMMON -fno-common -fno-stack-protector -mpreferred-stack-boundary=4 $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,) - - - -ifdef OAI_NW_DRIVER_USE_NETLINK -EXTRA_CFLAGS += -DOAI_NW_DRIVER_USE_NETLINK -else -EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall -endif - - -#################################################### -# LOADABLE MODULE GOALS -#################################################### -obj-m += ue_ip.o -ue_ip-objs += device.o -ue_ip-objs += common.o -ifdef OAI_NW_DRIVER_USE_NETLINK -ue_ip-objs += netlink.o -endif - -#################################################### -# REVOIR LE CLEAN -#################################################### - - -print: - @echo SET_X64 : $(SET_X64) - -clean: - rm -f *.ko - rm -f .*.ko.cmd - rm -f .*.o.cmd - rm -f *.o - rm -f *.mod.c - find . -name *.ko -delete - find . -name .*.o -delete - find . -name *.o -delete - find . -name *.mod.c -delete diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index a4398e9d9e..29db4ae07a 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -28,13 +28,6 @@ */ /*******************************************************************************/ -#ifndef OAI_NW_DRIVER_USE_NETLINK -#ifdef RTAI -#include "rtai_posix.h" -#define RTAI_IRQ 30 //try to get this irq with RTAI -#endif // RTAI -#endif // OAI_NW_DRIVER_USE_NETLINK - #include "constant.h" #include "local.h" #include "proto_extern.h" diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index ab6551f61c..d0b8e57558 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -10,21 +10,29 @@ IF_Module_t *if_inst[MAX_IF_MODULES]; Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; +extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); +extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); +extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); +extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); +extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); +extern uint8_t nfapi_mode; +extern uint16_t sf_ahead; + void handle_rach(UL_IND_t *UL_info) { int i; - if (UL_info->rach_ind.number_of_preambles>0) { + if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_info->rach_ind.number_of_preambles==1,"More than 1 preamble not supported\n"); - UL_info->rach_ind.number_of_preambles=0; - LOG_D(MAC,"Frame %d, Subframe %d Calling initiate_ra_proc\n",UL_info->frame,UL_info->subframe); + 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, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf)); initiate_ra_proc(UL_info->module_id, UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->rach_ind.preamble_list[0].preamble_rel8.preamble, - UL_info->rach_ind.preamble_list[0].preamble_rel8.timing_advance, - UL_info->rach_ind.preamble_list[0].preamble_rel8.rnti + 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 #ifdef Rel14 ,0 #endif @@ -32,24 +40,24 @@ void handle_rach(UL_IND_t *UL_info) { } #ifdef Rel14 - if (UL_info->rach_ind_br.number_of_preambles>0) { + if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_info->rach_ind_br.number_of_preambles<5,"More than 4 preambles not supported\n"); - for (i=0;irach_ind_br.number_of_preambles;i++) { - AssertFatal(UL_info->rach_ind_br.preamble_list[i].preamble_rel13.rach_resource_type>0, + AssertFatal(UL_info->rach_ind_br.rach_indication_body.number_of_preambles<5,"More than 4 preambles not supported\n"); + for (i=0;irach_ind_br.rach_indication_body.number_of_preambles;i++) { + AssertFatal(UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type>0, "Got regular PRACH preamble, not BL/CE\n"); LOG_D(MAC,"Frame %d, Subframe %d Calling initiate_ra_proc (CE_level %d)\n",UL_info->frame,UL_info->subframe, - UL_info->rach_ind_br.preamble_list[i].preamble_rel13.rach_resource_type-1); + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type-1); initiate_ra_proc(UL_info->module_id, UL_info->CC_id, UL_info->frame, UL_info->subframe, - UL_info->rach_ind_br.preamble_list[i].preamble_rel8.preamble, - UL_info->rach_ind_br.preamble_list[i].preamble_rel8.timing_advance, - UL_info->rach_ind_br.preamble_list[i].preamble_rel8.rnti, - UL_info->rach_ind_br.preamble_list[i].preamble_rel13.rach_resource_type); + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.preamble, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.timing_advance, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.rnti, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type); } - UL_info->rach_ind.number_of_preambles=0; + UL_info->rach_ind_br.rach_indication_body.number_of_preambles=0; } #endif } @@ -58,91 +66,164 @@ void handle_sr(UL_IND_t *UL_info) { int i; - for (i=0;isr_ind.number_of_srs;i++) - SR_indication(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->sr_ind.sr_pdu_list[i].rx_ue_information.rnti, - UL_info->sr_ind.sr_pdu_list[i].ul_cqi_information.ul_cqi); + if (nfapi_mode == 1) // PNF + { + if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) + { + oai_nfapi_sr_indication(&UL_info->sr_ind); + } + } + else + { + for (i=0;isr_ind.sr_indication_body.number_of_srs;i++) + SR_indication(UL_info->module_id, + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + 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.number_of_srs=0; + UL_info->sr_ind.sr_indication_body.number_of_srs=0; } void handle_cqi(UL_IND_t *UL_info) { int i; - for (i=0;icqi_ind.number_of_cqis;i++) - cqi_indication(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, - &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); + if (nfapi_mode == 1) + { + if (UL_info->cqi_ind.number_of_cqis>0) + { + LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.number_of_cqis); + nfapi_cqi_indication_t ind; - UL_info->cqi_ind.number_of_cqis=0; + ind.header.message_id = NFAPI_RX_CQI_INDICATION; + ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; + ind.cqi_indication_body = UL_info->cqi_ind; + + oai_nfapi_cqi_indication(&ind); + + UL_info->cqi_ind.number_of_cqis=0; + } + } + else + { + for (i=0;icqi_ind.number_of_cqis;i++) + cqi_indication(UL_info->module_id, + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, + &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; + } } void handle_harq(UL_IND_t *UL_info) { int i; - for (i=0;iharq_ind.number_of_harqs;i++) - harq_indication(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - &UL_info->harq_ind.harq_pdu_list[i]); + 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); - UL_info->harq_ind.number_of_harqs=0; + 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 (i=0;iharq_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_ulsch(UL_IND_t *UL_info) { int i,j; - for (i=0;irx_ind.number_of_pdus;i++) { + if(nfapi_mode == 1) + { + if (UL_info->crc_ind.crc_indication_body.number_of_crcs>0) + { + //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); - for (j=0;jcrc_ind.number_of_crcs;j++) { - // find crc_indication j corresponding rx_indication i - 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) { - if (UL_info->crc_ind.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication - LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti, - (uint8_t *)NULL, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } - else { - LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); - rx_sdu(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti, - UL_info->rx_ind.rx_pdu_list[i].data, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } - 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;jcrc_ind.number_of_crcs;j++) { - AssertFatal(jcrc_ind.number_of_crcs,"Couldn't find matchin CRC indication\n"); - } // for (i=0;irx_ind.number_of_pdus;i++) { - - UL_info->rx_ind.number_of_pdus=0; - UL_info->crc_ind.number_of_crcs=0; + oai_nfapi_crc_indication(&UL_info->crc_ind); + + UL_info->crc_ind.crc_indication_body.number_of_crcs = 0; + } + + if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0) + { + //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); + oai_nfapi_rx_ind(&UL_info->rx_ind); + UL_info->rx_ind.rx_indication_body.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 (i=0;irx_ind.rx_indication_body.number_of_pdus;i++) { + for (j=0;jcrc_ind.crc_indication_body.number_of_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); + 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_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication + LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); + 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->subframe, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.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); + } + else { + LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); + 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->subframe, + 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); + } + 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;jcrc_ind.crc_indication_body.number_of_crcs;j++) + } // for (i=0;irx_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->subframe && 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->subframe); + } + } } /****************************************************************************/ @@ -203,24 +284,24 @@ static void dump_ul(UL_IND_t *u) A("XXXX UL mod %d CC %d f.sf %d.%d\n", u->module_id, u->CC_id, u->frame, u->subframe); - A("XXXX harq_ind %d\n", u->harq_ind.number_of_harqs); - for (i = 0; i < u->harq_ind.number_of_harqs; i++) { - nfapi_harq_indication_pdu_t *v = &u->harq_ind.harq_pdu_list[i]; + A("XXXX harq_ind %d\n", u->harq_ind.harq_indication_body.number_of_harqs); + for (i = 0; i < u->harq_ind.harq_indication_body.number_of_harqs; i++) { + nfapi_harq_indication_pdu_t *v = &u->harq_ind.harq_indication_body.harq_pdu_list[i]; A("XXXX harq ind %d\n", i); - A("XXXX rnti %d\n", v->rx_ue_information.rnti); - A("XXXX tb1 %d tb2 %d\n", v->harq_indication_fdd_rel8.harq_tb1, - v->harq_indication_fdd_rel8.harq_tb2); - A("XXXX number_of_ack_nack %d\n", - v->harq_indication_fdd_rel9.number_of_ack_nack); + A("XXXX rnti %d\n", v->rx_ue_information.rnti); + A("XXXX tb1 %d tb2 %d\n", v->harq_indication_fdd_rel8.harq_tb1, + v->harq_indication_fdd_rel8.harq_tb2); + A("XXXX number_of_ack_nack %d\n", + v->harq_indication_fdd_rel9.number_of_ack_nack); A("XXXX harq[0] = %d\n", v->harq_indication_fdd_rel9.harq_tb_n[0]); A("XXXX harq ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, - v->ul_cqi_information.channel); + v->ul_cqi_information.channel); } - A("XXXX crc_ind %d\n", u->crc_ind.number_of_crcs); + A("XXXX crc_ind %d\n", u->crc_ind.crc_indication_body.number_of_crcs); - A("XXXX sr_ind %d\n", u->sr_ind.number_of_srs); + A("XXXX sr_ind %d\n", u->sr_ind.sr_indication_body.number_of_srs); A("XXXX cqi_ind %d\n", u->cqi_ind.number_of_cqis); for (i = 0; i < u->cqi_ind.number_of_cqis; i++) { @@ -230,11 +311,11 @@ static void dump_ul(UL_IND_t *u) v->ul_cqi_information.channel); } - A("XXXX rach_ind %d\n", u->rach_ind.number_of_preambles); + A("XXXX rach_ind %d\n", u->rach_ind.rach_indication_body.number_of_preambles); - A("XXXX rx_ind %d\n", u->rx_ind.number_of_pdus); - for (i = 0; i < u->rx_ind.number_of_pdus; i++) { - nfapi_rx_indication_pdu_t *v = &u->rx_ind.rx_pdu_list[i]; + A("XXXX rx_ind %d\n", u->rx_ind.rx_indication_body.number_of_pdus); + for (i = 0; i < u->rx_ind.rx_indication_body.number_of_pdus; i++) { + nfapi_rx_indication_pdu_t *v = &u->rx_ind.rx_indication_body.rx_pdu_list[i]; A("XXXX rx ind %d\n", i); A("XXXX timing_advance %d\n", v->rx_indication_rel8.timing_advance); @@ -461,26 +542,29 @@ void UL_indication(UL_IND_t *UL_info) IF_Module_t *ifi = if_inst[module_id]; eNB_MAC_INST *mac = RC.mac[module_id]; - LOG_D(PHY,"UL_Indication: frame %d, subframe %d, module_id %d, CC_id %d\n", - UL_info->frame,UL_info->subframe, - module_id,CC_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", + UL_info->frame,UL_info->subframe, + 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); - if (ifi->CC_mask==0) { - ifi->current_frame = UL_info->frame; - ifi->current_subframe = UL_info->subframe; + if (nfapi_mode != 1) + { + if (ifi->CC_mask==0) { + ifi->current_frame = UL_info->frame; + ifi->current_subframe = UL_info->subframe; + } + else { + AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask); + AssertFatal(UL_info->subframe != ifi->current_subframe,"CC_mask %x is not full and subframe has changed\n",ifi->CC_mask); + } + ifi->CC_mask |= (1<frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask); - AssertFatal(UL_info->subframe != ifi->current_subframe,"CC_mask %x is not full and subframe has changed\n",ifi->CC_mask); - } - ifi->CC_mask |= (1<frame,UL_info->subframe); - handle_rach(UL_info); handle_sr(UL_info); @@ -489,61 +573,68 @@ void UL_indication(UL_IND_t *UL_info) handle_harq(UL_info); - // clear HI prior to hanling ULSCH + // clear HI prior to handling ULSCH mac->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi = 0; handle_ulsch(UL_info); - if (ifi->CC_mask == ((1<CC_mask == ((1<frame+((UL_info->subframe>5)?1:0)) % 1024, - (UL_info->subframe+4)%10); + eNB_dlsch_ulsch_scheduler(module_id, + (UL_info->frame+((UL_info->subframe>(9-sf_ahead))?1:0)) % 1024, + (UL_info->subframe+sf_ahead)%10); - ifi->CC_mask = 0; + ifi->CC_mask = 0; - sched_info->module_id = module_id; - sched_info->CC_id = CC_id; - sched_info->frame = (UL_info->frame + ((UL_info->subframe>5) ? 1 : 0)) % 1024; - sched_info->subframe = (UL_info->subframe+4)%10; - sched_info->DL_req = &mac->DL_req[CC_id]; - sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id]; - if ((mac->common_channels[CC_id].tdd_Config==NULL) || - (is_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+4)%10)>0)) - sched_info->UL_req = &mac->UL_req[CC_id]; - else - sched_info->UL_req = NULL; + sched_info->module_id = module_id; + sched_info->CC_id = CC_id; + sched_info->frame = (UL_info->frame + ((UL_info->subframe>(9-sf_ahead)) ? 1 : 0)) % 1024; + sched_info->subframe = (UL_info->subframe+sf_ahead)%10; + sched_info->DL_req = &mac->DL_req[CC_id]; + sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id]; + if ((mac->common_channels[CC_id].tdd_Config==NULL) || + (is_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+sf_ahead)%10)>0)) + sched_info->UL_req = &mac->UL_req[CC_id]; + else + sched_info->UL_req = NULL; - sched_info->TX_req = &mac->TX_req[CC_id]; + sched_info->TX_req = &mac->TX_req[CC_id]; #ifdef DUMP_FAPI - dump_dl(sched_info); + dump_dl(sched_info); #endif - AssertFatal(ifi->schedule_response!=NULL, - "UL_indication is null (mod %d, cc %d)\n", - module_id, - CC_id); - ifi->schedule_response(sched_info); + if (ifi->schedule_response) + { + AssertFatal(ifi->schedule_response!=NULL, + "schedule_response is null (mod %d, cc %d)\n", + module_id, + CC_id); + ifi->schedule_response(sched_info); + } - LOG_D(PHY,"Schedule_response: frame %d, subframe %d (dl_pdus %d / %p)\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu, - &sched_info->DL_req->dl_config_request_body.number_pdu); - } + 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); + } + } } IF_Module_t *IF_Module_init(int Mod_id){ AssertFatal(Mod_id %d\n",Mod_id,MAX_IF_MODULES); + LOG_D(PHY,"Installing callbacks for IF_Module - UL_indication\n"); + if (if_inst[Mod_id]==NULL) { if_inst[Mod_id] = (IF_Module_t*)malloc(sizeof(IF_Module_t)); memset((void*)if_inst[Mod_id],0,sizeof(IF_Module_t)); - + if_inst[Mod_id]->CC_mask=0; if_inst[Mod_id]->UL_indication = UL_indication; AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0, - "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); + "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); } return if_inst[Mod_id]; } diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index e33a8291e2..7baae6c3b6 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -61,30 +61,30 @@ typedef struct{ sub_frame_t subframe; /// harq indication list - nfapi_harq_indication_body_t harq_ind; + nfapi_harq_indication_t harq_ind; /// crc indication list - nfapi_crc_indication_body_t crc_ind; + nfapi_crc_indication_t crc_ind; /// SR indication list - nfapi_sr_indication_body_t sr_ind; + nfapi_sr_indication_t sr_ind; /// CQI indication list nfapi_cqi_indication_body_t cqi_ind; /// RACH indication list - nfapi_rach_indication_body_t rach_ind; + nfapi_rach_indication_t rach_ind; #ifdef Rel14 /// RACH indication list for BR UEs - nfapi_rach_indication_body_t rach_ind_br; + nfapi_rach_indication_t rach_ind_br; #endif /// SRS indication list nfapi_srs_indication_body_t srs_ind; /// RX indication - nfapi_rx_indication_body_t rx_ind; + nfapi_rx_indication_t rx_ind; } UL_IND_t; diff --git a/openair2/PHY_INTERFACE/mac_phy_primitives.c b/openair2/PHY_INTERFACE/mac_phy_primitives.c index 3d42393d11..06e06d096d 100644 --- a/openair2/PHY_INTERFACE/mac_phy_primitives.c +++ b/openair2/PHY_INTERFACE/mac_phy_primitives.c @@ -187,9 +187,6 @@ MACPHY_DATA_REQ *new_macphy_data_req(unsigned char Mod_id) return((MACPHY_DATA_REQ*)0); } -#ifndef USER_MODE -EXPORT_SYMBOL(new_macphy_data_req); -#endif #endif //PHY_CONTEXT @@ -262,13 +259,7 @@ void macphy_data_ind(unsigned char Mod_id,unsigned char Pdu_type,void *pdu,unsig } } msg("[OPENAIR][MAC][ERROR] No more PHY_RESOURCES !!!!\n"); -#ifdef USER_MODE exit(-1); -#else - print_active_indications(); - print_active_requests(); - mac_xface->macphy_exit(); -#endif } */ diff --git a/openair2/PHY_INTERFACE/vars.h b/openair2/PHY_INTERFACE/vars.h index 736d6f89db..566f4347b6 100644 --- a/openair2/PHY_INTERFACE/vars.h +++ b/openair2/PHY_INTERFACE/vars.h @@ -42,7 +42,3 @@ unsigned int mac_registered; #endif -#ifndef USER_MODE -EXPORT_SYMBOL(mac_xface); -#endif //PHY_EMUL - diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c index 8d69b6e76b..0844593d93 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c @@ -28,45 +28,10 @@ * \email: navid.nikaein@eurecom.fr */ -#ifdef USER_MODE #include #include #include -#else //USER_MODE - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -#ifdef KERNEL2_6 - -#include -#endif - -#ifdef KERNEL2_4 -#include -#include -#endif -#endif //USER_MODE - #include "platform_types.h" #include "openair_defs.h" diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index fb31620961..a95db63d53 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -81,7 +81,6 @@ mac_rrc_data_req( uint8_t sfn = (uint8_t)((frameP>>2)&0xff); - #ifdef DEBUG_RRC int i; LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); diff --git a/openair2/RRC/LITE/MESSAGES/Makefile b/openair2/RRC/LITE/MESSAGES/Makefile deleted file mode 100644 index bd99081ad2..0000000000 --- a/openair2/RRC/LITE/MESSAGES/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -include $(OPENAIR_DIR)/common/utils/Makefile.inc -OPENAIR2_TOP = ../../.. -include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc - - -EXTRA_CFLAGS += -I$(OPENAIR1_DIR) -I/usr/realtime/include -D__need_Emath -D__NO_ASSERT_H__ - -ifdef RTAI -# Get the RTAI variables -CCC = $(shell rtai-config --cc) -RTAI_SUBVERSION=$(shell rtai-config --version | sed -e 's/^..\(.\).*$$/\1/') -IS_RTAI_SUBVERSION_LESS_THAN_FIVE=$(shell if [ $(RTAI_SUBVERSION) -lt 5 ] ; then echo true ; fi) - -EXTRA_CFLAGS += -D__IN_RTAI__ $(shell rtai-config --module-cflags) -g -march=pentium4 -DNODE_RG -DBIGPHYSAREA -DRTAI -DRTAI_ENABLED -fno-stack-protector -DHW_PREFIX_REMOVAL -Wall -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -DWIDENS_DLC -I$(KERNEL_DIR)/build/include -I$(KERNEL_DIR)/build/include/asm/mach-default -include $(KERNEL_DIR)/build/include/linux/autoconf.h $(if $(IS_RTAI_SUBVERSION_LESS_THAN_FIVE),-DRTAI_ISNT_POSIX,) -endif - - -obj-m = asn1_msg_kern.o -asn1_msg_kern-objs = $(ASN1_CONVERTER_OBJS) $(ASN1_MODULE_OBJS) bsearch.o rtai_mem.o - -clean: - rm -rf $(asn1_msg_kern-objs) $(obj-m) - -test: - echo $(asn1_msg_kern-objs) $(obj-m) - -regen: regenerate-from-asn1-source - -regenerate-from-asn1-source: - asn1c -gen-PER -fcompound-names -fnative-types -fskeletons-copy asn1c/ASN1_files/EUTRA-RRC-Definitions.asn - diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 1fff931c74..94d8c17f0a 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -28,7 +28,6 @@ * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr */ -#ifdef USER_MODE #include #include #include /* for atoi(3) */ @@ -36,14 +35,7 @@ #include /* for strerror(3) */ #include /* for EX_* exit codes */ #include /* for errno */ -#else -#include /* Needed by all modules */ -#endif -#ifdef USER_MODE -//#include "RRC/LITE/defs.h" -//#include "COMMON/mac_rrc_primitives.h" #include "UTIL/LOG/log.h" -#endif #include #include /* for _ASN_DEFAULT_STACK_MAX */ #include @@ -93,16 +85,8 @@ #include "common/ran_context.h" #include "secu_defs.h" -//#include "PHY/defs.h" -#ifndef USER_MODE -#define msg printk -#ifndef errno -int errno; -#endif -#else -# if !defined (msg) -# define msg printf -# endif +#if !defined (msg) +#define msg printf #endif //#define XER_PRINT @@ -486,9 +470,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[eNB] SystemInformationBlockType1 Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { return(-1); @@ -1016,9 +998,7 @@ uint8_t do_SIB23(uint8_t Mod_id, # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[eNB] SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { msg("[RRC] ASN1 : SI encoding failed for SIB23\n"); @@ -1105,9 +1085,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[UE] RRCConnectionRequest Encoded %zd bits (%zd bytes), ecause %d\n",enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); -#endif return((enc_rval.encoded+7)/8); @@ -1188,9 +1166,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin # endif #endif -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); @@ -1250,9 +1226,7 @@ do_RRCConnectionReconfigurationComplete( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } @@ -1643,10 +1617,8 @@ do_RRCConnectionSetup( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionSetup Encoded %zd bits (%zd bytes), ecause %d\n", enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); -#endif // FREEMEM(SRB_list); // free(SRB1_config); @@ -1716,13 +1688,11 @@ do_SecurityModeCommand( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[eNB %d] securityModeCommand for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, enc_rval.encoded, (enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { LOG_E(RRC,"[eNB %d] ASN1 : securityModeCommand encoding failed for UE %x\n", @@ -1794,13 +1764,11 @@ do_UECapabilityEnquiry( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[eNB %d] UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, enc_rval.encoded, (enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { LOG_E(RRC,"[eNB %d] ASN1 : UECapabilityRequest encoding failed for UE %x\n", @@ -1960,13 +1928,11 @@ do_RRCConnectionReconfiguration( # endif #endif - //#ifdef USER_MODE LOG_I(RRC,"RRCConnectionReconfiguration Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); // for (i=0;i<30;i++) // msg("%x.",buffer[i]); // msg("\n"); - //#endif return((enc_rval.encoded+7)/8); } @@ -2229,10 +2195,8 @@ do_RRCConnectionReestablishmentReject( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } @@ -2290,10 +2254,8 @@ do_RRCConnectionReject( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"RRCConnectionReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } @@ -2481,9 +2443,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, # endif #endif -#ifdef USER_MODE LOG_D(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif if (enc_rval.encoded==-1) { msg("[RRC] ASN1 : MCCH encoding failed for MBSFNAreaConfiguration\n"); @@ -2615,9 +2575,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ # endif #endif -#ifdef USER_MODE printf("Measurement Report Encoded %zu bits (%zu bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 270d9bc58f..05396bf727 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -28,7 +28,6 @@ * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr */ -#ifdef USER_MODE #include #include #include /* for atoi(3) */ @@ -36,9 +35,6 @@ #include /* for strerror(3) */ #include /* for EX_* exit codes */ #include /* for errno */ -#else -#include /* Needed by all modules */ -#endif #include #include /* for _ASN_DEFAULT_STACK_MAX */ diff --git a/openair2/RRC/LITE/MESSAGES/rtai_mem.c b/openair2/RRC/LITE/MESSAGES/rtai_mem.c deleted file mode 100644 index c522a1f0bf..0000000000 --- a/openair2/RRC/LITE/MESSAGES/rtai_mem.c +++ /dev/null @@ -1,146 +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 rtai_mem.c -* \brief a wrapper for Unified RTAI real-time memory management. -* \author Florian Kaltenberger -* \date 2011-04-06 -* \version 0.1 -* \company Eurecom -* \email: florian.kaltenberger@eurecom.fr -* \note -* \bug -* \warning -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -//#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include - -/* -void* rt_alloc_wrapper(int size) { - - unsigned long* tmp_ptr; - static unsigned long name = 0; - - rt_shm_free(name); - tmp_ptr = (unsigned long*) rt_shm_alloc(name,size+sizeof(unsigned long),GFP_KERNEL); - - if (!tmp_ptr) { - printk("rt_mem.c: failed to allocate %d bytes for name %ld at %p\n",size,name,tmp_ptr); - return NULL; - } - - printk("rt_mem.c: allocated %d bytes for name %ld at %p\n",size,name,tmp_ptr+1); - - tmp_ptr[0] = name; - name++; - - return (void*) (tmp_ptr+1); - -} - -int rt_free_wrapper(void* ptr) { - - unsigned long name; - - printk("rt_mem.c: freeing memory at %p, ",ptr); - - name = *(((unsigned long*) ptr)-1); - - printk("name %ld\n",name); - - return rt_shm_free(name); - -} - -void* rt_realloc_wrapper(void* oldptr, int size) { - - void* newptr; - - printk("rt_mem.c: reallocating %p with %d bytes\n",oldptr,size); - - if (oldptr==NULL) - newptr = rt_alloc_wrapper(size); - else { - newptr = rt_alloc_wrapper(size); - memcpy(newptr,oldptr,size); - rt_free_wrapper(oldptr); - } - - return newptr; -} -*/ - -void* rt_realloc(void* oldptr, int size) -{ - - void* newptr; - - printk("rt_mem.c: reallocating %p with %d bytes\n",oldptr,size); - - if (oldptr==NULL) { - newptr = rt_malloc(size); - } else { - newptr = rt_malloc(size); - memcpy(newptr,oldptr,size); - rt_free(oldptr); - } - - return newptr; -} - -void* rt_calloc(int nmemb, int size) -{ - - void* newptr; - - printk("rt_mem.c: allocating %d elements with %d bytes\n",nmemb,size); - - newptr = rt_malloc(nmemb*size); - memset(newptr,0,nmemb*size); - - return newptr; -} diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index a3b92a1d77..bda2655a4c 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -31,11 +31,9 @@ #ifndef __OPENAIR_RRC_DEFS_H__ #define __OPENAIR_RRC_DEFS_H__ -#ifdef USER_MODE #include #include #include -#endif #include "collection/tree.h" #include "rrc_types.h" @@ -47,11 +45,6 @@ #include "LAYER2/MAC/defs.h" -//#include "COMMON/openair_defs.h" -#ifndef USER_MODE -#include -#endif - #include "SystemInformationBlockType1.h" #include "SystemInformation.h" #include "RRCConnectionReconfiguration.h" diff --git a/openair2/RRC/LITE/mesh_top.c b/openair2/RRC/LITE/mesh_top.c deleted file mode 100644 index 16395e99c6..0000000000 --- a/openair2/RRC/LITE/mesh_top.c +++ /dev/null @@ -1,146 +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 - */ - -/*________________________openair_rrc_top.c________________________ - - Authors : Hicham Anouar - Company : EURECOM - Emails : anouar@eurecom.fr -________________________________________________________________*/ - - -#ifndef USER_MODE -#define __NO_VERSION__ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#ifdef KERNEL2_6 -#include -#endif - -#ifdef KERNEL2_4 -#include -#include -#endif - -#endif - - - -#include "defs.h" -#include "vars.h" - -extern MAC_RLC_XFACE* mac_rrc_register(RRC_XFACE*); -extern int mac_rrc_unregister(RRC_XFACE *); - -extern void *bigphys_malloc(int); - - - - -#ifndef USER_MODE - -/*------------------------------------------------*/ -/* Prototypes */ -/*------------------------------------------------*/ -#ifdef KERNEL2_4 -static int init_module( void ); -static void cleanup_module(void); -#else -static int openair_rrc_init_module( void ); -static void openair_rrc_cleanup_module(void); -#endif - -#ifdef KERNEL2_6 -static int __init openair_rrc_init_module( void ) -#else -int init_module( void ) -#endif //KERNEL2_6 -{ - printk("[OPENAIR][RRC][INIT] inserting module\n"); - - - Rrc_xface = (RRC_XFACE*)malloc16(sizeof(RRC_XFACE)); - - if(Rrc_xface == NULL) { - printk("[RRC] FATAL EROOR: Could not allocate memory for Rrc_xface !!!\n"); - return (-1); - } - - Mac_rlc_xface=mac_rrc_register(Rrc_xface); - - if( Mac_rlc_xface == NULL ) { - printk("[OPENAIR][RRC][INIT] Could not get RRC descriptor\n"); - return -1; - } else { - printk("[OPENAIR][RRC][INIT] Got RRC descriptor , Rcc_xface %p,Mac_rlc_xface=%p \n",Rrc_xface,Mac_rlc_xface); - } - - if(rrc_init_global_param()==-1) { - printk("[OPENAIR][RRC][INIT] FATAL ERROR: INIT_GLOBAL_PARAM_NOK\n"); - return -1; - } - - return 0; -} - -#ifdef KERNEL2_6 -static void __exit openair_rrc_cleanup_module(void) -#else -void cleanup_module(void) -#endif //KERNEL2_6 -{ -#ifndef NO_RRM - rtf_destroy(RRC2RRM_FIFO); - rtf_destroy(RRM2RRC_FIFO); -#endif //NO_RRM - printk("[OPENAIR][RRC][CLEANUP] cleanup module\n"); - mac_rrc_unregister(Rrc_xface); - -} - -MODULE_AUTHOR -("Lionel GAUTHIER , Raymond KNOPP , Aawatif MENOUNI ,Dominique NUSSBAUM , Michelle WETTERWALD , Maxime GUILLAUD "); -MODULE_DESCRIPTION ("openair RRC layer module"); -MODULE_LICENSE ("GPL"); -module_init (openair_rrc_init_module); -module_exit (openair_rrc_cleanup_module); - -#endif //USER_MODE - - diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 225d5698bb..260e1b729f 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -62,14 +62,8 @@ #include "TDD-Config.h" #include "UECapabilityEnquiry.h" #include "UE-CapabilityRequest.h" -#ifdef PHY_ABSTRACTION -#include "OCG.h" -#include "OCG_extern.h" -#endif -#ifdef USER_MODE #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" -#endif #if ENABLE_RAL #include "rrc_UE_ral.h" #endif @@ -730,13 +724,8 @@ rrc_ue_establish_drb( */ #ifdef PDCP_USE_NETLINK # if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) -# ifdef OAI_EMU - ip_addr_offset3 = oai_emulation.info.nb_enb_local; - ip_addr_offset4 = NB_eNB_INST; -# else ip_addr_offset3 = 0; ip_addr_offset4 = 8; -# endif LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id @@ -744,9 +733,6 @@ rrc_ue_establish_drb( ip_addr_offset4+ue_mod_idP+1); // fourth_octet if (oip_ifup == 0 ) { // interface is up --> send a config the DRB -# ifdef OAI_EMU - oai_emulation.info.oai_ifup[ue_mod_idP]=1; -# endif LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, @@ -762,10 +748,6 @@ rrc_ue_establish_drb( LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); } -# else -# ifdef OAI_EMU - oai_emulation.info.oai_ifup[ue_mod_idP]=1; -# endif # endif #endif @@ -1540,17 +1522,6 @@ rrc_ue_process_radioResourceConfigDedicated( UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State = RRC_CONNECTED; LOG_I(RRC,"[UE %d] State = RRC_CONNECTED (eNB %d)\n",ctxt_pP->module_id,eNB_index); -#if !defined(ENABLE_USE_MME) && defined(OAI_EMU) -# ifdef OAI_EMU - rrc_eNB_emulation_notify_ue_module_id( - ctxt_pP->module_id, - ctxt_pP->rnti, - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[0], - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[1], - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[2], - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->cellAccessRelatedInfo.cellIdentity.buf[3]); -# endif /* OAI_EMU */ -#endif } @@ -1730,9 +1701,7 @@ rrc_ue_process_securityModeCommand( # endif #endif -#ifdef USER_MODE LOG_D(RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); -#endif for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(RRC, "%02x.", buffer[i]); @@ -1835,9 +1804,7 @@ rrc_ue_process_ueCapabilityEnquiry( # endif #endif -#ifdef USER_MODE LOG_D(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { LOG_T(RRC, "%02x.", buffer[i]); @@ -4246,10 +4213,6 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i #endif // rel10 -#ifndef USER_MODE -EXPORT_SYMBOL(Rlc_info_am_config); -#endif - #if defined(ENABLE_ITTI) //----------------------------------------------------------------------------- void *rrc_ue_task( void *args_p ) diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index aad423418a..f44886dcc5 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -69,7 +69,7 @@ openair_rrc_on( int CC_id; if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); @@ -78,7 +78,7 @@ openair_rrc_on( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; } } else { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); for (i = 0; i < NB_eNB_INST; i++) { @@ -101,9 +101,7 @@ rrc_init_global_param( //----------------------------------------------------------------------------- { - //#ifdef USER_MODE // Rrc_xface = (RRC_XFACE*)malloc16(sizeof(RRC_XFACE)); - //#endif //USRE_MODE // Rrc_xface->openair_rrc_top_init = openair_rrc_top_init; // Rrc_xface->openair_rrc_eNB_init = openair_rrc_eNB_init; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index e57ed85b6f..b7c17259cc 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -63,12 +63,10 @@ #include "MeasResults.h" //#endif -#ifdef USER_MODE -# include "RRC/NAS/nas_config.h" -# include "RRC/NAS/rb_config.h" -# include "OCG.h" -# include "OCG_extern.h" -#endif +#include "RRC/NAS/nas_config.h" +#include "RRC/NAS/rb_config.h" +#include "OCG.h" +#include "OCG_extern.h" #if defined(ENABLE_SECURITY) # include "UTIL/OSA/osa_defs.h" @@ -136,6 +134,8 @@ init_SI( SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(SystemInformationBlockType1_v1310_IEs_t *)NULL; #endif + LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t*) malloc16(4); // copy basic parameters RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId = configuration->Nid_cell[CC_id]; @@ -283,6 +283,8 @@ init_SI( } #endif + LOG_D(RRC, "About to call rrc_mac_config_req_eNB\n"); + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, @@ -806,6 +808,7 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* #ifndef UE_EXPANSION int i, j , CC_id, pdu_number; LTE_eNB_ULSCH_t *ulsch = NULL; + LTE_eNB_DLSCH_t *dlsch = NULL; nfapi_ul_config_request_body_t *ul_req_tmp = NULL; PHY_VARS_eNB *eNB_PHY = NULL; eNB_MAC_INST *eNB_MAC = RC.mac[enb_mod_idP]; @@ -833,14 +836,6 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* */ return; } -#else -#if defined(OAI_EMU) - AssertFatal(ue_context_pP->local_uid < NUMBER_OF_UE_MAX, "local_uid invalid (%d<%d) for UE %x!", ue_context_pP->local_uid, NUMBER_OF_UE_MAX, rnti); - ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[enb_mod_idP][ue_context_pP->local_uid]; - AssertFatal(ue_module_id < NUMBER_OF_UE_MAX, "ue_module_id invalid (%d<%d) for UE %x!", ue_module_id, NUMBER_OF_UE_MAX, rnti); - oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[enb_mod_idP][ue_context_pP->local_uid] = -1; - oai_emulation.info.eNB_ue_module_id_to_rnti[enb_mod_idP][ue_module_id] = NOT_A_RNTI; -#endif #endif #ifndef UE_EXPANSION for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -849,9 +844,14 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* ulsch = eNB_PHY->ulsch[i]; if((ulsch != NULL) && (ulsch->rnti == rnti)){ LOG_I(RRC, "clean_eNb_ulsch UE %x \n", rnti); - //clean_eNb_ulsch(ulsch); - ulsch->rnti = 0; - break; + clean_eNb_ulsch(ulsch); + } + } + for (i=0; idlsch[i][0]; + if((dlsch != NULL) && (dlsch->rnti == rnti)){ + LOG_I(RRC, "clean_eNb_dlsch UE %x \n", rnti); + clean_eNb_dlsch(dlsch); } } @@ -5009,12 +5009,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id + 1); // fourth octet if (oip_ifup == 0) { // interface is up --> send a config the DRB -# ifdef OAI_EMU - oai_emulation.info.oai_ifup[ctxt_pP->module_id] = 1; - dest_ip_offset = NB_eNB_INST; -# else dest_ip_offset = 8; -# endif LOG_I(OIP, "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ctxt_pP->module_id, ctxt_pP->module_id, @@ -5031,10 +5026,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); } -# else -# ifdef OAI_EMU - oai_emulation.info.oai_ifup[ctxt_pP->module_id] = 1; -# endif # endif #endif @@ -6613,6 +6604,8 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { LOG_I(RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } + + LOG_D(RRC,"[MSG] RRC UL Information Transfer \n"); #ifdef RRC_MSG_PRINT LOG_F(RRC,"[MSG] RRC UL Information Transfer \n"); diff --git a/openair2/RRC/LITE/rrc_rrm_interface.c b/openair2/RRC/LITE/rrc_rrm_interface.c index 822ce554af..9f4270be89 100644 --- a/openair2/RRC/LITE/rrc_rrm_interface.c +++ b/openair2/RRC/LITE/rrc_rrm_interface.c @@ -292,10 +292,5 @@ int send_msg_fifo(int *s, msg_t *fmsg) int send_msg(void *s, msg_t *smsg) { -#ifdef USER_MODE send_msg_sock((sock_rrm_t *)s, smsg); -#else - send_msg_fifo((int *)s,smsg); -#endif - } diff --git a/openair2/RRC/LITE/rrc_rrm_interface.h b/openair2/RRC/LITE/rrc_rrm_interface.h index d204ab2db6..0880859a59 100644 --- a/openair2/RRC/LITE/rrc_rrm_interface.h +++ b/openair2/RRC/LITE/rrc_rrm_interface.h @@ -101,8 +101,6 @@ extern "C" { #define START_MSG_PUSU 0xCC -#ifdef USER_MODE - #include #include @@ -128,16 +126,6 @@ char *recv_msg( sock_rrm_t *s ) ; } #endif -#else //USER_MODE -#include - -#define RRC2RRM_FIFO 14 -#define RRM2RRC_FIFO 15 -int send_msg_fifo(int *s ,msg_t *msg ) ; -#endif //USER_MODE - int send_msg(void *, msg_t *); - - #endif diff --git a/openair2/RRC/LITE/rrm_2_rrc_msg.c b/openair2/RRC/LITE/rrm_2_rrc_msg.c index 3ef0bc2e0a..3ed3a9d859 100644 --- a/openair2/RRC/LITE/rrm_2_rrc_msg.c +++ b/openair2/RRC/LITE/rrm_2_rrc_msg.c @@ -65,17 +65,12 @@ void fn_rrc (void) /******************************************************************************/ msg_head_t *Header ; -#ifdef USER_MODE char *Data; -#else - int bytes_read; -#endif L2_ID Mac_id; while(1) { -#ifdef USER_MODE Header = (msg_head_t *) recv_msg(&S_rrc) ; if(Header==NULL) { @@ -83,52 +78,9 @@ void fn_rrc (void) } Data_to_read=Header->size; -#else - - if(Header_read_idx < Header_size) { - bytes_read = rtf_get (RRM2RRC_FIFO,&Header_buf[Header_read_idx],Header_size-Header_read_idx); - - if(bytes_read >0) { - msg("RRC: GET FIFOS RETURNS %d bytes, header %d\n",bytes_read,Header_read_idx); - } - - Header_read_idx+=bytes_read; - - if(Header_read_idx == Header_size) { - Header = (msg_head_t *) Header_buf; - Data_to_read=Header->size; - msg("RRC: Header read completed, data size %d\n",Data_to_read); - } - //msg("[fn_rrc]TTI %d: rcv_msg return Null\n",Rrc_xface->Frame_index); - else { - break; - } - } - -#endif if (Data_to_read > 0 ) { -#ifdef USER_MODE Data = (char *) (Header +1) ; -#else - bytes_read = rtf_get (RRM2RRC_FIFO,&Data[Data_read_idx],Data_to_read); - - if(bytes_read >0) { - msg("RRC: GET FIFOS RETURNS %d bytes, Data_to_read %d\n",bytes_read,Data_to_read); - } - - Data_to_read-=bytes_read; - Data_read_idx+=bytes_read; - - if(Data_to_read > 0 ) { - break; - } - - msg("RRC: DATA read completed, data size %d\n",Data_to_read); - Header_read_idx=0; - Data_read_idx=0; - Data_to_read=0; -#endif } msg("Got MSG of Type %d on Inst %d\n",Header->msg_type,Header->inst); diff --git a/openair2/RRC/LITE/utils.c b/openair2/RRC/LITE/utils.c index fd37fdf65c..bbf97046bf 100644 --- a/openair2/RRC/LITE/utils.c +++ b/openair2/RRC/LITE/utils.c @@ -29,25 +29,8 @@ ________________________________________________________________*/ -//#include "openair_types.h" #include "defs.h" #include "extern.h" -//#include "openair_proto.h" - - -#ifndef USER_MODE -char bcmp(void *x, void *y,int Size ) -{ - unsigned char i; - - for(i=0; imacphy_exit(); - #else exit(-1); - #endif */ } /* diff --git a/openair2/UTIL/LISTS/list2.c b/openair2/UTIL/LISTS/list2.c index 875f5e2d2f..3f0a59df53 100644 --- a/openair2/UTIL/LISTS/list2.c +++ b/openair2/UTIL/LISTS/list2.c @@ -38,11 +38,7 @@ ***************************************************************************/ #define LIST2_C #include "list.h" -#ifdef USER_MODE #include "assertions.h" -#else -#define NULL 0 -#endif #include @@ -336,9 +332,7 @@ list2_display (list2_t * listP) nb_elements++; } msg (" found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements); - #ifdef USER_MODE AssertFatal(nb_elements == listP->nb_elements, "Bad count of elements %d != %d", nb_elements, listP->nb_elements); - #endif } }*/ } diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index f3bd04754b..948425e8da 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -42,17 +42,8 @@ # include "intertask_interface.h" #endif -#ifdef USER_MODE # include # include -#endif -#ifdef RTAI -# include -# include -# define FIFO_PRINTF_MAX_STRING_SIZE 1000 -# define FIFO_PRINTF_NO 62 -# define FIFO_PRINTF_SIZE 65536 -#endif #include "common/config/config_userapi.h" // main log variables log_t *g_log; @@ -92,9 +83,7 @@ int log_list_head = 0; int log_shutdown; #endif -#ifndef RTAI static int gfd; -#endif static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_ORANGE, LOG_BLUE, "", ""}; /*!< \brief Optional start-format strings for highlighting */ static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET,LOG_RESET, "",""}; /*!< \brief Optional end-format strings for highlighting */ @@ -164,24 +153,12 @@ void log_getconfig(log_t *g_log) { int logInit (void) { -#ifdef USER_MODE -#ifndef RTAI int i; -#endif g_log = calloc(1, sizeof(log_t)); -#else - g_log = kmalloc(sizeof(log_t), GFP_KERNEL); -#endif - if (g_log == NULL) { -#ifdef USER_MODE perror ("cannot allocated memory for log generation module \n"); exit(EXIT_FAILURE); -#else - printk("cannot allocated memory for log generation module \n"); - return(-1); -#endif } @@ -485,7 +462,6 @@ int logInit (void) g_log->level = LOG_TRACE; g_log->flag = LOG_LOW; -#ifndef RTAI g_log->config.remote_ip = 0; g_log->config.remote_level = LOG_EMERG; g_log->config.facility = LOG_LOCAL7; @@ -513,21 +489,343 @@ int logInit (void) } } -#else - g_log->syslog = 0; - g_log->filelog = 0; - rtf_create (FIFO_PRINTF_NO, FIFO_PRINTF_SIZE); -#endif - -#ifdef USER_MODE printf("log init done\n"); -#else - printk("log init done\n"); -#endif return 0; } +void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args) +{ + //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args) + int len = 0; + log_component_t *c; + char *log_start; + char *log_end; + /* The main difference with the version above is the use of this local log_buffer. + * The other difference is the return value of snprintf which was not used + * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is + * big enough so that the buffer is never full. + */ + char log_buffer[MAX_LOG_TOTAL]; + + /* for no gcc warnings */ + (void)log_start; + (void)log_end; + + c = &g_log->log_component[comp]; + + // do not apply filtering for LOG_F + // only log messages which are enabled and are below the global log level and component's level threshold + if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { + /* if ((level != LOG_FILE) && + ((level > c->level) || + (level > g_log->level) || + ( c->level > g_log->level))) { + */ + return; + } + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN); + + // adjust syslog level for TRACE messages + if (g_log->syslog) { + if (g_log->level > LOG_DEBUG) { + g_log->level = LOG_DEBUG; + } + } + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { + log_start = log_buffer; + len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + } else { + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_start[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + log_start = log_buffer + len; + + if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->log_component[comp].name); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->level2string[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { +# define THREAD_NAME_LEN 128 + char threadname[THREAD_NAME_LEN]; + if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) + { + perror("pthread_getname_np : "); + } else { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } +# undef THREAD_NAME_LEN + } + + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", + func); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", + file, line); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + //len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%08lx]", thread_id); + //if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + + len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_end[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + } + + va_end(args); + + // OAI printf compatibility + if ((g_log->onlinelog == 1) && (level != LOG_FILE)) +#ifdef RTAI + if (len > MAX_LOG_TOTAL) { + rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); + } + + if (len > 0) { + rtf_put (FIFO_PRINTF_NO, log_buffer, len); + } + +#else + fwrite(log_buffer, len, 1, stdout); +#endif + +#ifndef RTAI + + if (g_log->syslog) { + syslog(g_log->level, "%s", log_buffer); + } + + if (g_log->filelog) { + if (write(gfd, log_buffer, len) < len) { + // TODO assert ? + } + } + + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + if (write(g_log->log_component[comp].fd, log_buffer, len) < len) { + // TODO assert ? + } + } + +#else + + // online print messges + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + printf(log_buffer); + } + +#endif + +#if defined(ENABLE_ITTI) + + if (level <= LOG_DEBUG) { + task_id_t origin_task_id = TASK_UNKNOWN; + MessagesIds messages_id; + MessageDef *message_p; + size_t message_string_size; + char *message_msg_p; + + message_string_size = log_end - log_start; + +#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) + + /* Try to identify sub task ID from log information (comp, log_instance_type) */ + switch (comp) { + case PHY: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PHY_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PHY_UE; + break; + + default: + break; + } + + break; + + case MAC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_MAC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_MAC_UE; + + default: + break; + } + + break; + + case RLC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_RLC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_RLC_UE; + + default: + break; + } + + break; + + case PDCP: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PDCP_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PDCP_UE; + + default: + break; + } + + break; + + default: + break; + } + +#endif + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + messages_id = ERROR_LOG; + break; + + case LOG_WARNING: + messages_id = WARNING_LOG; + break; + + case LOG_NOTICE: + messages_id = NOTICE_LOG; + break; + + case LOG_INFO: + messages_id = INFO_LOG; + break; + + default: + messages_id = DEBUG_LOG; + break; + } + + message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + message_msg_p = (char *) &message_p->ittiMsg.error_log; + break; + + case LOG_WARNING: + message_msg_p = (char *) &message_p->ittiMsg.warning_log; + break; + + case LOG_NOTICE: + message_msg_p = (char *) &message_p->ittiMsg.notice_log; + break; + + case LOG_INFO: + message_msg_p = (char *) &message_p->ittiMsg.info_log; + break; + + default: + message_msg_p = (char *) &message_p->ittiMsg.debug_log; + break; + } + + memcpy(message_msg_p, log_start, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + } + +#endif +#if 0 + LOG_params log_params; + int len; + + len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args); + + //2 first parameters must be passed as 'const' to the thread function + log_params.file = strdup(file); + log_params.func = strdup(func); + log_params.line = line; + log_params.comp = PHY;//comp; + log_params.level = 6; // INFO - level; + log_params.format = format; + log_params.len = len; + + if (pthread_mutex_lock(&log_lock) != 0) { + return; + } + + log_list_tail++; + log_list[log_list_tail - 1] = log_params; + + if (log_list_tail >= 1000) { + log_list_tail = 0; + } + + if (log_list_nb_elements < 1000) { + log_list_nb_elements++; + } + + if(pthread_cond_signal(&log_notify) != 0) { + pthread_mutex_unlock(&log_lock); + return; + } + + if(pthread_mutex_unlock(&log_lock) != 0) { + return; + } + +#endif +} + //log record: add to a list void logRecord(const char *file, const char *func, int line, int comp, int level, const char *format, ...) @@ -650,23 +948,9 @@ void logRecord_thread_safe(const char *file, const char *func, // OAI printf compatibility if ((g_log->onlinelog == 1) && (level != LOG_FILE)) { -#ifdef RTAI - - if (len > MAX_LOG_TOTAL) { - rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); - } - - if (len > 0) { - rtf_put (FIFO_PRINTF_NO, log_buffer, len); - } - -#else fprintf(stdout, "%s", log_buffer); -#endif } -#ifndef RTAI - if (g_log->syslog) { syslog(g_log->level, "%s", log_buffer); } @@ -683,8 +967,6 @@ void logRecord_thread_safe(const char *file, const char *func, } } -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_OUT); } @@ -834,20 +1116,7 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, // OAI printf compatibility if ((g_log->onlinelog == 1) && (level != LOG_FILE)) -#ifdef RTAI - if (len > MAX_LOG_TOTAL) { - rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); - } - - if (len > 0) { - rtf_put (FIFO_PRINTF_NO, c->log_buffer, len); - } - -#else fwrite(c->log_buffer, len, 1, stdout); -#endif - -#ifndef RTAI if (g_log->syslog) { syslog(g_log->level, "%s", c->log_buffer); @@ -865,15 +1134,6 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, } } -#else - - // online print messges - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - printf(c->log_buffer); - } - -#endif - #if defined(ENABLE_ITTI) if (level <= LOG_DEBUG) { @@ -1132,20 +1392,7 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, // OAI printf compatibility if ((g_log->onlinelog == 1) && (level != LOG_FILE)) -#ifdef RTAI - if (len > MAX_LOG_TOTAL) { - rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); - } - - if (len > 0) { - rtf_put (FIFO_PRINTF_NO, log_buffer, len); - } - -#else fwrite(log_buffer, len, 1, stdout); -#endif - -#ifndef RTAI if (g_log->syslog) { syslog(g_log->level, "%s", log_buffer); @@ -1163,15 +1410,6 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, } } -#else - - // online print messges - if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { - printf(log_buffer); - } - -#endif - #if defined(ENABLE_ITTI) if (level <= LOG_DEBUG) { @@ -1398,16 +1636,11 @@ void set_component_filelog(int comp) { if (g_log->log_component[comp].filelog == 0) { g_log->log_component[comp].filelog = 1; -#ifndef RTAI if (g_log->log_component[comp].fd == 0) { g_log->log_component[comp].fd = open(g_log->log_component[comp].filelog_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); } - -#else - -#endif } } @@ -1463,9 +1696,6 @@ int is_newline( char *str, int size) void logClean (void) { -#ifdef RTAI - rtf_destroy (FIFO_PRINTF_NO); -#else int i; if (g_log->syslog) { @@ -1481,9 +1711,6 @@ void logClean (void) close(g_log->log_component[i].fd); } } - -#endif - } #if defined(ENABLE_ITTI) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 1d795740b6..c21407f6eb 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -32,7 +32,6 @@ # define __LOG_H__ /*--- INCLUDES ---------------------------------------------------------------*/ -#ifdef USER_MODE #include #include #include @@ -53,9 +52,6 @@ #define _GNU_SOURCE #endif #include -#else -#include "rtai_fifos.h" -#endif /*----------------------------------------------------------------------------*/ @@ -282,20 +278,11 @@ void *log_thread_function(void * list); * @ingroup _macro * @brief Macro used to call tr_log_full_ex with file, function and line information * @{*/ -#ifdef USER_MODE -//#define logIt(component, level, format, args...) do {logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args);} while(0); #ifdef LOG_NO_THREAD #define logIt(component, level, format, args...) logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) #else //default #define logIt(component, level, format, args...) logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) #endif -#else -#ifdef LOG_NO_THREAD -#define logIt(component, level, format, args...) logRecord_mt(NULL, __FUNCTION__, __LINE__, component, level, format, ##args) -#else // default -#define logIt(component, level, format, args...) logRecord(NULL, __FUNCTION__, __LINE__, component, level, format, ##args) -#endif -#endif /* @}*/ /*----------------macro definitions for reading log configuration from the config module */ @@ -326,7 +313,6 @@ void *log_thread_function(void * list); * @{*/ // debugging macros -#ifdef USER_MODE # if T_TRACER # include "T.h" # define LOG_I(c, x...) T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) @@ -364,17 +350,6 @@ void *log_thread_function(void * list); # define LOG_T(c, x...) logIt(c, LOG_TRACE, x) # endif /*DISABLE_LOG_X*/ # endif /* T_TRACER */ -#else /* USER_MODE */ -# define LOG_G(c, x...) printk(x) -# define LOG_A(c, x...) printk(x) -# define LOG_C(c, x...) printk(x) -# define LOG_E(c, x...) printk(x) -# define LOG_W(c, x...) printk(x) -# define LOG_N(c, x...) printk(x) -# define LOG_I(c, x...) printk(x) -# define LOG_D(c, x...) printk(x) -# define LOG_T(c, x...) printk(x) -#endif /* @}*/ diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c index e0c20f9243..b18d2a25ff 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.c +++ b/openair2/UTIL/LOG/vcd_signal_dumper.c @@ -48,10 +48,6 @@ #include "vcd_signal_dumper.h" -#if defined(ENABLE_RTAI_CLOCK) -#include "rtai_lxrt.h" -#endif - #define VCDSIGNALDUMPER_VERSION_MAJOR 0 #define VCDSIGNALDUMPER_VERSION_MINOR 1 @@ -399,6 +395,17 @@ const char* eurecomFunctionsNames[] = { "compress_if", "decompress_if", + + "nfapi_subframe", + "generate_pcfich", + "generate_dci0", + "generate_dlsch", + "generate_phich", + "pdcch_scrambling", + "pdcch_modulation", + "pdcch_interleaving", + "pdcch_tx", + }; struct vcd_module_s vcd_modules[] = { @@ -412,8 +419,6 @@ static inline unsigned long long int vcd_get_time(void); #if defined(ENABLE_USE_CPU_EXECUTION_TIME) struct timespec g_time_start; -#elif defined(ENABLE_RTAI_CLOCK) -RTIME start; #endif @@ -609,8 +614,6 @@ void vcd_signal_dumper_init(char *filename) #if defined(ENABLE_USE_CPU_EXECUTION_TIME) clock_gettime(CLOCK_MONOTONIC, &g_time_start); -#elif defined(ENABLE_RTAI_CLOCK) - start=rt_get_time_ns(); #endif vcd_signal_dumper_create_header(); @@ -663,9 +666,6 @@ static inline void vcd_signal_dumper_print_time_since_start(void) secondsSinceStart = (long long unsigned int)time.tv_sec - (long long unsigned int)g_time_start.tv_sec; /* Write time in nanoseconds */ fprintf(vcd_fd, "#%llu\n", nanosecondsSinceStart + (secondsSinceStart * 1000000000UL)); -#elif defined(ENABLE_RTAI_CLOCK) - /* Write time in nanoseconds */ - fprintf(vcd_fd, "#%llu\n",rt_get_time_ns()-start); #endif } } @@ -679,8 +679,6 @@ static inline unsigned long long int vcd_get_time(void) return (long long unsigned int)((time.tv_nsec - g_time_start.tv_nsec)) + ((long long unsigned int)time.tv_sec - (long long unsigned int)g_time_start.tv_sec) * 1000000000UL; -#elif defined(ENABLE_RTAI_CLOCK) - return rt_get_time_ns() - start; #endif } diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index 2e7f7ee792..a4c8cd2476 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -376,6 +376,16 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, + VCD_SIGNAL_DUMPER_FUNCTIONS_NFAPI, + VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH, + VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0, + VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, + VCD_SIGNAL_DUMPER_FUNCTIONS_END } vcd_signal_dump_functions; diff --git a/openair2/UTIL/MATH/random.c b/openair2/UTIL/MATH/random.c index 06caa3bc3c..30a6e9b1ab 100644 --- a/openair2/UTIL/MATH/random.c +++ b/openair2/UTIL/MATH/random.c @@ -29,11 +29,7 @@ #include "rtos_header.h" #include "platform_types.h" -#ifdef USER_MODE -# include -#else -#include -#endif +#include /* Random generators */ @@ -47,7 +43,6 @@ static int seed; void init_uniform (void) { -#ifdef USER_MODE struct timeval tv; struct timezone tz; @@ -61,9 +56,6 @@ init_uniform (void) #warning TO DO seed = rgId //seed += rgId; #endif -#else - seed = rt_get_time_ns(); -#endif } diff --git a/openair2/UTIL/MATH/taus.c b/openair2/UTIL/MATH/taus.c index 6e0fd84e66..632b1544dd 100644 --- a/openair2/UTIL/MATH/taus.c +++ b/openair2/UTIL/MATH/taus.c @@ -29,21 +29,12 @@ * @ingroup util */ -#ifndef RTAI_ENABLED #include #include #include #include #include #include "oml.h" -#else -#include -#include -#include -#include -#define time(x) (unsigned int)(rt_get_time_ns()) -#endif - unsigned int s0[MAX_NUM_COMPS], s1[MAX_NUM_COMPS], s2[MAX_NUM_COMPS], b[MAX_NUM_COMPS], r[MAX_NUM_COMPS]; diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c index 09f10547cb..9c3a50467a 100644 --- a/openair2/UTIL/MEM/mem_block.c +++ b/openair2/UTIL/MEM/mem_block.c @@ -54,7 +54,7 @@ static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER; //#define DEBUG_MEM_MNGT_ALLOC_SIZE //#define DEBUG_MEM_MNGT_ALLOC //----------------------------------------------------------------------------- -#if defined(USER_MODE) && defined(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 //----------------------------------------------------------------------------- @@ -269,10 +269,8 @@ get_free_mem_block (uint32_t sizeP, const char* caller) #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]); -#ifdef USER_MODE // display_mem_load (); // check_mem_area ((void *)&mem_block_var); -#endif #endif } while (pool_selected++ < 12); diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h index b7e36bf5b3..e967380269 100644 --- a/openair2/UTIL/MEM/mem_block.h +++ b/openair2/UTIL/MEM/mem_block.h @@ -31,9 +31,7 @@ #ifndef __MEM_BLOCK_H__ # define __MEM_BLOCK_H__ -#ifdef USER_MODE #include -#endif #ifdef MEM_BLOCK_C # define public_mem_block(x) x # define private_mem_block(x) x @@ -63,19 +61,8 @@ public_mem_block(mem_block_t *copy_mem_block (mem_block_t * leP, mem_block_t * d public_mem_block(void display_mem_load (void);) public_mem_block(void check_mem_area (void);) -# ifdef USER_MODE private_mem_block(void check_free_mem_block (mem_block_t * leP);) -# endif -#ifdef USER_MODE -//# define MEM_SCALE MAX_MOBILES_PER_ENB*NB_RB_MAX # define MEM_SCALE MAX_MOBILES_PER_ENB -#else -# ifdef NODE_RG -# define MEM_SCALE 2 -# else -# define MEM_SCALE 1 -# endif -#endif // definition of the size of the allocated memory area # define MEM_MNGT_MB0_BLOCK_SIZE 64 // 64 diff --git a/openair2/UTIL/MEM/mem_mngt.c b/openair2/UTIL/MEM/mem_mngt.c index 49cd310ac9..57c90ea4f9 100644 --- a/openair2/UTIL/MEM/mem_mngt.c +++ b/openair2/UTIL/MEM/mem_mngt.c @@ -49,9 +49,7 @@ // #endif //----------------------------------------------------------------------------- -#ifdef USER_MODE uint32_t counters[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#endif //----------------------------------------------------------------------------- /* * initialize all ures @@ -227,10 +225,8 @@ get_free_mem_block (uint16_t sizeP, __func__) #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]); -# ifdef USER_MODE display_mem_load (); check_mem_area (mem); -# endif #endif } while (pool_selected++ < 9); diff --git a/openair2/UTIL/OCG/makefile b/openair2/UTIL/OCG/makefile index 1e531f9494..1ef4ec98dc 100644 --- a/openair2/UTIL/OCG/makefile +++ b/openair2/UTIL/OCG/makefile @@ -7,7 +7,7 @@ OPENAIR2_TOP = ../../../openair2 OPENAIR3_TOP = ../../../openair3 OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat +CFLAGS += -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat CFLAGS += -m32 -DOPENAIR_LTE -DOPENAIR2 #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE @@ -22,8 +22,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION - #ifdef OCG CFLAGS += -I/usr/include/libxml2 -lxml2 #endif diff --git a/openair2/UTIL/OMG/makefile b/openair2/UTIL/OMG/makefile index 319b8296cd..80ab8c6394 100644 --- a/openair2/UTIL/OMG/makefile +++ b/openair2/UTIL/OMG/makefile @@ -60,7 +60,7 @@ OPENAIR2_TOP = ../../../openair2 OPENAIR3_TOP = ../../../openair3 OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat +CFLAGS += -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat CFLAGS += -DOPENAIR_LTE -DOPENAIR2 #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE @@ -75,8 +75,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION - include $(OPENAIR1_DIR)/PHY/Makefile.inc include $(OPENAIR1_DIR)/SCHED/Makefile.inc include $(OPENAIR2_DIR)/LAYER2/Makefile.inc diff --git a/openair2/UTIL/OMG/makefile_old b/openair2/UTIL/OMG/makefile_old index acc89254fb..7bc551cb03 100644 --- a/openair2/UTIL/OMG/makefile_old +++ b/openair2/UTIL/OMG/makefile_old @@ -62,7 +62,7 @@ OPENAIR2_TOP = ../../../openair2 OPENAIR3_TOP = ../../../openair3 OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat +CFLAGS += -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 #-Wno-packed-bitfield-compat CFLAGS += -DOPENAIR_LTE -DOPENAIR2 #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE @@ -77,8 +77,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION - include $(OPENAIR1_DIR)/PHY/Makefile.inc include $(OPENAIR1_DIR)/SCHED/Makefile.inc include $(OPENAIR2_DIR)/LAYER2/Makefile.inc diff --git a/openair2/UTIL/OMG/makefile_standalone b/openair2/UTIL/OMG/makefile_standalone index 68170543ee..d612c01837 100644 --- a/openair2/UTIL/OMG/makefile_standalone +++ b/openair2/UTIL/OMG/makefile_standalone @@ -8,7 +8,7 @@ OBJsumo = omg.c common.c sumo.c client_traci_OMG.c socket_traci_OMG.c storage_tr OBJ = omg.c common.c static.c job.c rwp.c rwalk.c trace.c steadystaterwp.c sumo.c grid.c mobility_parser.c hashtable.c client_traci_OMG.c socket_traci_OMG.c storage_traci_OMG.c id_manager.c -CFLAGS += -DSTANDALONE -DUSER_MODE -g +CFLAGS += -DSTANDALONE -g .PHONY: help staticOMG rwpOMG clean diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 711436d2cd..ebc52bb1e0 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -410,18 +410,8 @@ static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, /* PCAP Header */ /* TODO: Timestamp might want to be relative to a more sensible base time... */ -#if defined(RTAI) - { - unsigned long long int current_ns; - - current_ns = rt_get_time_ns(); - packet_header.ts_sec = current_ns / 1000000000UL; - packet_header.ts_usec = current_ns % 1000; - } -#else packet_header.ts_sec = context->subframesSinceCaptureStart / 1000; packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000; -#endif packet_header.incl_len = offset + length; packet_header.orig_len = offset + length; diff --git a/openair2/UTIL/TRACE/print.h b/openair2/UTIL/TRACE/print.h index 5982d249fa..72c43f20d4 100644 --- a/openair2/UTIL/TRACE/print.h +++ b/openair2/UTIL/TRACE/print.h @@ -28,14 +28,5 @@ ***************************************************************************/ #ifndef __PRINT_H__ # define __PRINT_H__ -# ifdef USER_MODE -# define msg printf -# else -# ifdef FIFO_PRINTF -# include "fifo_printf_proto_extern.h" -# define msg fifo_printf -# else -# define msg fifo_printf_null -# endif -# endif +# define msg printf #endif diff --git a/openair2/X2AP/Makefile.inc b/openair2/X2AP/Makefile.inc index 7369cf8dfa..a301a9934e 100755 --- a/openair2/X2AP/Makefile.inc +++ b/openair2/X2AP/Makefile.inc @@ -28,7 +28,6 @@ CFLAGS = \ -Wall \ -DENB_MODE \ -DENABLE_USE_MME \ - -DUSER_MODE \ -I. \ -I$(ASN1MESSAGESDIR)/ASN1/$(ASN1RELDIR) \ -I$(ASN1MESSAGESDIR) \ diff --git a/openair2/X2AP/x2ap.h b/openair2/X2AP/x2ap.h index 65529c7119..89e8540b97 100644 --- a/openair2/X2AP/x2ap.h +++ b/openair2/X2AP/x2ap.h @@ -33,10 +33,7 @@ typedef struct x2ap_config_s { } x2ap_config_t; -#if defined(OAI_EMU) -#else extern x2ap_config_t x2ap_config; -#endif void *x2ap_task(void *arg); diff --git a/openair3/COMMON/nas_messages_def.h b/openair3/COMMON/nas_messages_def.h index 5214a15171..9bdcde4fdf 100644 --- a/openair3/COMMON/nas_messages_def.h +++ b/openair3/COMMON/nas_messages_def.h @@ -61,9 +61,3 @@ MESSAGE_DEF(NAS_PDN_CONNECTIVITY_FAIL, MESSAGE_PRIORITY_MED, nas_pdn_ MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_RSP, MESSAGE_PRIORITY_MED, nas_auth_param_rsp_t, nas_auth_param_rsp) MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_FAIL, MESSAGE_PRIORITY_MED, nas_auth_param_fail_t, nas_auth_param_fail) -#if defined(DISABLE_USE_NAS) -MESSAGE_DEF(NAS_ATTACH_REQ, MESSAGE_PRIORITY_MED, nas_attach_req_t, nas_attach_req) -MESSAGE_DEF(NAS_ATTACH_ACCEPT, MESSAGE_PRIORITY_MED, nas_attach_accept_t, nas_attach_accept) -MESSAGE_DEF(NAS_AUTHENTICATION_RESP, MESSAGE_PRIORITY_MED, nas_auth_resp_t, nas_auth_resp) -MESSAGE_DEF(NAS_AUTHENTICATION_REQ, MESSAGE_PRIORITY_MED, nas_auth_req_t, nas_auth_req) -#endif diff --git a/openair3/COMMON/nas_messages_types.h b/openair3/COMMON/nas_messages_types.h index 45de68840e..81a44fa4f4 100644 --- a/openair3/COMMON/nas_messages_types.h +++ b/openair3/COMMON/nas_messages_types.h @@ -233,17 +233,7 @@ typedef struct nas_conn_est_ind_s { typedef nas_establish_rsp_t nas_conn_est_rej_t; -#if defined(DISABLE_USE_NAS) -typedef struct nas_conn_est_cnf_s { - uint32_t ue_id; - - nas_establish_cnf_t nas_establish_cnf; - /* Transparent message from MME_APP to S1AP */ - s1ap_initial_ctxt_setup_req_t transparent; -} nas_conn_est_cnf_t; -#else typedef nas_establish_cnf_t nas_conn_est_cnf_t; -#endif typedef struct nas_conn_rel_ind_s { @@ -336,10 +326,4 @@ typedef struct nas_auth_param_fail_s { } nas_auth_param_fail_t; -#if defined(DISABLE_USE_NAS) -typedef struct nas_attach_accept_s { - s1ap_initial_ctxt_setup_req_t transparent; -} nas_attach_accept_t; -#endif - #endif /* NAS_MESSAGES_TYPES_H_ */ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 7c87cbc073..4234bc373d 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -49,6 +49,7 @@ #include "COMMON/platform_constants.h" #include "UTIL/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" +#include "gtpv1u_eNB_defs.h" #undef GTP_DUMP_SOCKET diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index aba32aa494..301df6e816 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -65,10 +65,7 @@ #include "oaisim_mme_test_s1c.h" #endif - -#if !defined(OAI_EMU) s1ap_eNB_config_t s1ap_config; -#endif static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h index 85bf00a4fa..e122703d82 100644 --- a/openair3/S1AP/s1ap_eNB.h +++ b/openair3/S1AP/s1ap_eNB.h @@ -35,13 +35,9 @@ typedef struct s1ap_eNB_config_s { unsigned char mme_enabled; ///< MME enabled ? } s1ap_eNB_config_t; -#if defined(OAI_EMU) -# define EPC_MODE_ENABLED oai_emulation.info.s1ap_config.mme_enabled -#else extern s1ap_eNB_config_t s1ap_config; -# define EPC_MODE_ENABLED s1ap_config.mme_enabled -#endif +#define EPC_MODE_ENABLED s1ap_config.mme_enabled void *s1ap_eNB_task(void *arg); diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index bd7b804a67..868d86ad9c 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -427,7 +427,7 @@ on_error: return NULL; } -int udp_enb_init() +int udp_enb_init(void) { LOG_I(UDP_, "Initializing UDP task interface\n"); STAILQ_INIT(&udp_socket_list); diff --git a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/Makefile b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/Makefile index c9c5f82819..77b3d41f25 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/Makefile +++ b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -DUSER_MODE -DEXMIMO -g +CFLAGS = -DEXMIMO -g XTRA_CFLAGS = -msse -msse2 -mssse3 -fPIC #ifndef OPENAIR0_DIR diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 3a84302130..6bb7e2e82f 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -283,12 +283,11 @@ int64_t wrap_ts = 0; unsigned int u_sf_mode = 0; // 1=record, 2=replay unsigned int u_sf_record = 0; // record mode unsigned int u_sf_replay = 0; // replay mode -char u_sf_filename[1024]; // subframes file path +char u_sf_filename[1024] = ""; // subframes file path unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode -char *tmp_filename[1]; // use an array of pointer (libconfig does not seems to work with char array yet) char config_opt_sf_file[] = CONFIG_OPT_SF_FILE; char config_def_sf_file[] = DEF_SF_FILE; @@ -420,10 +419,10 @@ static void trx_usrp_end(openair0_device *device) { /*! \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 whicch the first sample MUST be sent + @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 anteannas + @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 */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { @@ -841,7 +840,7 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); usrp_recplay_params[0].helpstr = config_hlp_sf_file; usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE; - usrp_recplay_params[0].strptr=(char **)&tmp_filename[0]; + usrp_recplay_params[0].strptr=(char **)&u_sf_filename; usrp_recplay_params[0].defstrval = NULL; usrp_recplay_params[0].type=TYPE_STRING; usrp_recplay_params[0].numelt=sizeof(u_sf_filename); @@ -916,16 +915,13 @@ extern "C" { // end to check memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); memset(&u_sf_filename[0], 0, 1024); - tmp_filename[0] = u_sf_filename; if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; return -1; } config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); - if (strlen(tmp_filename[0]) != 0) { - (void) strcpy(u_sf_filename, tmp_filename[0]); - } else { + if (strlen(u_sf_filename) == 0) { (void) strcpy(u_sf_filename, DEF_SF_FILE); } @@ -1016,9 +1012,13 @@ extern "C" { //s->usrp->set_master_clock_rate(usrp_master_clock); openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + #if defined(USRP_REC_PLAY) std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info -#endif +#endif + + LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); + switch ((int)openair0_cfg[0].sample_rate) { case 30720000: // from usrp_time_offset @@ -1161,6 +1161,8 @@ extern "C" { s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i); + + LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); } } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 7d6ea9be0a..b911fbc5a4 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -42,6 +42,8 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) { + LOG_D(ENB_APP, "%s(enb_nb:%d ue_nb:%d)\n", __FUNCTION__, enb_nb, ue_nb); + itti_wait_ready(1); if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { LOG_E(PDCP, "Create task for L2L1 failed\n"); diff --git a/targets/Makefile b/targets/Makefile deleted file mode 100644 index b604898d2a..0000000000 --- a/targets/Makefile +++ /dev/null @@ -1,35 +0,0 @@ - - -build: - ./build_oai.bash -c -m - -build_rtai: - ./build_oai.bash -c -b -eRTAI -tSOFTMODEM -m - -build_usrp_rtai: - ./build_oai.bash -c -b -eRTAI -tSOFTMODEM -wUSRP -m - - -help: - @echo make check1 performs a simple sanity check - @echo make check2 performs another simple sanity check - @echo make check does both the above checks - -all: help - -check1: - @echo Doing 1 eNB 1 UE test - (cd SIMU/EXAMPLES/VIRT_EMUL_1eNB && make one_eNB_one_UE ) - -check2: - @echo Doing 1 eNB 4 UE test - (cd SIMU/EXAMPLES/VIRT_EMUL_1eNB && make one_eNB_four_UE ) - -install: - @echo Generating ASN1 files - @sh SCRIPTS/install_asn1.sh - -check: check1 check2 - -clean: - (cd SIMU/USER && make clean) diff --git a/targets/Makefile.common b/targets/Makefile.common index 042a36bf45..ac0771770b 100644 --- a/targets/Makefile.common +++ b/targets/Makefile.common @@ -86,7 +86,6 @@ endif ifeq ($(ENABLE_ITTI),1) COMMON_CFLAGS += -DENABLE_ITTI -COMMON_CFLAGS += -DUSER_MODE COMMON_CFLAGS += -I$(OPENAIR1_DIR) COMMON_CFLAGS += -I$(OPENAIR2_DIR)/NAS COMMON_CFLAGS += $(L2_incl) diff --git a/targets/PROJECTS/E-MBMS/build_all.bash b/targets/PROJECTS/E-MBMS/build_all.bash index 0cbece916e..bac9b33736 100755 --- a/targets/PROJECTS/E-MBMS/build_all.bash +++ b/targets/PROJECTS/E-MBMS/build_all.bash @@ -61,8 +61,8 @@ echo_success "\n###############################" echo_success "# COMPILE oaisim" echo_success "###############################" cd $OPENAIR_TARGETS/SIMU/USER -echo_success "Executing: make oaisim NAS=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 Rel10=1 -j`grep -c ^processor /proc/cpuinfo `" -make oaisim NAS=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 Rel10=1 -j`grep -c ^processor /proc/cpuinfo ` +echo_success "Executing: make oaisim NAS=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 Rel10=1 -j`grep -c ^processor /proc/cpuinfo `" +make oaisim NAS=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 Rel10=1 -j`grep -c ^processor /proc/cpuinfo ` if [[ $? -eq 2 ]] ; then exit 1 fi diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf index f97cd0ad8b..9393872b30 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf @@ -1,3 +1,20 @@ +log_config = { + global_log_level ="debug"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="low"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; +}; + L1s = ( { num_cc = 1; @@ -6,9 +23,9 @@ L1s = ( remote_n_address = "127.0.0.2"; local_n_address = "127.0.0.1"; local_n_portc = 50000; - remote_n_portc = 50000; - local_n_portd = 50001; - remote_n_portd = 50001; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index c9102b9b08..1c9ad09141 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -156,8 +156,25 @@ eNBs = ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; + } +); - log_config : +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo"; + remote_s_address = "127.0.0.1"; + local_s_address = "127.0.0.2"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); + +log_config = { global_log_level ="info"; global_log_verbosity ="medium"; @@ -174,21 +191,3 @@ eNBs = rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - } -); - -MACRLCs = ( - { - num_cc = 1; - local_s_if_name = "lo"; - remote_s_address = "127.0.0.1"; - local_s_address = "127.0.0.2"; - local_s_portc = 50000; - remote_s_portc = 50000; - local_s_portd = 50001; - remote_s_portd = 50001; - tr_s_preference = "nfapi"; - tr_n_preference = "local_RRC"; - } -); - diff --git a/targets/RT/Makefile b/targets/RT/Makefile deleted file mode 100644 index 1be49d2db8..0000000000 --- a/targets/RT/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -# command line flags are automatically exported and thus passed down to any sub-make. -# here we set the default flags in case on command line flags are provided -# these flags have to be explicitely exported so that the sub-make is aware of them - - -include $(OPENAIR_DIR)/common/utils/Makefile.inc -ifndef OPENAIR_LTE -export OPENAIR_LTE=1 -export OPENAIR_EMU=0 -endif - -ifndef OPENAIR1 -export OPENAIR1=0 -endif - -ifndef OPENAIR2 -export OPENAIR2=0 -endif - -ifndef OPENAIR3 -export OPENAIR3=0 -endif - -ifndef EMOS -export EMOS=0 -endif - -ifndef rrc_cellular -export rrc_cellular = 0 -export rrc_cellular_eNB = 0 -export rrc_cellular_UE = 0 -else - export rrc_cellular = 1 - ifeq ($(eNB_flag),1) - export rrc_cellular_eNB=1 - endif - ifeq ($(UE_flag),1) - export rrc_cellular_UE=1 - endif -endif - -all: openair_rf_cbmimo1_softmodem.ko asn1_msg_kern.ko nasmesh.ko rb_tool openair_rf scope - -openair_rf_cbmimo1_softmodem.ko: - (cd $(OPENAIR1_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 && mv openair_rf.ko $(CURDIR)/openair_rf_softmodem.ko) - -oai_user_cbmimo1.ko: - (cd $(OPENAIR1_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 BIT8_TX=1 OPENAIR1=0 OPENAIR2=0 && mv openair_rf.ko $(CURDIR)/openair_rf_softmodem.ko) - -oai_user_exmimo.ko: - (cd $(OPENAIR1_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) -C $(KERNEL_DIR)/build V=1 M=`pwd` RTAI=1 CBMIMO1=1 OPENAIR1=0 OPENAIR2=0 && mv openair_rf.ko $(CURDIR)/openair_rf_softmodem.ko) - -asn1_msg_kern.ko: - (cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES && $(MAKE) -C $(KERNEL_DIR)/build V=0 M=`pwd` RTAI=1 -j2 && mv asn1_msg_kern.ko $(CURDIR)/asn1_msg_kern.ko) - -nasmesh.ko: - (cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH && $(MAKE) V=1 -C $(KERNEL_DIR)/build M=`pwd` && mv nasmesh.ko $(CURDIR)/nasmesh.ko) - -rb_tool: - (cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE)) - -openair_rf: - (cd $(OPENAIR1_DIR)/USERSPACE_TOOLS/OPENAIR_RF && $(MAKE) clean CBMIMO1=1 && $(MAKE) all CBMIMO1=1 && $(MAKE) clean CBMIMO1=1) - -scope: - (cd $(OPENAIR1_DIR)/USERSPACE_TOOLS/SCOPE && $(MAKE) clean && $(MAKE) all && $(MAKE) clean ) - -#Remove all but source files -cleanall: - (cd $(OPENAIR1_DIR) && $(MAKE) cleanall) - (cd $(OPENAIR2_DIR) && $(MAKE) cleanall) - -fifos: - @for i in `seq 0 64`;\ - do \ - have_rtfX=`ls /dev/ |grep -c rtf$$i`;\ - if [ "$$have_rtfX" -eq 0 ] ;then \ - mknod -m 666 /dev/rtf$$i c 150 $$i; \ - fi;\ - done - -openair0: - mknod /dev/openair0 c 127 0 - chmod a+rw /dev/openair0 - -install_oai_user: - make fifos - insmod openair_rf_softmodem.ko - -updatefw: - $(OPENAIR1_DIR)/USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 - -boot_exmimo: - sudo make install_oai_user - $(OPENAIR1_DIR)/USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 - sleep 1 - sudo rmmod openair_rf - sudo make install_oai_user - -reboot_exmimo: - $(OPENAIR1_DIR)/USERSPACE_TOOLS/OAI_FW_INIT/updatefw -f $$OPENAIR0_DIR/express-mimo/software/sdr/main -s 0x43fffff0 -b - sudo rmmod openair_rf - sudo make install_oai_user - -install_softmodem: - make fifos -ifeq ($(OPENAIR2),1) - insmod asn1_msg_kern.ko -endif - insmod openair_rf_softmodem.ko - -remove: - rmmod openair_rf -ifeq ($(OPENAIR2),1) - rmmod asn1_msg_kern -endif - -test: - (cd $(OPENAIR1_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) test RTAI=1 CBMIMO1=1) - (cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES && $(MAKE) test) - -clean: - (cd $(OPENAIR1_DIR)/ARCH/CBMIMO1/DEVICE_DRIVER && $(MAKE) clean RTAI=1 CBMIMO1=1) - (cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES && $(MAKE) clean) diff --git a/targets/RT/USER/Makefile b/targets/RT/USER/Makefile deleted file mode 100644 index 8c413d4e2e..0000000000 --- a/targets/RT/USER/Makefile +++ /dev/null @@ -1,447 +0,0 @@ -# Include some shared directives -include $(OPENAIR_TARGETS)/Makerules - -default: lte-softmodem -all: lte-softmodem rrh - -include $(OPENAIR_TARGETS)/Makefile.common - -KERNEL_VERSION:=$(shell echo `uname -r | cut -d. -f-2`) -KERNEL_TYPE:=$(shell echo `uname -r | cut -d. -f-3 | cut -d- -f3`) -DEADLINE_SCHEDULER_KERNEL:=$(shell if [ $(KERNEL_TYPE) = "lowlatency" ]; then echo "1" ; else echo "0" ; fi) - -include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc - -ifdef EXMIMO -#ifdef DEADLINE_SCHEDULER # this ifdef is to be removed after the debugging -ifeq ($(DEADLINE_SCHEDULER_KERNEL),1) -CFLAGS+=-DDEADLINE_SCHEDULER -endif -#endif -endif - -ifndef USRP -USRP=0 -endif - -CFLAGS += -DDRIVER2013 -I$(OPENAIR_TARGETS)/ARCH/COMMON -I. - -ifndef OPENAIR2 -OPENAIR2=1 -endif - -ifdef DEBUG -DISABLE_XER_PRINT=0 -MSG_PRINT=1 -endif - -ifdef Rel10 -CFLAGS += -DRel10 -endif - -ifeq ($(EXMIMO),1) - CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/DEFS -DENABLE_VCD_FIFO -endif - -ifeq ($(ETHERNET),1) - CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/ -DETHERNET -endif - -ifeq ($(DEBUG),1) -CFLAGS += -g -ggdb -#CFLAGS += -DRRC_MSG_PRINT -#CFLAGS += -DPDCP_MSG_PRINT -else -CFLAGS += -O2 -endif - -ifdef ($(MSG_PRINT),1) -CFLAGS += -DRRC_MSG_PRINT -CFLAGS += -DPDCP_MSG_PRINT -endif - -SRC = synctest.c condtest.c - -ifndef RTAI -RTAI=1 -endif - -ifeq ($(LOCALIZATION), 1) -CFLAGS += -DLOCALIZATION -endif - -ifeq ($(LINUX_LIST), 1) -CFLAGS += -DLINUX_LIST -endif - -ifeq ($(RTAI),1) -CFLAGS += -DENABLE_RTAI_CLOCK -CFLAGS += -DCONFIG_RTAI_LXRT_INLINE #remend the RTAI warning -RTAI_OBJ = sched_dlsch.o sched_rx_pdsch.o rt_wrapper.o -else #RTAI -CFLAGS += -DENABLE_USE_CPU_EXECUTION_TIME -OBJ += sched_dlsch.o sched_rx_pdsch.o rt_wrapper.o -endif - -OBJ += $(OPENAIR1_DIR)/SIMULATION/TOOLS/taus.o $(OPENAIR_TARGETS)/SIMU/USER/init_lte.o - -ifeq ($(EXMIMO),1) -OBJ += $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.o $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/gain_control.o -CFLAGS += -DDRIVER2013 -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/DEFS -endif - -CFLAGS += -DENABLE_VCD_FIFO - - -TOP_DIR = $(OPENAIR1_DIR) -include $(OPENAIR1_DIR)/PHY/Makefile.inc -include $(OPENAIR1_DIR)/SCHED/Makefile.inc - -OBJ += $(PHY_OBJS) -ifeq ($(RTAI),1) -RTAI_OBJ += $(SCHED_OBJS) -else -OBJ += $(SCHED_OBJS) -endif - -OPENAIR2_TOP = $(OPENAIR2_DIR) -include $(OPENAIR2_DIR)/LAYER2/Makefile.inc -include $(OPENAIR2_DIR)/UTIL/Makefile.inc -include $(OPENAIR2_DIR)/RRC/NAS/Makefile.inc -include $(OPENAIR2_DIR)/ENB_APP/Makefile.inc - -ifeq ($(USRP),1) - -include $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/Makefile.inc -#CFLAGS += -I/opt/include/uhd -L/opt/lib -luhd -lpthread -lstdc++ -CFLAGS += -I/usr/include/uhd -L/usr/lib -luhd -lpthread -lstdc++ -CFLAGS += -DOAI_USRP -#LDFLAGS += -L/opt/lib -luhd -lpthread -lstdc++ -LDFLAGS += -L/usr/lib/ -luhd -lpthread -lstdc++ -endif - -ifeq ($(ETHERNET),1) -include $(OPENAIR_TARGETS)/ARCH/ETHERNET/USERSPACE/LIB/Makefile.inc -LDFLAGS += -lpthread -endif - -OBJ += $(ENB_APP_OBJS) - -ifeq ($(RTAI),1) -CFLAGS += -I/usr/realtime/include -I/usr/realtime/include/asm -LOG_OBJS= -RTAI_OBJ+=$(LOG_DIR)/vcd_signal_dumper.o -RTAI_OBJ+=$(LOG_DIR)/log.o -endif - - -OBJ += $(LOG_OBJS) - -ifeq ($(OPENAIR2),1) -ASN1_MSG_OBJS1=$(addprefix $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/, $(ASN1_MSG_OBJS)) -OBJ += $(L2_OBJS) $(LIST_OBJ) $(TIMER_OBJ) $(MEM_OBJ) $(OTG_OBJS) $(MATH_OBJS) $(OSA_OBJS) $(OPT_OBJS) -OBJ += $(OPENAIR1_DIR)/SIMULATION/ETH_TRANSPORT/netlink_init.o -#OBJ += $(PDCP_DIR)/pdcp_thread.o -CFLAGS += -DOPENAIR2 -DNO_RRM -DPUCCH -DMAC_CONTEXT=1 -endif - -#ifdef ENABLE_ITTI -RTAI_OBJ += $(UTILS_OBJS) -#else -#OBJ += $(UTILS_OBJS) -#endif - -ifdef SPECTRA -CFLAGS += -DSPECTRA -endif - -#ifdef ENABLE_ITTI -CFLAGS += -DEXMIMO_IOT -#endif - -CFLAGS += $(L2_incl) $(ENB_APP_incl) $(UTIL_incl) $(UTILS_incl) - -CFLAGS += -I$(OPENAIR1_DIR) -I$(OPENAIR2_DIR)/RRC/LITE/MESSAGES #-I$(OPENAIR3_DIR)/MESH -I$(OPENAIR3_DIR)/MESH/RRM - -CFLAGS += -DNEW_FFT -DLOG_NO_THREAD - -ifeq ($(XFORMS),1) -CFLAGS += -DXFORMS -I/usr/include/X11 -LDFLAGS += -lforms -OBJ += $(OPENAIR1_DIR)/PHY/TOOLS/lte_phy_scope.o -OBJ += stats.o -endif - -OBJ_SYNC = $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.o rt_wrapper.o $(OPENAIR2_DIR)/UTIL/LOG/log.o $(OPENAIR2_DIR)/UTIL/LOG/vcd_signal_dumper.o - -ifdef SMBV -CFLAGS += -DSMBV -endif - -CFLAGS += -DPHYSIM -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DPHY_CONTEXT=1 -CFLAGS += -DOPENAIR_LTE -DENABLE_FXP -DOPENAIR1 #-DDLSCH_THREAD #-DULSCH_THREAD - - -ifeq ($(EXMIMO),1) -CFLAGS += -DEXMIMO -#CFLAGS += -DEXMIMO -DTIMING_ADVANCE_HW=138 #this is for ExpressMIMO 1 -#CFLAGS += -DEXMIMO -DTIMING_ADVANCE_HW=45 #this is for ExpressMIMO 2 -endif - -ifeq ($(HARD_RT),1) -CFLAGS += -DHARD_RT -endif - -ifeq ($(EMOS),1) -CFLAGS += -D_FILE_OFFSET_BITS=64 #-DEMOS -DEMOS_CHANNEL -LDFLAGS += -lgps -endif - - -ifeq ($(LINK_ENB_PDCP_TO_GTPV1U), 1) -CFLAGS += -DLINK_ENB_PDCP_TO_GTPV1U -endif - -ifeq ($(LINK_ENB_PDCP_TO_IP_DRIVER), 1) -CFLAGS += -DPDCP_USE_NETLINK -DLINUX -OBJ += $(NAS_OBJS) -NAS_FLAG=1 -endif - -LDFLAGS += -lpthread -lm -lforms -lconfig -lrt -ifeq ($(RTAI),1) -RTAI_CFLAGS += $(shell rtai-config --lxrt-cflags) -DRTAI -LDFLAGS += $(shell rtai-config --lxrt-ldflags) -endif - -#ifeq ($(USRP),1) -#CFLAGS += -I/opt/uhd/include -L/opt/uhd/lib -luhd -lpthread -lstdc++ -#CFLAGS += -DOAI_USRP -#endif -#CFLAGS += -I/usr/include/c++/4.6 -I/usr/include/c++/4.6/x86_64-linux-gnu -I/usr/include/rtai/ - -LFDS_OBJ_DIR = $(subst $(OPENAIR_DIR),$(OBJS_DIR),$(LFDS_DIR)) -LFDS_LIB = $(LFDS_OBJ_DIR)/bin/liblfds611.a -LIBS += $(LFDS_LIB) -SHARED_DEPENDENCIES += $(LFDS_LIB) - --include $(OBJ:.o=.d) --include $(ASN1_MSG_OBJS1:.o=.d) --include $(RTAI_OBJ:.o=.d) --include lte-softmodem.d --include lte-ue.d --include rrh.d - -$(LFDS_LIB): - @if [ ! -d $(LFDS_OBJ_DIR)/bin ]; then mkdir -p $(LFDS_OBJ_DIR)/bin; fi; - @if [ ! -d $(LFDS_OBJ_DIR)/obj ]; then mkdir -p $(LFDS_OBJ_DIR)/obj; fi; - $(MAKE) -C $(LFDS_DIR) -f makefile.linux OUTDIR=$(LFDS_OBJ_DIR) - -ifeq ($(USRP),1) -$(USRP_OBJ):$(USRP_FILE_OBJ) - @echo Compiling $< - @$(CXX) -c -g -ggdb $(USRP_CFLAGS) $(USRP_FILE_OBJ) -o $(USRP_OBJ) -endif - -ifeq ($(ETHERNET),1) -$(ETHERNET_OBJ):$(ETHERNET_FILE_OBJ) - @echo Compiling $< - @$(CC) -c -g -ggdb $(ETHERNET_CFLAGS) $(ETHERNET_FILE_OBJ) -o $(ETHERNET_OBJ) -endif - -ifeq ($(RTAI),1) -$(RTAI_OBJ) lte-softmodem.o lte-ue.o: %.o : %.c -else -$(RTAI_OBJ): %.o : %.c -endif - @echo Compiling $< ... - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) -o $@ $< - @$(CC) -MM $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) $< > $*.d - @mv -f $*.d $*.d.tmp - @sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d - @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ - sed -e 's/^ *//' -e 's/$$/:/' >> $*.d - @rm -f $*.d.tmp - -ifdef ENABLE_ITTI -$(OBJ) $(RTAI_OBJ): $(ITTI_MESSAGES_H) -endif - -ifeq ($(RTAI),1) -$(OBJ) $(ASN1_MSG_OBJS1): %.o : %.c -else -$(OBJ) $(ASN1_MSG_OBJS1) lte-softmodem.o lte-ue.o: %.o : %.c -endif - -rrh.o: %.o : %.c - - @echo Compiling $< ... - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $< - @$(CC) -MM $(CFLAGS) $(EXTRA_CFLAGS) $< > $*.d - @mv -f $*.d $*.d.tmp - @sed -e 's|.*:|$*.o:|' < $*.d.tmp > $*.d - @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \ - sed -e 's/^ *//' -e 's/$$/:/' >> $*.d - @rm -f $*.d.tmp - -OBJ_EMOS = $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.o $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/gain_control.o rt_wrapper.o $(OPENAIR2_DIR)/UTIL/LOG/log.o $(OPENAIR2_DIR)/UTIL/LOG/vcd_signal_dumper.o $(OPENAIR1_DIR)/PHY/TOOLS/signal_energy.o $(OPENAIR1_DIR)/PHY/TOOLS/dB_routines.o -ifeq ($(XFORMS),1) -OBJ_EMOS+=lte_scope.o -endif - -condtest: condtest.c - $(CC) $(CFLAGS) $(LDFLAGS) condtest.c -o condtest - -synctest: $(OBJ_SYNC) $(SHARED_DEPENDENCIES) synctest.c - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) $(OBJ_SYNC) -o synctest synctest.c $(LDFLAGS) $(LIBS) - -sleeptest: rt_wrapper.o sleeptest.c - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) rt_wrapper.o -o sleeptest sleeptest.c $(LDFLAGS) - -lte-softmodem: $(OBJ) $(USRP_OBJ) $(ETHERNET_OBJ) $(ASN1_MSG_OBJS1) $(RTAI_OBJ) lte-ue.o lte-softmodem.o $(SHARED_DEPENDENCIES) - @echo Linking $@ - @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(OBJ) $(USRP_OBJ) $(ETHERNET_OBJ) $(RTAI_OBJ) $(ASN1_MSG_OBJS1) lte-ue.o lte-softmodem.o -o lte-softmodem $(LDFLAGS) $(LIBS) - -rrh: rrh.o - @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) rrh.o -o rrh -lpthread -lrt - -emos-raw: $(SHARED_DEPENDENCIES) $(OBJ_EMOS) emos-raw.c - @$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) $(OBJ_EMOS) -o emos-raw emos-raw.c $(LDFLAGS) $(LIBS) - - -synctest_eNB: synctest - cp synctest synctest_eNB - -synctest_UE: synctest - cp synctest synctest_UE - -drivers: -# cd $(OPENAIR2_DIR) && make clean && make nasmesh_netlink.ko -# cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && make clean && make - cd $(OPENAIR_TARGETS)/ARCH/EXMIMO/DRIVER/eurecom && make clean && make - cd $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT && make clean && make - cp $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw $(OPENAIR_TARGETS)/bin/. - -run: condtest - rtai-load condtest --verbose - -run_eNB_test: - rtai-load eNB_test --verbose - -run_eNB: - rtai-load eNB --verbose - -run_UE: - rtai-load UE --verbose - -run_UE0: - rtai-load UE0 --verbose - -run_UE0_smbv: - rtai-load UE0_smbv --verbose - -run_UE850: - rtai-load UE850 --verbose - -run_eNB850: - rtai-load eNB850 --verbose - -run_UE0prach: - rtai-load UE0prach --verbose - -run_UE1prach: - rtai-load UE1prach --verbose - -run_UE2prach: - rtai-load UE2prach --verbose - -run_UE0noL2: - rtai-load UE0noL2 -- verbose - -run_UE1noL2: - rtai-load UE1noL2 --verbose - -run_UE2noL2: - rtai-load UE2noL2 --verbose - -run_UE0calib: - rtai-load UE0calib --verbose - -run_UE0calibmed: - rtai-load UE0calibmed --verbose - -run_UE0calibbyp: - rtai-load UE0calibbyp --verbose - -run_UE1: - rtai-load UE1 --verbose - -run_UE2: - rtai-load UE2 --verbose - -run_eNB0: - rtai-load eNB0 --verbose - -run_eNB1: - rtai-load eNB1 --verbose - -run_eNB2: - rtai-load eNB2 --verbose - -clean: cleanmodem common-clean - -cleanmodem: - @$(RM_F_V) $(OBJ) $(RTAI_OBJ) $(OBJ_EMOS) $(OBJ_SYNC) $(USRP_OBJ) $(ETHERNET_OBJ) - @$(RM_F_V) $(OBJ:.o=.d) $(RTAI_OBJ:.o=.d) $(OBJ_EMOS:.o=.d) $(OBJ_SYNC:.o=.d) - @$(RM_F_V) $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1_msg.o $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1_msg.d - @$(RM_F_V) lte-ue.o lte-ue.d rrh.o rrh.d lte-softmodem.o lte-softmodem.d - @$(RM_F_V) rrh.o lte-ue.o lte-softmodem.o - -cleanasn1: - rm -f $(ASN1_MSG_OBJS1) - $(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ; rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS) *.o *.d ) - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.am.sample - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel* - -cleancell: - rm -f $(OPENAIR2_DIR)/RRC/CELLULAR/*.o - rm -f $(OPENAIR2_DIR)/RRC/CELLULAR/*.d - rm -f $(OPENAIR2_DIR)/RRC/L2_INTERFACE/*.o - rm -f $(OPENAIR2_DIR)/RRC/L2_INTERFACE/*.d - rm -f $(OPENAIR2_DIR)/NAS/SIMU_CELLULAR/*.o - rm -f $(OPENAIR2_DIR)/NAS/SIMU_CELLULAR/*.d - -cleanalmostall: cleanmodem - rm -f $(ASN1_MSG_OBJS1) - rm -rf condtest synctest lte-softmodem rrh - rm -rf synctest_eNB synctest_UE - -cleanall: common-cleanall clean cleanasn1 - rm -rf condtest synctest lte-softmodem rrh - rm -rf synctest_eNB synctest_UE - -show: - @echo $(CFLAGS) - @echo $(EXTRA_CFLAGS) - @echo $(OBJ) $(RTAI_OBJ) - @echo $(USRP_OBJ) - @echo $(ETHERNET_OBJ) - @echo $(ETHERNET_FILE_OBJ) - @echo IS_REL8 is $(IS_REL8) - @echo IS_REL10 is $(IS_REL10) - @echo openssl $(OPENSSL_FOUND) - @echo nettle $(NETTLE_FOUND) - @echo lowlatency kernel: $(DEADLINE_SCHEDULER_KERNEL) - -beautiful: - astyle --style=gnu -s2 $(SRC) - -fifos: - @for i in `seq 0 64`;\ - do \ - have_rtfX=`ls /dev/ |grep -c rtf$$i`;\ - if [ "$$have_rtfX" -eq 0 ] ;then \ - mknod -m 666 /dev/rtf$$i c 150 $$i; \ - fi;\ - done diff --git a/targets/RT/USER/Makefile.agilent b/targets/RT/USER/Makefile.agilent deleted file mode 100644 index 061c15a31c..0000000000 --- a/targets/RT/USER/Makefile.agilent +++ /dev/null @@ -1,243 +0,0 @@ -include $(OPENAIR_TARGETS)/Makerules - -include $(OPENAIR_TARGETS)/Makefile.common - -CFLAGS += -DDRIVER2013 -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/ARCH/EXMIMO/DEFS -DENABLE_VCD_FIFO -DEXMIMO_IOT - -SRC = lte-enb.c - -ifndef RTAI -RTAI=1 -endif - -ifeq ($(RTAI),1) -CFLAGS += -DENABLE_RTAI_CLOCK -DRTAI -RTAI_OBJ = sched_dlsch.o sched_ulsch.o sched_rx_pdsch.o lte-enb.o rt_wrapper.o -else -OBJ = sched_dlsch.o sched_ulsch.o sched_rx_pdsch.o lte-enb.o rt_wrapper.o -CFLAGS += -DENABLE_USE_CPU_EXECUTION_TIME -endif - -OBJ += $(OPENAIR1_DIR)/SIMULATION/TOOLS/taus.o $(OPENAIR_TARGETS)/SIMU/USER/init_lte.o $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.o - -TOP_DIR = $(OPENAIR1_DIR) -include $(OPENAIR1_DIR)/PHY/Makefile.inc -include $(OPENAIR1_DIR)/SCHED/Makefile.inc - -OBJ += $(PHY_OBJS) -ifeq ($(RTAI),1) -RTAI_OBJ += $(SCHED_OBJS) -else -OBJ += $(SCHED_OBJS) -endif - -#ifndef rrc_cellular -ifeq ($(rrc_cellular),0) -rrc_cellular = 0 -rrc_cellular_eNB = 0 -rrc_cellular_UE = 0 -else - ifeq ($(eNB_flag),1) - rrc_cellular_eNB=1 - endif - ifeq ($(UE_flag),1) - rrc_cellular_UE=1 - endif -endif - -export rrc_cellular - -OPENAIR2_TOP = $(OPENAIR2_DIR) -include $(OPENAIR2_DIR)/LAYER2/Makefile.inc -include $(OPENAIR2_DIR)/UTIL/Makefile.inc -include $(OPENAIR2_DIR)/RRC/NAS/Makefile.inc - -ifeq ($(RTAI),1) -LOG_OBJS= -RTAI_OBJ+=$(LOG_DIR)/vcd_signal_dumper.o -RTAI_OBJ+=$(LOG_DIR)/log.o -endif - -include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc - -OBJ += $(LOG_OBJS) - -ifndef OPENAIR2 -OPENAIR2=1 -endif -ifeq ($(OPENAIR2),1) -ASN1_MSG_OBJS1=$(addprefix $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/, $(ASN1_MSG_OBJS)) -OBJ += $(L2_OBJS) $(LIST_OBJ) $(TIMER_OBJ) $(MEM_OBJ) $(OTG_OBJS) $(MATH_OBJS) -OBJ += $(OPENAIR1_DIR)/SIMULATION/ETH_TRANSPORT/netlink_init.o -OBJ += $(PDCP_DIR)/pdcp_thread.o -CFLAGS += -DOPENAIR2 -DNO_RRM -DPUCCH -DMAC_CONTEXT=1 -endif - -CFLAGS += $(L2_incl) $(UTIL_incl) $(UTILS_incl) - -CFLAGS += -I$(OPENAIR1_DIR) -I$(OPENAIR2_DIR)/RRC/LITE/MESSAGES #-I$(OPENAIR3_DIR)/MESH -I$(OPENAIR3_DIR)/MESH/RRM - -CFLAGS += -DNEW_FFT -DLOG_NO_THREAD - -ifeq ($(XFORMS),1) -CFLAGS += -DXFORMS -I/usr/include/X11 -LDFLAGS += -lforms -OBJ += $(OPENAIR1_DIR)/PHY/TOOLS/lte_phy_scope.o -OBJ += stats.o -endif - -ifdef SMBV -CFLAGS += -DSMBV -endif - -CFLAGS += -DPHYSIM -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DPHY_CONTEXT=1 -CFLAGS += -DOPENAIR_LTE -DENABLE_FXP -DOPENAIR1 -DDLSCH_THREAD #-DULSCH_THREAD - -#only for CBMIMO1 -ifdef CBMIMO1 -CFLAGS += -DFW2011 -DBIT8_TX -DCBMIMO1 -else -#only for EXPRESS MIMO -CFLAGS += -DEXMIMO -#CFLAGS += -DEXMIMO -DTIMING_ADVANCE_HW=138 #this is for ExpressMIMO 1 -#CFLAGS += -DEXMIMO -DTIMING_ADVANCE_HW=45 #this is for ExpressMIMO 2 -endif - -ifndef HARD_RT -HARD_RT=1 -endif - -ifeq ($(HARD_RT),1) -CFLAGS += -DHARD_RT -endif - -ifeq ($(EMOS),1) -CFLAGS += -DEMOS -DEMOS_CHANNEL -LDFLAGS += -lgps -endif - -ifndef NAS -NAS=1 -endif - -ifeq ($(NAS),1) -CFLAGS += -DPDCP_USE_NETLINK -DLINUX -OBJ += $(NAS_OBJS) -endif - -RTAI_CFLAGS += $(shell rtai-config --lxrt-cflags) -CFLAGS += -I/usr/realtime/include -DRTAI -LDFLAGS += -lpthread -lm -lforms -ifeq ($(RTAI),1) -LDFLAGS += $(shell rtai-config --lxrt-ldflags) -else -LDFLAGS += -lrt -endif - -#ifndef USE_MME -# USE_MME=R8 -#endif - -ifdef USE_MME - include $(OPENAIR2_DIR)/S1AP/Makefile.inc - include $(OPENAIR2_DIR)/S1AP/MESSAGES/Makefile.inc - CFLAGS += -DENABLE_USE_MME -DENB_MODE - LDFLAGS += -lsctp - CFLAGS_S1AP += -DENB_MODE -DENABLE_USE_MME -DEMIT_ASN_DEBUG=1 -DUSER_MODE - S1AP_BUILT_OBJS += $(S1AP_OBJS) $(addprefix $(OPENAIR2_DIR)/S1AP/MESSAGES/, $(S1AP_ASN_MODULE_SOURCES)) - S1AP_BUILT_OBJS += $(OPENAIR3_DIR)/OPENAIRMME/SCTP/sctp_primitives_client.o -endif - - -ASN1RELDIR=R9.8 -ifeq ($(USE_MME), R8) - ASN1RELDIR=R8.10 -else - CFLAGS_S1AP += -DUPDATE_RELEASE_9 -endif -S1AP_DIR=$(OPENAIR2_DIR)/S1AP -ASN1MESSAGESDIR=$(S1AP_DIR)/MESSAGES -ASN1DIR=$(ASN1MESSAGESDIR)/ASN1 - -all: lte-enb - -$(LFDS_DIR)/bin/liblfds611.a: - $(MAKE) -C $(LFDS_DIR) -f makefile.linux - - -$(RTAI_OBJ): %.o : %.c - @echo Compiling $< ... - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $(RTAI_CFLAGS) -o $@ $< - -$(OBJ) $(ASN1_MSG_OBJS1): %.o : %.c - @echo Compiling $< ... - @$(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) -o $@ $< - -$(S1AP_BUILT_OBJS): %.o : %.c - @echo Compiling $< - @$(CC) -Wall -c $(CFLAGS_S1AP) $(S1AP_Incl) $(UTIL_incl) -o $@ $< - -$(ASN1MESSAGESDIR)/s1ap_ieregen.stamp: $(ASN1DIR)/$(ASN1RELDIR)/S1AP-PDU-Contents.asn $(ASN1DIR)/asn1tostruct.py - echo Timestamp > $@ - (cd $(ASN1DIR) && python $(ASN1DIR)/asn1tostruct.py -f$<) - -$(ASN1MESSAGESDIR)/s1ap_asn1regen.stamp: $(ASN1DIR)/$(ASN1RELDIR)/S1AP-CommonDataTypes.asn $(ASN1DIR)/$(ASN1RELDIR)/S1AP-Constants.asn $(ASN1DIR)/$(ASN1RELDIR)/S1AP-IEs.asn $(ASN1DIR)/$(ASN1RELDIR)/S1AP-PDU.asn - echo Timestamp > $@ - (cd $(ASN1MESSAGESDIR) && asn1c -gen-PER -fnative-types -fskeletons-copy $^) - -$(S1AP_DIR)/libs1ap.a: $(ASN1MESSAGESDIR)/s1ap_ieregen.stamp $(ASN1MESSAGESDIR)/s1ap_asn1regen.stamp $(S1AP_BUILT_OBJS) - @echo Creating $@ - $(AR) rcs $@ $^ - -$(LFDS_DIR)/bin/liblfds611.a: - $(MAKE) -C $(LFDS_DIR) -f makefile.linux - -ifdef USE_MME - lte-enb: $(OBJ) $(S1AP_DIR)/libs1ap.a $(ASN1_MSG_OBJS1) $(RTAI_OBJ) $(LFDS_DIR)/bin/liblfds611.a -else - lte-enb: $(OBJ) $(ASN1_MSG_OBJS1) $(RTAI_OBJ) $(LFDS_DIR)/bin/liblfds611.a -endif - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(OBJ) $(RTAI_OBJ) $(ASN1_MSG_OBJS1) -o lte-enb $(LDFLAGS) $(LFDS_DIR)/bin/liblfds611.a - - - -nasmesh: - (cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE)) - (cd $(OPENAIR2_DIR) && $(MAKE) nasmesh_netlink.ko) - (sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko) -rb_tool: - (cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && $(MAKE)) - -nasmesh_install: - (sudo rmmod nasmesh) - (sudo insmod $(OPENAIR2_DIR)/NAS/DRIVER/MESH/nasmesh.ko) - -clean: - rm -rf $(OBJ) $(RTAI_OBJ) - rm -f $(S1AP_BUILT_OBJS) - rm -f $(ASN1MESSAGESDIR)/libs1ap.a - -cleanasn1: - rm -f $(ASN1_MSG_OBJS1) - $(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ; rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS) *.o *.d ) - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.am.sample - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel8 - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel10 - -cleanall: clean cleanasn1 - rm -rf condtest synctest lte-softmodem - rm -rf synctest_eNB synctest_UE - -show: - @echo $(CFLAGS) - @echo $(EXTRA_CFLAGS) - @echo $(OBJ) $(RTAI_OBJ) - @echo rrc_cellular variable is $(rrc_cellular) - @echo eNB_flag is $(eNB_flag) - @echo UE_flag is $(UE_flag) - @echo IS_REL8 is $(IS_REL8) - @echo IS_REL10 is $(IS_REL10) - -beautiful: - astyle --style=gnu -s2 $(SRC) diff --git a/targets/RT/USER/Makefile.msg_many b/targets/RT/USER/Makefile.msg_many deleted file mode 100644 index bc7840c1e5..0000000000 --- a/targets/RT/USER/Makefile.msg_many +++ /dev/null @@ -1,21 +0,0 @@ -CFLAGS = $(shell rtai-config --lxrt-cflags) -LDFLAGS = $(shell rtai-config --lxrt-ldflags) -lpthread -llxrt -lm - -CFLAGS += -D__IN_RTAI__ -Wall -O2 -I. - -OBJS = msg_many.o msg_helper.o - -all: msg_many - -msg_many: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) - -$(OBJS): msg_many.h - -run: msg_many - rtai-load msg_many --verbose - -.PHONY: clean -clean: - rm -f msg_many $(OBJS) - diff --git a/targets/RT/USER/UE_transport_IQ.c b/targets/RT/USER/UE_transport_IQ.c deleted file mode 100644 index 16f491263d..0000000000 --- a/targets/RT/USER/UE_transport_IQ.c +++ /dev/null @@ -1,548 +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 UE_transport_IQ.c - * \brief UE transport IQ sampels - * \author Katerina Trilyraki, Navid Nikaein, Raymond Knopp - * \date 2015 - * \version 0.1 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning very experimental - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "common_lib.h" -#include "PHY/defs.h" -#include "rrh_gw.h" -#include "rrh_gw_externs.h" - -#define START_CMD 1 -#define RRH_UE_PORT 51000 -#define RRH_UE_DEST_IP "127.0.0.1" -#define PRINTF_PERIOD 3750 - -/****************************************************************************** - ** FUNCTION PROTOTYPES ** - ******************************************************************************/ -void *rrh_proc_UE_thread(void *); -void *rrh_UE_thread(void *); -void *rrh_UE_rx_thread(void *); -void *rrh_UE_tx_thread(void *); - - - -openair0_timestamp timestamp_UE_tx[4]= {0,0,0,0},timestamp_UE_rx[4]= {0,0,0,0}; -openair0_timestamp nrt_UE_counter[4]= {0,0,0,0}; - -pthread_t main_rrh_UE_thread,main_rrh_proc_UE_thread; -pthread_attr_t attr, attr_proc; -struct sched_param sched_param_rrh, sched_param_rrh_proc; -pthread_cond_t sync_UE_cond[4]; -pthread_mutex_t sync_UE_mutex[4]; - -int32_t overflow_rx_buffer_UE[4]= {0,0,0,0}; -int32_t nsamps_UE[4]= {0,0,0,0}; -int32_t UE_tx_started=0,UE_rx_started=0; -int32_t RT_flag_UE=0, NRT_flag_UE=1; -int32_t counter_UE_rx[4]= {0,0,0,0}; -int32_t counter_UE_tx[4]= {0,0,0,0}; -int32_t **tx_buffer_UE, **rx_buffer_UE; - -int sync_UE_rx[4]= {-1,-1,-1,-1}; -void *rrh_UE_thread_status; - - -void *rx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_rx -void *tx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_tx - - -void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) { - - int i; - int error_code_UE, error_code_proc_UE; - - RT_flag_UE=RT_flag; - NRT_flag_UE=NRT_flag; - - pthread_attr_init(&attr); - sched_param_rrh.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_init(&attr_proc); - sched_param_rrh_proc.sched_priority = sched_get_priority_max(SCHED_FIFO-1); - - pthread_attr_setschedparam(&attr,&sched_param_rrh); - pthread_attr_setschedpolicy(&attr,SCHED_FIFO); - pthread_attr_setschedparam(&attr_proc,&sched_param_rrh_proc); - pthread_attr_setschedpolicy(&attr_proc,SCHED_FIFO-1); - - - for (i=0; i<4; i++) { - pthread_mutex_init(&sync_UE_mutex[i],NULL); - pthread_cond_init(&sync_UE_cond[i],NULL); - } - - error_code_UE = pthread_create(&main_rrh_UE_thread, &attr, rrh_UE_thread, (void *)dev_ue); - error_code_proc_UE = pthread_create(&main_rrh_proc_UE_thread, &attr_proc, rrh_proc_UE_thread, (void *)dev_ue); - - if (error_code_UE) { - printf("Error while creating UE thread\n"); - exit(-1); - } - - if (error_code_proc_UE) { - printf("Error while creating UE proc thread\n"); - exit(-1); - } - -} - - -/*! \fn void *rrh_proc_UE_thread((void *)dev_ue) -* \brief this function -* \param[in] -* \param[out] -* \return -* \note -* @ingroup _oai -*/ -void *rrh_proc_UE_thread(void * arg) { - - int antenna_index,i; - openair0_timestamp truncated_timestamp, truncated_timestamp_final, last_hw_counter=0; - struct timespec time_req, time_rem; - int16_t *txp,*rxp; - unsigned int samples_per_frame=0; - rrh_module_t *dev=(rrh_module_t *)arg; - - samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame; - AssertFatal(samples_per_frame <=0, "invalide samples_per_frame !%u\n",samples_per_frame); - - time_req.tv_sec = 0; - time_req.tv_nsec = 1000; - - while (rrh_exit==0) { - //wait until some data has been copied - for (antenna_index=0; antenna_index<4; antenna_index++) { - if (sync_UE_rx[antenna_index]==0) { - if (!UE_tx_started) { - UE_tx_started=1; //Set this flag to 1 to indicate that a UE started retrieving data - if (RT_flag_UE==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_flag_UE==1) { - if (hw_counter > last_hw_counter+1) { - printf("L1"); - // goto end_copy_UE; - } else { - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req,&time_rem); - } - } - } - - truncated_timestamp = timestamp_UE_tx[antenna_index]%(samples_per_frame); - truncated_timestamp_final = (timestamp_UE_tx[antenna_index]+nsamps_UE[antenna_index])%samples_per_frame; - - if ((truncated_timestamp + nsamps_UE[antenna_index]) > samples_per_frame) { - if ((timestamp_eNB_rx[antenna_index]%samples_per_frame < nsamps_UE[antenna_index]) && (eNB_rx_started==1)) { - overflow_rx_buffer_eNB[antenna_index]++; - printf("eNB Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_eNB[antenna_index],(int)truncated_timestamp); - - if (NRT_flag_UE==1) { - while ((timestamp_eNB_rx[antenna_index]%samples_per_frame) < nsamps_UE[antenna_index]) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][truncated_timestamp]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][truncated_timestamp]; - - for (i=0; i<(samples_per_frame<<1)-(truncated_timestamp<<1); i++) { - rxp[i] = txp[i]>>6; - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][0]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][0]; - - for (i=0; i>6; - } - - } else { - if (((truncated_timestamp < (timestamp_eNB_rx[antenna_index]%samples_per_frame)) && - (truncated_timestamp_final > (timestamp_eNB_rx[antenna_index]%samples_per_frame))) && - (eNB_rx_started==1)) { - overflow_rx_buffer_eNB[antenna_index]++; - printf("eNB Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_eNB[antenna_index],(int)truncated_timestamp); - - if (NRT_flag_UE==1) { - while (truncated_timestamp_final > timestamp_eNB_rx[antenna_index]%samples_per_frame) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][truncated_timestamp]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][truncated_timestamp]; - - for (i=0; i<(nsamps_eNB[antenna_index]); i++) { - rxp[i] =txp[i]>>6; - } - - } - //end_copy_UE : - last_hw_counter=hw_counter; - pthread_mutex_lock(&sync_UE_mutex[antenna_index]); - sync_UE_rx[antenna_index]--; - pthread_mutex_unlock(&sync_UE_mutex[antenna_index]); - - } - } - - } - - return(0); -} - -/*! \fn void *rrh_UE_thread(void *arg) -* \brief this function -* \param[in] -* \param[out] -* \return -* \note -* @ingroup _oai -*/ -void *rrh_UE_thread(void *arg) { - - rrh_module_t *dev=(rrh_module_t *)arg; - - struct sched_param sched_param_UE_rx, sched_param_UE_tx; - int16_t i,cmd; //,nsamps,antenna_index; - //struct timespec time_req_1us; - pthread_t UE_rx_thread, UE_tx_thread; - pthread_attr_t attr_UE_rx, attr_UE_tx; - int error_code_UE_rx, error_code_UE_tx; - void *tmp; - unsigned int samples_per_frame=0; - - samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame; - //time_req_1us.tv_sec = 0; - //time_req_1us.tv_nsec = 1000; - - while (rrh_exit==0) { - - cmd=dev->eth_dev.trx_start_func(&dev->eth_dev); - - /* allocate memory for TX/RX buffers */ - rx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*)); - tx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*)); - - for (i=0; ieth_dev.openair0_cfg->rx_num_channels; i++) { - tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4)); - memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4)); - rx_buffer_UE[i]=(tmp+4*sizeof(int32_t)); - } - - for (i=0; ieth_dev.openair0_cfg->tx_num_channels; i++) { - tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4)); - memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4)); - tx_buffer_UE[i]=(tmp+4*sizeof(int32_t)); - } - - printf("Client %s:%d is connected (DL_RB=%d) rt=%d|%d. \n" , dev->eth_dev.openair0_cfg->remote_addr, - dev->eth_dev.openair0_cfg->remote_port, - dev->eth_dev.openair0_cfg->num_rb_dl, - dev->eth_dev.openair0_cfg->rx_num_channels, - dev->eth_dev.openair0_cfg->tx_num_channels); - - if (cmd==START_CMD) { - - pthread_attr_init(&attr_UE_rx); - pthread_attr_init(&attr_UE_tx); - sched_param_UE_rx.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_param_UE_tx.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_UE_rx,&sched_param_UE_rx); - pthread_attr_setschedparam(&attr_UE_tx,&sched_param_UE_tx); - pthread_attr_setschedpolicy(&attr_UE_rx,SCHED_FIFO); - pthread_attr_setschedpolicy(&attr_UE_tx,SCHED_FIFO); - - error_code_UE_rx = pthread_create(&UE_rx_thread, &attr_UE_rx, rrh_UE_rx_thread, (void *)&dev); - error_code_UE_tx = pthread_create(&UE_tx_thread, &attr_UE_tx, rrh_UE_tx_thread, (void *)&dev); - - if (error_code_UE_rx) { - printf("Error while creating UE RX thread\n"); - exit(-1); - } - - if (error_code_UE_tx) { - printf("Error while creating UE TX thread\n"); - exit(-1); - } - - while (rrh_exit==0) - sleep(1); - } - } - - - rrh_UE_thread_status = 0; - pthread_exit(&rrh_UE_thread_status); - - return(0); -} - - -/*! \fn void *rrh_UE_rx_thread(void *arg) -* \brief this function -* \param[in] -* \param[out] -* \return -* \note -* @ingroup _oai -*/ -void *rrh_UE_rx_thread(void *arg) { - - rrh_module_t *dev = (rrh_module_t *)arg; - struct timespec time0,time1,time2; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_sent; - int antenna_index, nsamps; - int trace_cnt=0; - unsigned long long max_rx_time=0, min_rx_time=133333, total_rx_time=0, average_rx_time=133333, s_period=0, trial=0; - unsigned int samples_per_frame=0; - openair0_timestamp last_hw_counter=0; - - antenna_index = 0; - nsamps = dev->eth_dev.openair0_cfg->samples_per_packet; - samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; - - /* TODO: check if setting time0 has to be done here */ - clock_gettime(CLOCK_MONOTONIC,&time0); - - while (rrh_exit == 0) { - if (!UE_rx_started) { - UE_rx_started=1; //Set this flag to 1 to indicate that a UE started retrieving data - - if (RT_flag_UE==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_flag_UE==1) { - if (hw_counter > last_hw_counter+1) { - printf("L1"); - //goto end_copy_UE; - } else { - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - } - - clock_gettime(CLOCK_MONOTONIC,&time1); - - // send return - - if ((timestamp_UE_rx[antenna_index]%(samples_per_frame)+nsamps) > samples_per_frame) { // Wrap around if nsamps exceeds the buffer limit - if (((timestamp_eNB_tx[antenna_index]%(samples_per_frame)) < ((timestamp_UE_rx[antenna_index]+nsamps)%(samples_per_frame))) && (eNB_tx_started==1)) { - printf("UE underflow wraparound timestamp_UE_rx : %d, timestamp_eNB_tx : %d\n", - (int)(timestamp_UE_rx[antenna_index]%(samples_per_frame)), - (int)(timestamp_eNB_tx[antenna_index]%samples_per_frame)); - - if (NRT_flag_UE==1) { - while ((timestamp_eNB_tx[antenna_index]%samples_per_frame) < ((timestamp_UE_rx[antenna_index]+nsamps)%(samples_per_frame))) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - - rx_ue[antenna_index]=(void*)&rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(samples_per_frame)]; - if ((bytes_sent =dev->eth_dev.trx_write_func (dev, - timestamp_UE_rx[antenna_index], - rx_ue, - ( samples_per_frame- (timestamp_eNB_rx[antenna_index]%(samples_per_frame)) ), - antenna_index, - 0))<0) - perror("RRH UE : sendto for RX"); - - rx_ue[antenna_index]=(void*)&rx_buffer_UE[antenna_index][3]; - if ((bytes_sent =dev->eth_dev.trx_write_func (dev, - timestamp_UE_rx[antenna_index], - rx_ue, - (nsamps - samples_per_frame + (timestamp_eNB_rx[antenna_index]%(samples_per_frame))), - antenna_index, - 0))<0) - perror("RRH UE : sendto for RX"); - - } else { - if (((timestamp_UE_rx[antenna_index]%samples_per_frame)< timestamp_eNB_tx[antenna_index]%samples_per_frame) && - (((timestamp_UE_rx[antenna_index]+nsamps)%samples_per_frame) > (timestamp_eNB_tx[antenna_index]%samples_per_frame)) && - (eNB_tx_started==1) ) { - printf("UE underflow timestamp_UE_rx : %d, timestamp_eNB_tx : %d\n", - (int)(timestamp_UE_rx[antenna_index]%samples_per_frame), - (int)(timestamp_eNB_tx[antenna_index]%samples_per_frame)); - - if (NRT_flag_UE==1) { - while (((timestamp_UE_rx[antenna_index]+nsamps)%samples_per_frame) > (timestamp_eNB_tx[antenna_index]%samples_per_frame)) { - nanosleep(&time_req_1us,&time_rem_1us); - } - } - } - - rx_ue[antenna_index]=(void*)&rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(samples_per_frame)]; - if ((bytes_sent = dev->eth_dev.trx_write_func (dev, - timestamp_UE_rx[antenna_index], - rx_ue, - nsamps, - antenna_index, - 0))<0) - perror("RRH UE thread: sendto for RX"); - } - - timestamp_UE_rx[antenna_index]+=nsamps; - last_hw_counter=hw_counter; - - clock_gettime(CLOCK_MONOTONIC,&time2); - - if (trace_cnt++ > 10) { - total_rx_time = (unsigned int)(time2.tv_nsec - time0.tv_nsec); - - if (total_rx_time < 0) total_rx_time=1000000000-total_rx_time; - - if ((total_rx_time > 0) && (total_rx_time < 1000000000)) { - trial++; - - if (total_rx_time < min_rx_time) - min_rx_time = total_rx_time; - - if (total_rx_time > max_rx_time) - max_rx_time = total_rx_time; - - average_rx_time = (long long unsigned int)((average_rx_time*trial)+total_rx_time)/(trial+1); - } - - if (s_period++ == PRINTF_PERIOD) { - s_period=0; - printf("Average UE RX time : %llu\tMax RX time : %llu\tMin RX time : %llu\n",average_rx_time,max_rx_time,min_rx_time); - - } - - //printf("RX: t1 %llu (time from last send), t2 %llu (sendto of %lu bytes) total time : %llu\n",(long long unsigned int)(time1.tv_nsec - time0.tv_nsec), (long long unsigned int)(time2.tv_nsec - time1.tv_nsec), - // (nsamps<<2)+sizeof(openair0_timestamp),(long long unsigned int)(time2.tv_nsec - time0.tv_nsec)); - - } - - memcpy(&time0,&time2,sizeof(struct timespec)); - - } //while (UE_exit==0) - - return(0); - -} - - -/*! \fn void *rrh_UE_tx_thread(void *arg) -* \brief this function -* \param[in] -* \param[out] -* \return -* \note -* @ingroup _oai -*/ -void *rrh_UE_tx_thread(void *arg) { - - struct timespec time0a,time0,time1,time2; - struct timespec time_req_1us, time_rem_1us; - - - rrh_module_t *dev = (rrh_module_t *)arg; - ssize_t bytes_received; - int antenna_index, nsamps; - unsigned int samples_per_frame=0; - - antenna_index = 0; - nsamps = dev->eth_dev.openair0_cfg->samples_per_packet; - samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; - - - while (rrh_exit == 0) { - - clock_gettime(CLOCK_MONOTONIC,&time0a); - - bytes_received = dev->eth_dev.trx_read_func(dev, - ×tamp_UE_tx[antenna_index], - tx_ue, - nsamps, - antenna_index); - - clock_gettime(CLOCK_MONOTONIC,&time1); - - if (NRT_flag_UE==1) { - nrt_UE_counter[antenna_index]++; - } - printf(" first part size: %d second part size: %"PRId64" idx=%"PRId64"\n", - (int32_t)(((samples_per_frame)<<2)-((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2)), - (nsamps<<2)-((samples_per_frame)<<2)+((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2), - timestamp_UE_tx[antenna_index]%(samples_per_frame)); - if ((timestamp_UE_tx[antenna_index]%(samples_per_frame)+nsamps) > samples_per_frame) { // Wrap around if nsamps exceeds the buffer limit - memcpy(&tx_buffer_UE[antenna_index][timestamp_UE_tx[antenna_index]%(samples_per_frame)],(void*)(tx_ue[antenna_index]), - (samples_per_frame<<2)-((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2)); - - memcpy(&tx_buffer_UE[antenna_index][0], (void*)(tx_ue[antenna_index]+(samples_per_frame*4)-((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2)), - (nsamps<<2)-((samples_per_frame-(timestamp_UE_tx[antenna_index]%(samples_per_frame)))<<2)); - //printf("Received UE TX samples for antenna %d, nsamps %d (%d)\n",antenna_index,nsamps,(int)(bytes_received>>2)); - } else { - memcpy(&tx_buffer_UE[antenna_index][timestamp_UE_tx[antenna_index]%(samples_per_frame)], (void*)(tx_ue[antenna_index]),(nsamps<<2)); - } - - while (sync_UE_rx[antenna_index]==0) - nanosleep(&time_req_1us,&time_rem_1us); - - pthread_mutex_lock(&sync_UE_mutex[antenna_index]); - sync_UE_rx[antenna_index]++; - - if (!sync_UE_rx[antenna_index]) { - counter_UE_tx[antenna_index]=(counter_UE_tx[antenna_index]+nsamps)%samples_per_frame; - nsamps_UE[antenna_index]=nsamps; - } else { - printf("rrh_eNB_proc thread is busy, will exit\n"); - exit(-1); - } - - pthread_mutex_unlock(&sync_UE_mutex[antenna_index]); - - clock_gettime(CLOCK_MONOTONIC,&time2); - - memcpy(&time0,&time2,sizeof(struct timespec)); - - } - - return(0); - -} - - diff --git a/targets/RT/USER/condtest.c b/targets/RT/USER/condtest.c deleted file mode 100644 index b6f00e80b3..0000000000 --- a/targets/RT/USER/condtest.c +++ /dev/null @@ -1,173 +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 -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include - -#define PERIOD 100000000 -#define THRESHOLD 1 - -static SEM *mutex; -static CND *cond; - -static int thread0; -static int thread1; - -static int instance_cnt=-1; //0 means worker is busy, -1 means its free - -static void *fun0(void *arg) -{ - RT_TASK *task; - int done1=0, cnt1=0; - RTIME right_now; - int ret; - - task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); - mlockall(MCL_CURRENT | MCL_FUTURE); - - rt_make_hard_real_time(); - - while (cnt1 < THRESHOLD) { - rt_sem_wait(mutex); - rt_printk("fun0: Hello World %d, instance_cnt %d!\n",cnt1,instance_cnt); - - while (instance_cnt<0) { - ret = rt_cond_wait(cond, mutex); - - if (ret != 0) { - rt_printk("error in rt_cond_wait, code %d\n",ret); - - switch (ret) { - case RTE_PERM: - rt_printk("error RTE_PERM %d\n",ret); - break; - - case RTE_UNBLKD: - rt_printk("error RTE_UNBLKD %d\n",ret); - break; - - case RTE_OBJREM: - rt_printk("error RTE_OBJREM %d\n",ret); - break; - - default: - rt_printk("unknown error code %d\n",ret); - break; - } - - break; - } - } - - rt_sem_signal(mutex); - - // do some work here - cnt1++; - - rt_sem_wait(mutex); - instance_cnt--; - rt_sem_signal(mutex); - - } - - // makes task soft real time - rt_make_soft_real_time(); - - printf("Back to soft RT\n"); - // clean task - rt_task_delete(task); - printf("Task deleted. returning\n"); - return 0; -} - - -int main(void) -{ - RT_TASK *task; - RTIME now; - int cnt=0; - - // make main thread LXRT soft realtime - task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); - mlockall(MCL_CURRENT | MCL_FUTURE); - - // start realtime timer and scheduler - //rt_set_oneshot_mode(); - rt_set_periodic_mode(); - start_rt_timer(0); - - now = rt_get_time() + 10*PERIOD; - rt_task_make_periodic(task, now, PERIOD); - - printf("Init mutex and cond.\n"); - mutex = rt_sem_init(nam2num("MUTEX"), 1); - - if (mutex==0) - printf("Error init mutex\n"); - - cond = rt_cond_init(nam2num("CONDITION")); - - if (cond==0) - printf("Error init cond\n"); - - thread0 = rt_thread_create(fun0, NULL, 10000); - //thread1 = rt_thread_create(fun1, NULL, 20000); - - //rt_sleep(PERIOD); - - while (cnt < THRESHOLD) { - rt_task_wait_period(); - rt_printk("main: Hello World %d!\n",cnt); - rt_sem_wait(mutex); //now the mutex should have value 0 - - if (instance_cnt==0) { - rt_sem_signal(mutex); //now the mutex should have vaule 1 - rt_printk("worker thread busy!\n"); - } else { - instance_cnt++; - rt_cond_signal(cond); - rt_sem_signal(mutex); //now the mutex should have vaule 1 - rt_printk("signaling worker thread to start!\n"); - } - - cnt++; - } - - // wait for end of program - printf("TYPE TO TERMINATE\n"); - getchar(); - - // cleanup - stop_rt_timer(); - return 0; -} diff --git a/targets/RT/USER/eNB_transport_IQ.c b/targets/RT/USER/eNB_transport_IQ.c deleted file mode 100644 index b822a5ea75..0000000000 --- a/targets/RT/USER/eNB_transport_IQ.c +++ /dev/null @@ -1,744 +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 eNB_transport_IQ.c - * \brief eNB transport IQ samples - * \author Katerina Trilyraki, Navid Nikaein, Raymond Knopp - * \date 2015 - * \version 0.1 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning very experimental - */ -#include -#include -#include -#include -#include -#include -#include - -#include "common_lib.h" -#include "PHY/defs.h" -#include "rrh_gw.h" -#include "rrh_gw_externs.h" -#include "rt_wrapper.h" - -#define PRINTF_PERIOD 3750 -#define HEADER_SIZE ((sizeof(int32_t) + sizeof(openair0_timestamp))>>2) - -pthread_cond_t sync_eNB_cond[4]; -pthread_mutex_t sync_eNB_mutex[4]; -pthread_mutex_t sync_trx_mutex=PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t sync_trx_cond=PTHREAD_COND_INITIALIZER; - -openair0_timestamp nrt_eNB_counter[4]= {0,0,0,0}; -int32_t overflow_rx_buffer_eNB[4]= {0,0,0,0}; -int32_t nsamps_eNB[4]= {0,0,0,0}; -int32_t eNB_tx_started=0,eNB_rx_started=0; -int32_t counter_eNB_rx[4]= {0,0,0,0}; -int32_t counter_eNB_tx[4]= {0,0,0,0}; -uint8_t RT_flag_eNB,NRT_flag_eNB; -void *rrh_eNB_thread_status; -int sync_eNB_rx[4]= {-1,-1,-1,-1}; -unsigned int sync_trx=0; - -int32_t **tx_buffer_eNB; -int32_t **rx_buffer_eNB; -void **rx_eNB; //was fixed to 2 ant -void **tx_eNB; //was fixed to 2 ant - -openair0_timestamp timestamp_eNB_tx[4]= {0,0,0,0};// all antennas must have the same ts -openair0_timestamp timestamp_eNB_rx[4]= {0,0,0,0}; -openair0_timestamp timestamp_rx=0,timestamp_tx=0; - -unsigned int rx_pos=0, next_rx_pos=0; -unsigned int tx_pos=0, tx_pos_rf=0, prev_tx_pos=0; -unsigned int rt_period=0; - -struct itimerspec timerspec; -pthread_mutex_t timer_mutex; - - - -/*! \fn void *rrh_eNB_rx_thread(void *arg) - * \brief this function - * \param[in] - * \return none - * \note - * @ingroup _oai - */ -void *rrh_eNB_rx_thread(void *); -/*! \fn void *rrh_eNB_tx_thread(void *arg) - * \brief this function - * \param[in] - * \return none - * \note - * @ingroup _oai - */ -void *rrh_eNB_tx_thread(void *); -/*! \fn void *rrh_eNB_thread(void *arg) - * \brief this function - * \param[in] - * \return none - * \note - * @ingroup _oai - */ -void *rrh_eNB_thread(void *); -/*! \fn void check_dev_config( rrh_module_t *mod_enb) - * \brief this function - * \param[in] *mod_enb - * \return none - * \note - * @ingroup _oai - */ -static void check_dev_config( rrh_module_t *mod_enb); -/*! \fn void calc_rt_period_ns( openair0_config_t openair0_cfg) - * \brief this function - * \param[in] openair0_cfg - * \return none - * \note - * @ingroup _oai - */ -static void calc_rt_period_ns( openair0_config_t *openair0_cfg); - - - -void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) { - - int error_code_eNB; - pthread_t main_rrh_eNB_thread; - pthread_attr_t attr; - struct sched_param sched_param_rrh; - - RT_flag_eNB=RT_flag; - NRT_flag_eNB=NRT_flag; - - /* init socket and have handshake-like msg with client to exchange parameters */ - mod_enb->eth_dev.trx_start_func(&mod_enb->eth_dev);//change port make it plus_id - - mod_enb->devs->openair0_cfg = mod_enb->eth_dev.openair0_cfg; - - /* check sanity of configuration parameters and print */ - check_dev_config(mod_enb); - if (rf_config_file[0] == '\0') - mod_enb->devs->openair0_cfg->configFilename = NULL; - else - mod_enb->devs->openair0_cfg->configFilename = rf_config_file; - /* initialize and configure the RF device */ - if (openair0_device_load(mod_enb->devs, mod_enb->devs->openair0_cfg)<0) { - LOG_E(RRH,"Exiting, cannot initialize RF device.\n"); - exit(-1); - } else { - if (mod_enb->devs->type != NONE_DEV) { - /* start RF device */ - if (mod_enb->devs->type == EXMIMO_DEV) { - //call start function for exmino - } else { - - if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0) - LOG_E(RRH,"Unable to initiate RF device.\n"); - else - LOG_I(RRH,"RF device has been initiated.\n"); - } - - } - } - - /* create main eNB module thread - main_rrh_eNB_thread allocates memory - for TX/RX buffers and creates TX/RX - threads for every eNB module */ - pthread_attr_init(&attr); - sched_param_rrh.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr,&sched_param_rrh); - pthread_attr_setschedpolicy(&attr,SCHED_FIFO); - error_code_eNB = pthread_create(&main_rrh_eNB_thread, &attr, rrh_eNB_thread, (void *)mod_enb); - - if (error_code_eNB) { - LOG_E(RRH,"Error while creating eNB thread\n"); - exit(-1); - } - -} - - -void *rrh_eNB_thread(void *arg) { - - rrh_module_t *dev=(rrh_module_t *)arg; - pthread_t eNB_rx_thread, eNB_tx_thread; - int error_code_eNB_rx, error_code_eNB_tx; - int32_t i,j; - void *tmp; - unsigned int samples_per_frame=0; - - samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; - - while (rrh_exit==0) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX, 1 ); - - /* calculate packet period */ - calc_rt_period_ns(dev->eth_dev.openair0_cfg); - - /* allocate memory for TX/RX buffers - each antenna port has a TX and a RX buffer - each TX and RX buffer is of (samples_per_frame + HEADER_SIZE) samples (size of samples is 4 bytes) */ - rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*)); - tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*)); - LOG_D(RRH,"rx_buffer_eNB address =%p tx_buffer_eNB address =%p \n",rx_buffer_eNB,tx_buffer_eNB); - - /* rx_buffer_eNB points to the beginning of data */ - for (i=0; ieth_dev.openair0_cfg->rx_num_channels; i++) { - tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32)); - memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32)); - rx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) ); - LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p\n",i,rx_buffer_eNB[i],tmp); - } - /* tx_buffer_eNB points to the beginning of data */ - for (i=0; ieth_dev.openair0_cfg->tx_num_channels; i++) { - tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32)); - memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32)); - tx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) ); - LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p \n",i,tx_buffer_eNB[i],tmp); - } - /* dummy initialization for TX/RX buffers */ - for (i=0; ieth_dev.openair0_cfg->rx_num_channels; i++) { - for (j=0; jeth_dev.openair0_cfg->tx_num_channels; i++) { - for (j=0; jeth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*)); - tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*)); - - /* init mutexes */ - for (i=0; ieth_dev.openair0_cfg->tx_num_channels; i++) { - pthread_mutex_init(&sync_eNB_mutex[i],NULL); - pthread_cond_init(&sync_eNB_cond[i],NULL); - } - /* init mutexes */ - pthread_mutex_init(&sync_trx_mutex,NULL); - - /* create eNB module's TX/RX threads */ -#ifdef DEADLINE_SCHEDULER - error_code_eNB_rx = pthread_create(&eNB_rx_thread, NULL, rrh_eNB_rx_thread, (void *)dev); - error_code_eNB_tx = pthread_create(&eNB_tx_thread, NULL, rrh_eNB_tx_thread, (void *)dev); - LOG_I(RRH,"[eNB][SCHED] deadline scheduling applied to eNB TX/RX threads\n"); -#else - pthread_attr_t attr_eNB_rx, attr_eNB_tx; - struct sched_param sched_param_eNB_rx, sched_param_eNB_tx; - - pthread_attr_init(&attr_eNB_rx); - pthread_attr_init(&attr_eNB_tx); - sched_param_eNB_rx.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_param_eNB_tx.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_eNB_rx,&sched_param_eNB_rx); - pthread_attr_setschedparam(&attr_eNB_tx,&sched_param_eNB_tx); - pthread_attr_setschedpolicy(&attr_eNB_rx,SCHED_FIFO); - pthread_attr_setschedpolicy(&attr_eNB_tx,SCHED_FIFO); - - error_code_eNB_rx = pthread_create(&eNB_rx_thread, &attr_eNB_rx, rrh_eNB_rx_thread, (void *)dev); - error_code_eNB_tx = pthread_create(&eNB_tx_thread, &attr_eNB_tx, rrh_eNB_tx_thread, (void *)dev); - LOG_I(RRH,"[eNB][SCHED] FIFO scheduling applied to eNB TX/RX threads\n"); -#endif - - if (error_code_eNB_rx) { - LOG_E(RRH,"[eNB] Error while creating eNB RX thread\n"); - exit(-1); - } - if (error_code_eNB_tx) { - LOG_E(RRH,"[eNB] Error while creating eNB TX thread\n"); - exit(-1); - } - - /* create timer thread; when no RF device is present a software clock is generated */ - if (dev->devs->type == NONE_DEV) { - - int error_code_timer; - pthread_t main_timer_proc_thread; - - LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period); - - /* setup the timer to generate an interrupt: - -for the first time in (sample_per_packet/sample_rate) ns - -and then every (sample_per_packet/sample_rate) ns */ - timerspec.it_value.tv_sec = rt_period/1000000000; - timerspec.it_value.tv_nsec = rt_period%1000000000; - timerspec.it_interval.tv_sec = rt_period/1000000000; - timerspec.it_interval.tv_nsec = rt_period%1000000000; - - -#ifdef DEADLINE_SCHEDULER - error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec); - LOG_I(RRH,"[eNB][SCHED] deadline scheduling applied to timer thread \n"); -#else - pthread_attr_t attr_timer; - struct sched_param sched_param_timer; - - pthread_attr_init(&attr_timer); - sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO-1); - pthread_attr_setschedparam(&attr_timer,&sched_param_timer); - pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO-1); - - pthread_mutex_init(&timer_mutex,NULL); - - error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec); - LOG_I(RRH,"[eNB][SCHED] FIFO scheduling applied to timer thread \n"); -#endif - - if (error_code_timer) { - LOG_E(RRH,"Error while creating timer proc thread\n"); - exit(-1); - } - - } - - while (rrh_exit==0) - sleep(1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,0 ); - } - - rrh_eNB_thread_status = 0; - pthread_exit(&rrh_eNB_thread_status); - return(0); -} - -/* Receive from RF and transmit to RRH */ - -void *rrh_eNB_rx_thread(void *arg) { - - /* measurement related vars */ - struct timespec time0,time1,time2; - unsigned long long max_rx_time=0, min_rx_time=rt_period, total_rx_time=0, average_rx_time=rt_period, s_period=0, trial=0; - int trace_cnt=0; - - struct timespec time_req_1us, time_rem_1us; - rrh_module_t *dev = (rrh_module_t *)arg; - ssize_t bytes_sent; - int i=0 ,pck_rx=0, s_cnt=0; - openair0_timestamp last_hw_counter=0; //volatile int64_t - unsigned int samples_per_frame=0,samples_per_subframe=0, spp_rf=0, spp_eth=0; - uint8_t loopback=0,measurements=0; - unsigned int subframe=0; - unsigned int frame=0; - - time_req_1us.tv_sec = 0; - time_req_1us.tv_nsec =1000; //time_req_1us.tv_nsec = (int)rt_period/2;--->granularity issue - spp_eth = dev->eth_dev.openair0_cfg->samples_per_packet; - spp_rf = dev->devs->openair0_cfg->samples_per_packet; - - samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; - samples_per_subframe = (unsigned int)samples_per_frame/10; - loopback = dev->loopback; - measurements = dev->measurements; - next_rx_pos = spp_eth; - -#ifdef DEADLINE_SCHEDULER - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = (0.8 * 100) * 10000;//4 * 10000; - attr.sched_deadline = (0.9 * 100) * 10000;//rt_period-2000; - attr.sched_period = 1 * 1000000;//rt_period; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] eNB RX thread: sched_setattr failed (run with sudo)\n"); - exit(-1); - } -#endif - - while (rrh_exit == 0) { - while (rx_pos <(1 + subframe)*samples_per_subframe) { - //LOG_D(RRH,"starting a new send:%d %d\n",sync_trx,frame); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX, frame); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX, subframe ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, pck_rx ); - LOG_D(RRH,"pack=%d rx_pos=%d subframe=%d frame=%d\n ",pck_rx, rx_pos, subframe,frame); - - if (dev->devs->type == NONE_DEV) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt ); - if (!eNB_rx_started) { - eNB_rx_started=1; // set this flag to 1 to indicate that eNB started - if (RT_flag_eNB==1) { - last_hw_counter=hw_counter;//get current counter - } - } else { - if (RT_flag_eNB==1) { - if (hw_counter > last_hw_counter+1) { - printf("LR"); - } else { - while ((hw_counter < last_hw_counter+1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP, 1 ); - nanosleep(&time_req_1us,&time_rem_1us); //rt_sleep_ns(sleep_ns); - s_cnt++; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP, 0 ); - } - } - } - } - } - - - if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1); - - if (loopback == 1 ) { - if (sync_eNB_rx[i]==0) { - rx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos]; - LOG_I(RRH,"tx_buffer_eNB[i][tx_pos]=%d ,tx_pos=%d\n",tx_buffer_eNB[i][tx_pos],tx_pos); - } else { - rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos]; - LOG_I(RRH,"rx_buffer_eNB[i][rx_pos]=%d ,rx_pos=%d\n",rx_buffer_eNB[i][rx_pos],rx_pos); - } - } - - for (i=0; ieth_dev.openair0_cfg->rx_num_channels; i++) { - rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos]; - LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_rx); - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos ); - if (dev->devs->type != NONE_DEV) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 ); - /* Read operation to RF device (RX)*/ - if ( dev->devs->trx_read_func (dev->devs, - ×tamp_rx, - rx_eNB, - spp_rf, - dev->devs->openair0_cfg->rx_num_channels - )<0) { - perror("RRH eNB : USRP read"); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 0 ); - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_TS, timestamp_rx&0xffffffff ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - if ((bytes_sent = dev->eth_dev.trx_write_func (&dev->eth_dev, - timestamp_rx, - rx_eNB, - spp_eth, - dev->eth_dev.openair0_cfg->rx_num_channels, - 0))<0) { - perror("RRH eNB : ETHERNET write"); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - /* when there is no RF timestamp is updated by number of samples */ - if (dev->devs->type == NONE_DEV) { - timestamp_rx+=spp_eth; - last_hw_counter=hw_counter; - } - - if (measurements == 1 ) { - - clock_gettime(CLOCK_MONOTONIC,&time2); - - if (trace_cnt++ > 10) { - total_rx_time = (unsigned int)(time2.tv_nsec - time0.tv_nsec); - if (total_rx_time < 0) - total_rx_time=1000000000-total_rx_time; - - if ((total_rx_time > 0) && (total_rx_time < 1000000000)) { - trial++; - if (total_rx_time < min_rx_time) - min_rx_time = total_rx_time; - if (total_rx_time > max_rx_time){ - max_rx_time = total_rx_time; - LOG_I(RRH,"Max value %d update at rx_position %d \n",total_rx_time,timestamp_rx); - } - average_rx_time = (long long unsigned int)((average_rx_time*trial)+total_rx_time)/(trial+1); - } - if (s_period++ == PRINTF_PERIOD) { - s_period=0; - LOG_I(RRH,"Average eNB RX time : %lu ns\tMax RX time : %lu ns\tMin RXX time : %lu ns\n",average_rx_time,max_rx_time,min_rx_time); - } - } - - memcpy(&time0,&time2,sizeof(struct timespec)); - } - - if (loopback == 1 ) { - pthread_mutex_lock(&sync_eNB_mutex[i]); - sync_eNB_rx[i]--; - pthread_mutex_unlock(&sync_eNB_mutex[i]); - } - - rx_pos += spp_eth; - pck_rx++; - next_rx_pos=(rx_pos+spp_eth); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 ); - /* - if (frame>50) { - pthread_mutex_lock(&sync_trx_mutex); - while (sync_trx) { - pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex); - } - sync_trx=1; - LOG_D(RRH,"out of while send:%d %d\n",sync_trx,frame); - pthread_cond_signal(&sync_trx_cond); - pthread_mutex_unlock(&sync_trx_mutex); - }*/ - } // while - - subframe++; - s_cnt=0; - - /* wrap around rx buffer index */ - if (next_rx_pos >= samples_per_frame) - next_rx_pos -= samples_per_frame; - if (rx_pos >= samples_per_frame) - rx_pos -= samples_per_frame; - /* wrap around subframe number */ - if (subframe == 10 ) { - subframe = 0; - frame++; - } - - - } //while (eNB_exit==0) - return 0; -} - -/* Receive from eNB and transmit to RF */ - -void *rrh_eNB_tx_thread(void *arg) { - - struct timespec time0,time1,time2; - - rrh_module_t *dev = (rrh_module_t *)arg; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_received; - int i; - //openair0_timestamp last_hw_counter=0; - unsigned int samples_per_frame=0,samples_per_subframe=0; - unsigned int spp_rf=0, spp_eth=0; - uint8_t loopback=0,measurements=0; - unsigned int subframe=0,frame=0; - unsigned int pck_tx=0; - -#ifdef DEADLINE_SCHEDULER - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = (0.8 * 100) * 10000; - attr.sched_deadline = (0.9 * 100) * 10000; - attr.sched_period = 1 * 1000000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] eNB TX thread: sched_setattr failed\n"); - exit(-1); - } -#endif - - time_req_1us.tv_sec = 1; - time_req_1us.tv_nsec = 0; - spp_eth = dev->eth_dev.openair0_cfg->samples_per_packet; - spp_rf = dev->devs->openair0_cfg->samples_per_packet; - samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; - samples_per_subframe = (unsigned int)samples_per_frame/10; - tx_pos=0; - - loopback = dev->loopback; - measurements = dev->measurements; - - while (rrh_exit == 0) { - while (tx_pos < (1 + subframe)*samples_per_subframe) { - - //LOG_D(RRH,"bef lock read:%d %d\n",sync_trx,frame); - //pthread_mutex_lock(&sync_trx_mutex); - - //while (!sync_trx) { - //LOG_D(RRH,"in sync read:%d %d\n",sync_trx,frame); - //pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex); - //} - //LOG_D(RRH,"out of while read:%d %d\n",sync_trx,frame); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, subframe ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx ); - - if (measurements == 1 ) clock_gettime(CLOCK_MONOTONIC,&time1); - for (i=0; ieth_dev.openair0_cfg->tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos]; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - - /* Read operation to ETHERNET device */ - if (( bytes_received = dev->eth_dev.trx_read_func(&dev->eth_dev, - ×tamp_tx, - tx_eNB, - spp_eth, - dev->eth_dev.openair0_cfg->tx_num_channels))<0) { - perror("RRH eNB : ETHERNET read"); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - if (dev->devs->type != NONE_DEV) { - LOG_D(RRH," tx_buffer_eNB[i][tx_pos]=%x t_buffer_eNB[i][tx_pos+1]=%x t_buffer_eNB[i][tx_pos+2]=%x \n",tx_buffer_eNB[0][tx_pos],tx_buffer_eNB[0][tx_pos+1],tx_buffer_eNB[0][tx_pos+2]); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 ); - /* Write operation to RF device (TX)*/ - if ( dev->devs->trx_write_func (dev->devs, - timestamp_tx, - tx_eNB, - spp_rf, - dev->devs->openair0_cfg->tx_num_channels, - 1)<0){ - perror("RRH eNB : USRP write"); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 0 ); - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff ); - - - //if (dev->devs->type == NONE_DEV) last_hw_counter=hw_counter; - - - if (loopback ==1 ) { - while (sync_eNB_rx[i]==0) - nanosleep(&time_req_1us,&time_rem_1us); - - pthread_mutex_lock(&sync_eNB_mutex[i]); - sync_eNB_rx[i]++; - pthread_mutex_unlock(&sync_eNB_mutex[i]); - } - - if (measurements == 1 ) { - clock_gettime(CLOCK_MONOTONIC,&time2); - memcpy(&time0,&time2,sizeof(struct timespec)); - } - - prev_tx_pos=tx_pos; - tx_pos += spp_eth; - pck_tx++; - - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 ); - //sync_trx=0; - //pthread_cond_signal(&sync_trx_cond); - //pthread_mutex_unlock(&sync_trx_mutex); - } - - /* wrap around tx buffer index */ - if (tx_pos >= samples_per_frame) - tx_pos -= samples_per_frame; - /* wrap around subframe number */ - subframe++; - if (subframe == 10 ) { - subframe = 0; // the radio frame is complete, start over - frame++; - } - - } //while (eNB_exit==0) - return 0; -} - - -static void calc_rt_period_ns( openair0_config_t *openair0_cfg) { - - rt_period= (double)(openair0_cfg->samples_per_packet/(openair0_cfg->samples_per_frame/10.0)*1000000); - AssertFatal(rt_period > 0, "Invalid rt period !%u\n", rt_period); - LOG_I(RRH,"[eNB] Real time period is set to %u ns\n", rt_period); -} - - -static void check_dev_config( rrh_module_t *mod_enb) { - - AssertFatal( (mod_enb->devs->openair0_cfg->num_rb_dl==100 || mod_enb->devs->openair0_cfg->num_rb_dl==50 || mod_enb->devs->openair0_cfg->num_rb_dl==25 || mod_enb->devs->openair0_cfg->num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg->num_rb_dl); - AssertFatal( mod_enb->devs->openair0_cfg->samples_per_frame > 0 , "Invalid number of samples per frame! %d\n",mod_enb->devs->openair0_cfg->samples_per_frame); - AssertFatal( mod_enb->devs->openair0_cfg->sample_rate > 0.0, "Invalid sample rate! %f\n", mod_enb->devs->openair0_cfg->sample_rate); - AssertFatal( mod_enb->devs->openair0_cfg->samples_per_packet > 0 , "Invalid number of samples per packet! %d\n",mod_enb->devs->openair0_cfg->samples_per_packet); - AssertFatal( mod_enb->devs->openair0_cfg->rx_num_channels > 0 , "Invalid number of RX antennas! %d\n", mod_enb->devs->openair0_cfg->rx_num_channels); - AssertFatal( mod_enb->devs->openair0_cfg->tx_num_channels > 0 , "Invalid number of TX antennas! %d\n", mod_enb->devs->openair0_cfg->tx_num_channels); - AssertFatal( mod_enb->devs->openair0_cfg->rx_freq[0] > 0.0 ,"Invalid RX frequency! %f\n", mod_enb->devs->openair0_cfg->rx_freq[0]); - AssertFatal( mod_enb->devs->openair0_cfg->tx_freq[0] > 0.0 ,"Invalid TX frequency! %f\n", mod_enb->devs->openair0_cfg->tx_freq[0]); - AssertFatal( mod_enb->devs->openair0_cfg->rx_gain[0] > 0.0 ,"Invalid RX gain! %f\n", mod_enb->devs->openair0_cfg->rx_gain[0]); - AssertFatal( mod_enb->devs->openair0_cfg->tx_gain[0] > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg->tx_gain[0]); - AssertFatal( mod_enb->devs->openair0_cfg->rx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->rx_bw); - AssertFatal( mod_enb->devs->openair0_cfg->tx_bw > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->tx_bw); - AssertFatal( mod_enb->devs->openair0_cfg->autocal[0] > 0 , "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg->autocal[0]); - - printf("\n---------------------RF device configuration parameters---------------------\n"); - - printf("\tMod_id=%d\n \tlog level=%d\n \tDL_RB=%d\n \tsamples_per_frame=%d\n \tsample_rate=%f\n \tsamples_per_packet=%d\n \ttx_sample_advance=%d\n \trx_num_channels=%d\n \ttx_num_channels=%d\n \trx_freq_0=%f\n \ttx_freq_0=%f\n \trx_freq_1=%f\n \ttx_freq_1=%f\n \trx_freq_2=%f\n \ttx_freq_2=%f\n \trx_freq_3=%f\n \ttx_freq_3=%f\n \trxg_mode=%d\n \trx_gain_0=%f\n \ttx_gain_0=%f\n \trx_gain_1=%f\n \ttx_gain_1=%f\n \trx_gain_2=%f\n \ttx_gain_2=%f\n \trx_gain_3=%f\n \ttx_gain_3=%f\n \trx_gain_offset_2=%f\n \ttx_gain_offset_3=%f\n \trx_bw=%f\n \ttx_bw=%f\n \tautocal=%d\n", - mod_enb->devs->openair0_cfg->Mod_id, - mod_enb->devs->openair0_cfg->log_level, - mod_enb->devs->openair0_cfg->num_rb_dl, - mod_enb->devs->openair0_cfg->samples_per_frame, - mod_enb->devs->openair0_cfg->sample_rate, - mod_enb->devs->openair0_cfg->samples_per_packet, - mod_enb->devs->openair0_cfg->tx_sample_advance, - mod_enb->devs->openair0_cfg->rx_num_channels, - mod_enb->devs->openair0_cfg->tx_num_channels, - mod_enb->devs->openair0_cfg->rx_freq[0], - mod_enb->devs->openair0_cfg->tx_freq[0], - mod_enb->devs->openair0_cfg->rx_freq[1], - mod_enb->devs->openair0_cfg->tx_freq[1], - mod_enb->devs->openair0_cfg->rx_freq[2], - mod_enb->devs->openair0_cfg->tx_freq[2], - mod_enb->devs->openair0_cfg->rx_freq[3], - mod_enb->devs->openair0_cfg->tx_freq[3], - mod_enb->devs->openair0_cfg->rxg_mode[0], - mod_enb->devs->openair0_cfg->tx_gain[0], - mod_enb->devs->openair0_cfg->tx_gain[0], - mod_enb->devs->openair0_cfg->rx_gain[1], - mod_enb->devs->openair0_cfg->tx_gain[1], - mod_enb->devs->openair0_cfg->rx_gain[2], - mod_enb->devs->openair0_cfg->tx_gain[2], - mod_enb->devs->openair0_cfg->rx_gain[3], - mod_enb->devs->openair0_cfg->tx_gain[3], - //mod_enb->devs->openair0_cfg->rx_gain_offset[0], - //mod_enb->devs->openair0_cfg->rx_gain_offset[1], - mod_enb->devs->openair0_cfg->rx_gain_offset[2], - mod_enb->devs->openair0_cfg->rx_gain_offset[3], - mod_enb->devs->openair0_cfg->rx_bw, - mod_enb->devs->openair0_cfg->tx_bw, - mod_enb->devs->openair0_cfg->autocal[0] - ); - - printf("----------------------------------------------------------------------------\n"); - - -} diff --git a/targets/RT/USER/emos-raw.c b/targets/RT/USER/emos-raw.c deleted file mode 100644 index 2cf0e18c71..0000000000 --- a/targets/RT/USER/emos-raw.c +++ /dev/null @@ -1,1603 +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 lte-softmodem.c -* \brief main program to control HW and scheduling -* \author R. Knopp, F. Kaltenberger -* \date 2012 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rt_wrapper.h" - -#include "PHY/types.h" -#include "PHY/TOOLS/defs.h" -#include "openair0_lib.h" - -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" - -#include "gain_control.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface_init.h" -# include "timer.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# endif -#endif - -#define OPENAIR_THREAD_PRIORITY 255 -#define OPENAIR_THREAD_STACK_SIZE 8192 - -#ifdef XFORMS -/* -#include "PHY/TOOLS/lte_phy_scope.h" -#include "stats.h" -// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) -// at eNB 0, an UL scope for every UE -FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; -FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX]; -FD_stats_form *form_stats=NULL; -char title[255]; -unsigned char scope_enb_num_ue = 1; -*/ -#include "lte_scope.h" -FD_lte_scope *form_lte; -char title[255]; -#endif //XFORMS - -#ifdef EMOS -#include -struct gps_fix_t dummy_gps_data; -#ifdef RTAI -#include -#endif - -//#define CHANSOUNDER_FIFO_SIZE 10485760 // 10 Mbytes FIFO -//#define CHANSOUNDER_FIFO_SIZE 20971520 // 20 Mbytes FIFO -#define CHANSOUNDER_FIFO_SIZE 52428800 // 50 Mbytes FIFO -//#define CHANSOUNDER_FIFO_SIZE 104857600 // 100 Mbytes FIFO -//#define CHANSOUNDER_FIFO_SIZE 1073741824 // 1Gbyte FIFO -#define CHANSOUNDER_FIFO_MINOR 4 // minor of the FIFO device - this is /dev/rtf3 -#define CHANSOUNDER_FIFO_DEV "/dev/rtf4" -#endif - -#define FRAME_PERIOD 100000000ULL -#define DAQ_PERIOD 66667ULL -#define LTE_SLOTS_PER_FRAME 20 -//#define RESAMPLING_FACTOR 0 -#define SAMPLES_PER_SLOT 15360 -#define FRAME_LENGTH_COMPLEX_SAMPLES (SAMPLES_PER_SLOT*LTE_SLOTS_PER_FRAME) -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#ifdef RTAI -static SEM *mutex; -//static CND *cond; - -static long int thread0; -//static long int thread1; -//static long int sync_thread; -#else -pthread_t thread0; -//pthread_t thread1; -pthread_attr_t attr_dlsch_threads; -struct sched_param sched_param_dlsch; -#endif - -pthread_t thread2; //xforms -pthread_t thread3; //emos -pthread_t thread4; //GPS -pthread_t thread5; //log - -/* -static int instance_cnt=-1; //0 means worker is busy, -1 means its free -int instance_cnt_ptr_kern,*instance_cnt_ptr_user; -int pci_interface_ptr_kern; -*/ -//extern unsigned int bigphys_top; -//extern unsigned int mem_base; - -int number_of_cards = 1; -exmimo_config_t *p_exmimo_config; -exmimo_id_t *p_exmimo_id; -volatile unsigned int *DAQ_MBOX; - -int oai_exit = 0; - -//int time_offset[4] = {-138,-138,-138,-138}; -//int time_offset[4] = {-145,-145,-145,-145}; -int time_offset[4] = {0,0,0,0}; - -int fs4_test=0; -char UE_flag=0; -uint8_t eNB_id=0,UE_id=0; - -// this array sets the bandwidth used for each card (and applies to all chains on one card). -exmimo_bw_t bandwidth[MAX_CARDS] = {BW5,BW5,BW5,BW5}; -// the array carrier_freq sets the frequency for each chain of each card. A 0 means that the chain is disabled. -// Please make sure that the total number of channels enabled per card is in accordance with the following rules: -// BW20: one channel, BW10: 2 channels, BW5: 4 channels -//uint32_t carrier_freq[MAX_CARDS][4] = {{2590000000,0,0,0},{2590000000,0,0,0},{2605000000,2605000000,0,0},{0,0,0,0}}; -//uint32_t carrier_freq[MAX_CARDS][4] = {{2590000000,0,0,0},{2605000000,2605000000,0,0},{0,0,0,0},{0,0,0,0}}; -uint32_t carrier_freq[MAX_CARDS][4] = {{771500000,771500000,771500000,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; - -// the following paramters set the aquisition time and period. These parameters have to be set in accordance with the write speed of your harddisk and the required throughput according to the setting above (see also channel_buffer_size which is computed later). -#define AQU_LENGTH_FRAMES 100 //Aquisition time in frames -#define AQU_PERIOD_FRAMES 100 //Repetition time of aquisition in frames -#define AQU_LENGTH_SLOTS (AQU_LENGTH_FRAMES*LTE_SLOTS_PER_FRAME) //Aquisition time in slots -#define AQU_PERIOD_SLOTS (AQU_PERIOD_FRAMES*LTE_SLOTS_PER_FRAME) //Repetition time of aquisition in slots - -int32_t rx_total_gain_dB[3] = {-112, -124, -136}; - -/* -// this array sets the bandwidth used for each card (and applies to all chains on one card). -exmimo_bw_t bandwidth[MAX_CARDS] = {BW20,BW20,BW10,BW5}; -// the array carrier_freq sets the frequency for each chain of each card. A 0 means that the chain is disabled. -// Please make sure that the total number of channels enabled per card is in accordance with the following rules: -// BW20: one channel, BW10: 2 channels, BW5: 4 channels -uint32_t carrier_freq[MAX_CARDS][4] = {{2590000000,0,0,0},{2590000000,0,0,0},{2605000000,2605000000,0,0},{0,0,0,0}}; -//uint32_t carrier_freq[MAX_CARDS][4] = {{2590000000,0,0,0},{2605000000,2605000000,0,0},{0,0,0,0},{0,0,0,0}}; -//uint32_t carrier_freq[MAX_CARDS][4] = {{2590000000,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; - -// the following paramters set the aquisition time and period. These parameters have to be set in accordance with the write speed of your harddisk and the required throughput according to the setting above (see also channel_buffer_size which is computed later). -#define AQU_LENGTH_FRAMES 100 //Aquisition time in frames -#define AQU_PERIOD_FRAMES 200 //Repetition time of aquisition in frames -#define AQU_LENGTH_SLOTS (AQU_LENGTH_FRAMES*LTE_SLOTS_PER_FRAME) //Aquisition time in slots -#define AQU_PERIOD_SLOTS (AQU_PERIOD_FRAMES*LTE_SLOTS_PER_FRAME) //Repetition time of aquisition in slots - -int32_t rx_total_gain_dB[3] = {-105, -110, -115}; -*/ - -char dumpfile_dir[256] = "/mnt/emos"; - -char *conf_config_file_name = NULL; - -unsigned int lost_bytes=0; -unsigned int rssi_lin[MAX_CARDS][4],rssi_lin_max[MAX_CARDS],rssi_lin_avg[MAX_CARDS]; -uint8_t rssi_avg_dB[MAX_CARDS]; -long long unsigned int total_bytes=0; - -struct timing_info_t { - //unsigned int frame, hw_slot, last_slot, next_slot; - RTIME time_min, time_max, time_avg, time_last, time_now; - //unsigned int mbox0, mbox1, mbox2, mbox_target; - unsigned int n_samples; -} timing_info; - -extern int16_t* sync_corr_ue0; -extern int16_t prach_ifft[4][1024*2]; - -unsigned int frame; -int rx_input_level_dBm; -#ifdef XFORMS -extern int otg_enabled; -#else -int otg_enabled; -#endif - -int mbox_bounds[20] = {8,16,24,30,38,46,54,60,68,76,84,90,98,106,114,120,128,136,144, 0}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers -//int mbox_bounds[20] = {6,14,22,28,36,44,52,58,66,74,82,88,96,104,112,118,126,134,142, 148}; ///boundaries of slots in terms ob mbox counter rounded up to even numbers - -//void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier); -//void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier); -void test_config(int card, int ant, unsigned int rf_mode, int UE_flag); - -unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) -{ - return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); -} -unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) -{ - return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); -} - -void signal_handler(int sig) -{ - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - oai_exit=1; - } -} - -void exit_fun(const char* s) -{ - void *array[10]; - size_t size; - - printf("Exiting: %s\n",s); - - oai_exit=1; - //rt_sleep_ns(FRAME_PERIOD); - - //exit (-1); -} - -#ifdef XFORMS -extern void ia_receiver_on_off( FL_OBJECT * form, long arg) {} - - -void *scope_thread(void *arg) -{ - int16_t prach_corr[1024]; - char stats_buffer[16384]; - //FILE *UE_stats, *eNB_stats; - int i,len=0; - float rxsig_t_dB[4][FRAME_LENGTH_COMPLEX_SAMPLES]; - float time[FRAME_LENGTH_COMPLEX_SAMPLES]; - struct sched_param sched_param; - int card,ant,idx; - - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; - sched_setscheduler(0, SCHED_FIFO,&sched_param); - - printf("Scope thread has priority %d\n",sched_param.sched_priority); - - /* - if (UE_flag==1) - UE_stats = fopen("UE_stats.txt", "w"); - else - eNB_stats = fopen("eNB_stats.txt", "w"); - */ - - while (!oai_exit) { - /* - if (UE_flag==1) { - len = dump_ue_stats (PHY_vars_UE_g[0], stats_buffer, 0, mode,rx_input_level_dBm); - fl_set_object_label(form_stats->stats_text, stats_buffer); - //rewind (UE_stats); - //fwrite (stats_buffer, 1, len, UE_stats); - - phy_scope_UE(form_ue[UE_id], - PHY_vars_UE_g[UE_id], - eNB_id, - UE_id,7); - - } else { - len = dump_eNB_stats (PHY_vars_eNB_g[0], stats_buffer, 0); - fl_set_object_label(form_stats->stats_text, stats_buffer); - //rewind (eNB_stats); - //fwrite (stats_buffer, 1, len, eNB_stats); - for(UE_id=0;UE_idframing.resampling_factor[ant]); - - for (i=0; ichannel_t_re[idx],time,rxsig_t_dB[0],len,"","",""); - fl_set_xyplot_data(form_lte->channel_t_im[idx],time,rxsig_t_dB[1],len,"","",""); - idx++; - } - } - } - - //printf("doing forms\n"); - usleep(100000); - } - - //fclose (UE_stats); - //fclose (eNB_stats); - - pthread_exit((void*)arg); -} -#endif - -int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); - - -#ifdef EMOS -void* gps_thread (void *arg) -{ - - struct gps_data_t gps_data; - struct gps_data_t *gps_data_ptr = &gps_data; - struct sched_param sched_param; - int ret; - - sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; - sched_setscheduler(0, SCHED_FIFO,&sched_param); - - printf("GPS thread has priority %d\n",sched_param.sched_priority); - - memset(&dummy_gps_data,0,sizeof(struct gps_fix_t)); - -#if GPSD_API_MAJOR_VERSION>=5 - ret = gps_open("127.0.0.1","2947",gps_data_ptr); - - if (ret!=0) -#else - gps_data_ptr = gps_open("127.0.0.1","2947"); - - if (gps_data_ptr == NULL) -#endif - { - printf("[EMOS] Could not open GPS\n"); - pthread_exit((void*)arg); - } - -#if GPSD_API_MAJOR_VERSION>=4 - else if (gps_stream(gps_data_ptr, WATCH_ENABLE,NULL) != 0) -#else - else if (gps_query(gps_data_ptr, "w+x") != 0) -#endif - { - printf("[EMOS] Error sending command to GPS\n"); - pthread_exit((void*) arg); - } else - printf("[EMOS] Opened GPS, gps_data=%p\n", gps_data_ptr); - - - while (!oai_exit) { - printf("[EMOS] polling data from gps\n"); -#if GPSD_API_MAJOR_VERSION>=5 - - if (gps_waiting(gps_data_ptr,500)) { - if (gps_read(gps_data_ptr) <= 0) { -#else - - if (gps_waiting(gps_data_ptr)) { - if (gps_poll(gps_data_ptr) != 0) { -#endif - printf("[EMOS] problem polling data from gps\n"); - } else { - memcpy(&dummy_gps_data,&(gps_data_ptr->fix),sizeof(struct gps_fix_t)); - printf("[EMOS] lat %g, lon %g\n",gps_data_ptr->fix.latitude,gps_data_ptr->fix.longitude); - } - } //gps_waiting - else { - printf("[EMOS] WARNING: No GPS data available, storing dummy packet\n"); - } - - //rt_sleep_ns(1000000000LL); - sleep(1); - } //oai_exit - - pthread_exit((void*) arg); - -} - -void *log_thread (void *arg) -{ - //struct tm now_sec; - struct timeval now; - int card; - FILE *logfile_id; - char logfile_name[1024]; - time_t starttime_tmp; - struct tm starttime; - - //open file - time(&starttime_tmp); - localtime_r(&starttime_tmp,&starttime); - snprintf(logfile_name,1024,"%s/%s_data_%d%02d%02d_%02d%02d%02d.log", - dumpfile_dir, - (UE_flag==0) ? "eNB" : "UE", - 1900+starttime.tm_year, starttime.tm_mon+1, starttime.tm_mday, starttime.tm_hour, starttime.tm_min, starttime.tm_sec); - logfile_id = fopen(logfile_name,"w"); - - if ((logfile_id == NULL)) { - fprintf(stderr, "[EMOS] Error opening logfile %s\n",logfile_name); - exit(EXIT_FAILURE); - } - - fprintf(logfile_id, - "#time, frame, total bytes wrote, total bytes lost, GPS time, GPS mode, lat, lon, alt, speed, rssi_lin_max[0], rssi_lin_avg[0], rssi_avg_dBm[0], rssi_avg_dB[0], rx_gain[0], LNA[0], ...\n"); - - while (!oai_exit) { - gettimeofday(&now,NULL); - //localtime_r(&(now.tv_sec),&now_sec); - fprintf(logfile_id,"%d.%06d, %d, %llu, %u, %e, %d, %e, %e, %e, %e, ", - (int) now.tv_sec, (int)now.tv_usec, - frame, total_bytes,lost_bytes, - dummy_gps_data.time, dummy_gps_data.mode, dummy_gps_data.latitude, dummy_gps_data.longitude, dummy_gps_data.altitude, dummy_gps_data.speed); - - for (card=0; cardrf.rf_mode[0] & LNAGAINMASK) >> 14)-1] - openair0_exmimo_pci[card].exmimo_config_ptr->rf.rx_gain[0][0], - rssi_avg_dB[card], openair0_exmimo_pci[card].exmimo_config_ptr->rf.rx_gain[0][0], (openair0_exmimo_pci[card].exmimo_config_ptr->rf.rf_mode[0] & LNAGAINMASK) >> 14); - - fprintf(logfile_id,"\n"); - usleep(10000); - } - - //close file - fclose(logfile_id); - - pthread_exit((void*) arg); - -} - -void *emos_thread (void *arg) -{ - char c; - char *fifo2file_buffer, *fifo2file_ptr; - - int fifo, counter=0, bytes; - - FILE *dumpfile_id; - char dumpfile_name[1024]; - time_t starttime_tmp; - struct tm starttime; - - //time_t timer; - struct tm now_sec; - struct timeval now; - - struct sched_param sched_param; - int ret; - - int card, ant; - int channel_buffer_size=0; //in bytes - - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); - - sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - sched_setscheduler(0, SCHED_FIFO,&sched_param); - - printf("EMOS thread has priority %d\n",sched_param.sched_priority); - - //timer = time(NULL); - //now = localtime(&timer); - - for (card=0; cardframing.resampling_factor[ant]); - } - - channel_buffer_size *= 4; //4 bytes per sample - - // allocate memory for NO_FRAMES_DISK channes estimations - fifo2file_buffer = malloc(AQU_LENGTH_SLOTS*channel_buffer_size); - fifo2file_ptr = fifo2file_buffer; - - if (fifo2file_buffer == NULL) { - printf("[EMOS] Cound not allocate memory for fifo2file_buffer\n"); - exit(EXIT_FAILURE); - } - - if ((fifo = open(CHANSOUNDER_FIFO_DEV, O_RDONLY)) < 0) { - fprintf(stderr, "[EMOS] Error opening the fifo\n"); - exit(EXIT_FAILURE); - } - - - time(&starttime_tmp); - localtime_r(&starttime_tmp,&starttime); - snprintf(dumpfile_name,1024,"%s/%s_data_%d%02d%02d_%02d%02d%02d.EMOS", - dumpfile_dir, - (UE_flag==0) ? "eNB" : "UE", - 1900+starttime.tm_year, starttime.tm_mon+1, starttime.tm_mday, starttime.tm_hour, starttime.tm_min, starttime.tm_sec); - - dumpfile_id = fopen(dumpfile_name,"w"); - - if ((dumpfile_id == NULL)) { - fprintf(stderr, "[EMOS] Error opening dumpfile %s\n",dumpfile_name); - exit(EXIT_FAILURE); - } - - printf("[EMOS] starting dump, channel_buffer_size=%d ...\n",channel_buffer_size); - - while (!oai_exit) { - //bytes = rtf_read_timed(fifo, fifo2file_ptr, channel_buffer_size,100); - bytes = rtf_read_all_at_once(fifo, fifo2file_ptr, channel_buffer_size); - - if (bytes<=0) { - usleep(100); - continue; - } - - if (bytes != channel_buffer_size) { - printf("[EMOS] Frame %d: ERROR! Only got %d bytes instead of %d!\n",frame,bytes,channel_buffer_size); - } - - /* - if (UE_flag==0) - printf("eNB: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_eNB*)fifo2file_ptr)->frame_tx,bytes); - else - printf("UE: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_UE*)fifo2file_ptr)->frame_rx,bytes); - */ - - fifo2file_ptr += channel_buffer_size; - counter ++; - total_bytes += bytes; - - if ((counter%AQU_LENGTH_SLOTS)==0) { - //reset stuff - fifo2file_ptr = fifo2file_buffer; - //counter = 0; - - printf("[EMOS] Frame %d: start writing %d bytes to disk\n",frame,AQU_LENGTH_SLOTS*channel_buffer_size); - - //flush buffer to disk - if (fwrite(fifo2file_buffer, sizeof(char), AQU_LENGTH_SLOTS*channel_buffer_size, dumpfile_id) != AQU_LENGTH_SLOTS*channel_buffer_size) { - fprintf(stderr, "[EMOS] Error writing to dumpfile\n"); - exit(EXIT_FAILURE); - } else - printf("[EMOS] Frame %d: wrote %d bytes to disk\n",frame,AQU_LENGTH_SLOTS*channel_buffer_size); - - } - - if ((counter%AQU_LENGTH_SLOTS)==0) { - //time(&starttime_tmp); - gettimeofday(&now,NULL); - localtime_r(&(now.tv_sec),&now_sec); - printf("[EMOS] %02d:%02d:%02d.%03d, frame %d, total bytes wrote %llu, bytes lost %u\n", - now_sec.tm_hour, now_sec.tm_min, now_sec.tm_sec, (int)(now.tv_usec/1000), frame, total_bytes,lost_bytes); - - for (card=0; cardrf.rf_mode[0] & LNAGAINMASK) >> 14)-1] - openair0_exmimo_pci[card].exmimo_config_ptr->rf.rx_gain[0][0], - rssi_avg_dB[card], openair0_exmimo_pci[card].exmimo_config_ptr->rf.rx_gain[0][0], (openair0_exmimo_pci[card].exmimo_config_ptr->rf.rf_mode[0] & LNAGAINMASK) >> 14); - - //printf("[EMOS] %02d:%02d:%02d, frame %d, GPS time %e, GPS mode %d, lat %e, lon %e, alt %e, speed %e\n", starttime.tm_hour, starttime.tm_min, starttime.tm_sec, counter/20, dummy_gps_data.time, dummy_gps_data.mode, dummy_gps_data.latitude, dummy_gps_data.longitude, dummy_gps_data.altitude, dummy_gps_data.speed); - } - } - - free(fifo2file_buffer); - fclose(dumpfile_id); - close(fifo); - - pthread_exit((void*) arg); - -} -#endif - -/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ -static void *eNB_thread(void *arg) -{ -#ifdef RTAI - RT_TASK *task; -#endif - unsigned char slot=0,last_slot, next_slot, hw_slot; - unsigned int msg1; - unsigned int aa,slot_offset, slot_offset_F; - int diff; - int delay_cnt; - RTIME time_in, time_diff; - int mbox_target=0,mbox_current=0; - int i,ret; - int tx_offset; - int bytes, bytes_tot=0, bytes_len; - long long int k1=1000; - long long int k2=1024-k1; - int ant,len,card = 0; - -#ifdef RTAI - task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); - LOG_D(HW,"Started eNB thread (id %p)\n",task); -#endif - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - timing_info.time_min = 100000000ULL; - timing_info.time_max = 0; - timing_info.time_avg = 0; - timing_info.n_samples = 0; - - while (!oai_exit) { - hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; - //LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]); - //this is the mbox counter where we should be - //mbox_target = ((((slot+1)%20)*15+1)>>1)%150; - mbox_target = mbox_bounds[slot]; - //this is the mbox counter where we are - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD) - if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround - diff = 150-mbox_current+mbox_target; - else if ((mbox_current<15) && (mbox_target>=135)) - diff = -150+mbox_target-mbox_current; - else - diff = mbox_target - mbox_current; - - if (diff < (-7)) { - // at the eNB, even slots have double as much time since most of the processing is done here and almost nothing in odd slots - LOG_D(HW,"eNB Frame %d, time %llu: missed slot, proceeding with next one (slot %d, hw_slot %d, diff %d)\n",frame, rt_get_time_ns(), slot, hw_slot, diff); - slot++; - - //if (frame>0) - //oai_exit=1; - if (slot==20) { - slot=0; - frame++; - } - - continue; - } - - if (diff>8) - LOG_D(HW,"eNB Frame %d, time %llu: skipped slot, waiting for hw to catch up (slot %d, hw_slot %d, mbox_current %d, mbox_target %d, diff %d)\n",frame, rt_get_time_ns(), slot, hw_slot, mbox_current, - mbox_target, diff); - - delay_cnt = 0; - - while ((diff>0) && (!oai_exit)) { - time_in = rt_get_time_ns(); - //LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in); - //LOG_D(HW,"eNB Frame %d, time %llu: sleeping for %llu (slot %d, hw_slot %d, diff %d, mbox %d, delay_cnt %d)\n", frame, time_in, diff*DAQ_PERIOD,slot,hw_slot,diff,((volatile unsigned int *)DAQ_MBOX)[0],delay_cnt); - ret = rt_sleep_ns(diff*DAQ_PERIOD); - - if (ret) - LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in); - - hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; - //LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns()); - delay_cnt++; - - if (delay_cnt == 10) { - oai_exit = 1; - LOG_D(HW,"eNB Frame %d: HW stopped ... \n",frame); - } - - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround - diff = 150-mbox_current+mbox_target; - else if ((mbox_current<15) && (mbox_target>=135)) - diff = -150+mbox_target-mbox_current; - else - diff = mbox_target - mbox_current; - } - - last_slot = (slot)%LTE_SLOTS_PER_FRAME; - - if (last_slot <0) - last_slot+=20; - - next_slot = (slot+3)%LTE_SLOTS_PER_FRAME; - - if (frame>=AQU_LENGTH_FRAMES) { - timing_info.time_last = timing_info.time_now; - timing_info.time_now = rt_get_time_ns(); - - if (timing_info.n_samples>0) { - time_diff = timing_info.time_now - timing_info.time_last; - - if (time_diff < timing_info.time_min) - timing_info.time_min = time_diff; - - if (time_diff > timing_info.time_max) - timing_info.time_max = time_diff; - - timing_info.time_avg += time_diff; - } - - timing_info.n_samples++; - - // do measurements for rssi - if (last_slot==0) { - for (card=0; cardframing.resampling_factor[0]); - rssi_lin_max[card] = 0; - - for (ant=0; ant<4; ant++) { - if (carrier_freq[card][ant] != 0) { - rssi_lin[card][ant] = signal_energy(&(((int32_t*) openair0_exmimo_pci[card].adc_head[ant])[last_slot*len]), len); - rssi_lin_max[card] = max(rssi_lin_max[card],rssi_lin[card][ant]); - } - } - - rssi_lin_avg[card] = (int) ((k1*((long long int)(rssi_lin_avg[card])) + (k2*((long long int)(rssi_lin_max[card]))))>>10); - rssi_avg_dB[card] = dB_fixed(rssi_lin_avg[card]); - - if (frame%100==0) { - gain_control_all(rssi_avg_dB[card],card); - //printf("AGC for card %d: rx_power_fil_dB=%d, rx_gain=%d, LNA=%d (1=Byp,2=Med,3=Max)\n",card,rssi_avg_dB,openair0_exmimo_pci[card].exmimo_config_ptr->rf.rx_gain[0][0],(openair0_exmimo_pci[card].exmimo_config_ptr->rf.rf_mode[0]&LNAGAINMASK)>>14); - } - } - } - -#ifdef EMOS - - // save raw samples here - if ((last_slot==0) && ((frame%AQU_PERIOD_FRAMES)==0)) { - printf("[EMOS] Frame %d: start writing to FIFO\n",frame); - bytes_tot=0; - } - - if ((frame%AQU_PERIOD_FRAMES)framing.resampling_factor[ant]); - bytes_len = len*4; - bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &(((int32_t*) openair0_exmimo_pci[card].adc_head[ant])[last_slot*len]), bytes_len); - bytes_tot += bytes; - - if (bytes!=bytes_len) { - lost_bytes += bytes_len - bytes; - LOG_W(PHY,"Frame %d, slot %d: Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n", - frame, last_slot, bytes, bytes_len); - } - } - } - } - - if ((last_slot==19) && ((frame%AQU_PERIOD_FRAMES)==99)) - printf("[EMOS] Frame %d: sent %d bytes to FIFO\n",frame,bytes_tot); - - } - -#endif - } - - slot++; - - if (slot==20) { - slot=0; - frame++; - } - -#if defined(ENABLE_ITTI) - itti_update_lte_time(frame, slot); -#endif - } - - LOG_D(HW,"eNB_thread: finished, ran %d times.\n",frame); - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - // clean task -#ifdef RTAI - rt_task_delete(task); -#endif - LOG_D(HW,"Task deleted. returning\n"); - return 0; -} - - -int main(int argc, char **argv) -{ - -#ifdef RTAI - RT_TASK *task; -#endif - int i,j,aa; - void *status; - int card = 0; - - uint32_t rf_mode_base = TXLPFNORM + TXLPFEN + RXLPFNORM + RXLPFEN + LNA1ON +LNAMax + RFBBNORM; - uint32_t rf_local[4] = {8255000,8255000,8255000,8255000}; // UE zepto - //{8254617, 8254617, 8254617, 8254617}; //eNB khalifa - //{8255067,8254810,8257340,8257340}; // eNB PETRONAS - uint32_t rf_vcocal[4] = {910,910,910,910}; - uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015}; - uint32_t rf_rxdc[4] = {32896,32896,32896,32896}; - uint32_t rxgain[4] = {30,30,30,30}; - uint32_t txgain[4] = {0,0,0,0}; - - uint16_t Nid_cell = 0; - uint8_t cooperation_flag=0, transmission_mode=1, abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - - int c; - char do_forms=0; - unsigned int fd; - unsigned int tcxo = 114; - - int amp; - uint8_t prach_fmt; - int N_ZC; - - char rxg_fname[100]; - char txg_fname[100]; - char rflo_fname[100]; - char rfdc_fname[100]; - FILE *rxg_fd=NULL; - FILE *txg_fd=NULL; - FILE *rflo_fd=NULL; - FILE *rfdc_fd=NULL; - unsigned int rxg_max[4]= {133,133,133,133}, rxg_med[4]= {127,127,127,127}, rxg_byp[4]= {120,120,120,120}; - int tx_max_power=0; - - char line[1000]; - int l; - int ret, ant; - int ant_offset=0; - - int error_code; - char *itti_dump_file = NULL; - - const struct option long_options[] = { - {"calib-ue-rx", required_argument, NULL, 256}, - {"calib-ue-rx-med", required_argument, NULL, 257}, - {"calib-ue-rx-byp", required_argument, NULL, 258}, - {"debug-ue-prach", no_argument, NULL, 259}, - {"no-L2-connect", no_argument, NULL, 260}, - {NULL, 0, NULL, 0} - }; - - //mode = normal_txrx; - - - while ((c = getopt_long (argc, argv, "C:K:O:ST:UdF:V",long_options,NULL)) != -1) { - switch (c) { - case 'V': - ouput_vcd = 1; - break; - - case 'd': - do_forms=1; - break; - - case 'U': - UE_flag = 1; - break; - - case 'C': - for (card=0; cardlog_component[HW].level = LOG_DEBUG; - g_log->log_component[HW].flag = LOG_HIGH; -#ifdef OPENAIR2 - g_log->log_component[PHY].level = LOG_INFO; -#else - g_log->log_component[PHY].level = LOG_DEBUG; -#endif - g_log->log_component[PHY].flag = LOG_HIGH; - g_log->log_component[MAC].level = LOG_INFO; - g_log->log_component[MAC].flag = LOG_HIGH; - g_log->log_component[RLC].level = LOG_INFO; - g_log->log_component[RLC].flag = LOG_HIGH; - g_log->log_component[PDCP].level = LOG_INFO; - g_log->log_component[PDCP].flag = LOG_HIGH; - g_log->log_component[OTG].level = LOG_INFO; - g_log->log_component[OTG].flag = LOG_HIGH; - g_log->log_component[RRC].level = LOG_INFO; - g_log->log_component[RRC].flag = LOG_HIGH; - - - // Initialize card - ret = openair0_open(); - - if ( ret != 0 ) { - if (ret == -1) - printf("Error opening /dev/openair0"); - - if (ret == -2) - printf("Error mapping bigshm"); - - if (ret == -3) - printf("Error mapping RX or TX buffer"); - - return(ret); - } - - number_of_cards = openair0_num_detected_cards; - - for (card=0; cardboard_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev); - - if (p_exmimo_id->board_swrev>=BOARD_SWREV_CNTL2) - p_exmimo_config->framing.eNB_flag = 0; - else - p_exmimo_config->framing.eNB_flag = !UE_flag; - - if (card==0) - p_exmimo_config->framing.multicard_syncmode = SYNCMODE_MASTER; - else - p_exmimo_config->framing.multicard_syncmode = SYNCMODE_SLAVE; - - //p_exmimo_config->framing.multicard_syncmode = SYNCMODE_FREE; - - - p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_TESTRX; //TXRXSWITCH_LSB; - - /* - for (ant=0;antnb_antennas_tx,frame_parms->nb_antennas_rx);ant++) - p_exmimo_config->rf.rf_mode[ant] = rf_mode_base; - for (ant=0;antnb_antennas_tx;ant++) - p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX); - for (ant=0;antnb_antennas_rx;ant++) - p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX); - for (ant=max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant<4;ant++) { - p_exmimo_config->rf.rf_mode[ant] = 0; - carrier_freq[ant] = 0; //this turns off all other LIMEs - } - */ - - for (ant=0; ant<4; ant++) { - if (carrier_freq[card][ant] != 0) { - p_exmimo_config->rf.rf_mode[ant] = rf_mode_base; - - switch (bandwidth[card]) { - case BW20: - p_exmimo_config->framing.resampling_factor[ant] = 0; - p_exmimo_config->rf.rf_mode[ant] += RXLPF10 + TXLPF10; - break; - - case BW10: - p_exmimo_config->framing.resampling_factor[ant] = 1; - p_exmimo_config->rf.rf_mode[ant] += RXLPF5 + TXLPF5; - break; - - case BW5: - p_exmimo_config->framing.resampling_factor[ant] = 2; - p_exmimo_config->rf.rf_mode[ant] += RXLPF25 + TXLPF25; - break; - } - - //p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX); - p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX); - } else { - p_exmimo_config->rf.rf_mode[ant] = 0; - } - } - - for (ant = 0; ant<4; ant++) { - p_exmimo_config->rf.do_autocal[ant] = 1; - p_exmimo_config->rf.rf_freq_rx[ant] = carrier_freq[card][ant]; - p_exmimo_config->rf.rf_freq_tx[ant] = carrier_freq[card][ant]; - p_exmimo_config->rf.rx_gain[ant][0] = rxgain[ant]; - p_exmimo_config->rf.tx_gain[ant][0] = txgain[ant]; - - p_exmimo_config->rf.rf_local[ant] = rf_local[ant]; - p_exmimo_config->rf.rf_rxdc[ant] = rf_rxdc[ant]; - - if ((carrier_freq[card][ant] >= 850000000) && (carrier_freq[card][ant] <= 865000000)) { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal_850[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = DD_TDD; - } else if ((carrier_freq[card][ant] >= 1900000000) && (carrier_freq[card][ant] <= 2000000000)) { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = B19G_TDD; - } else { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = 0; - } - - p_exmimo_config->rf.rffe_gain_txlow[ant] = 31; - p_exmimo_config->rf.rffe_gain_txhigh[ant] = 31; - p_exmimo_config->rf.rffe_gain_rxfinal[ant] = 52; - p_exmimo_config->rf.rffe_gain_rxlow[ant] = 31; - } - - - openair0_dump_config(card); - - printf("EXMIMO_CONFIG card %d: freq0..3 %u %u %u %u Hz, freqtx0..1 %u %u Hz, RX gain0..1 %d %d dB\n", - card, - p_exmimo_config->rf.rf_freq_rx[0], - p_exmimo_config->rf.rf_freq_rx[1], - p_exmimo_config->rf.rf_freq_rx[2], - p_exmimo_config->rf.rf_freq_rx[3], - p_exmimo_config->rf.rf_freq_tx[0], - p_exmimo_config->rf.rf_freq_tx[1], - p_exmimo_config->rf.rx_gain[0][0], - p_exmimo_config->rf.rx_gain[1][0]); - printf("EXMIMO_CONFIG card %d: rf_mode 0x %x %x %x %x, [0]: TXRXEn %d, TXLPFEn %d, TXLPF %d, RXLPFEn %d, RXLPF %d, RFBB %d, LNA %d, LNAGain %d, RXLPFMode %d, SWITCH %d, rf_rxdc %d, rf_local %d, rf_vcocal %d\n", - card, - p_exmimo_config->rf.rf_mode[0], - p_exmimo_config->rf.rf_mode[1], - p_exmimo_config->rf.rf_mode[2], - p_exmimo_config->rf.rf_mode[3], - (p_exmimo_config->rf.rf_mode[0]&3), // RXen+TXen - (p_exmimo_config->rf.rf_mode[0]&4)>>2, //TXLPFen - (p_exmimo_config->rf.rf_mode[0]&TXLPFMASK)>>3, //TXLPF - (p_exmimo_config->rf.rf_mode[0]&128)>>7, //RXLPFen - (p_exmimo_config->rf.rf_mode[0]&RXLPFMASK)>>8, //TXLPF - (p_exmimo_config->rf.rf_mode[0]&RFBBMASK)>>16, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&LNAMASK)>>12, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&LNAGAINMASK)>>14, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&RXLPFMODEMASK)>>19, // RXLPF mode - (p_exmimo_config->framing.tdd_config&TXRXSWITCH_MASK)>>1, // Switch mode - p_exmimo_config->rf.rf_rxdc[0], - p_exmimo_config->rf.rf_local[0], - p_exmimo_config->rf.rf_vcocal[0]); - - for (ant=0; ant<4; ant++) - p_exmimo_config->rf.do_autocal[ant] = 0; - } //card - - card=0; - -#ifdef EMOS - error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE); - - if (error_code==0) - printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR); - else if (error_code==ENODEV) - printf("[OPENAIR][SCHED][INIT] Problem: EMOS FIFO %d is greater than or equal to RTF_NO\n",CHANSOUNDER_FIFO_MINOR); - else if (error_code==ENOMEM) - printf("[OPENAIR][SCHED][INIT] Problem: cannot allocate memory for EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR); - else - printf("[OPENAIR][SCHED][INIT] Problem creating EMOS FIFO %d, error_code %d\n",CHANSOUNDER_FIFO_MINOR,error_code); - -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - -#ifdef RTAI - // make main thread LXRT soft realtime - task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); - - // start realtime timer and scheduler - //rt_set_oneshot_mode(); - rt_set_periodic_mode(); - start_rt_timer(0); - - //now = rt_get_time() + 10*PERIOD; - //rt_task_make_periodic(task, now, PERIOD); - - printf("Init mutex\n"); - //mutex = rt_get_adr(nam2num("MUTEX")); - mutex = rt_sem_init(nam2num("MUTEX"), 1); - - if (mutex==0) { - printf("Error init mutex\n"); - exit(-1); - } else - printf("mutex=%p\n",mutex); - -#endif - - DAQ_MBOX = (volatile unsigned int *) openair0_exmimo_pci[0].rxcnt_ptr[0]; - - // this starts the DMA transfers - if (UE_flag!=1) - for (card=0; cardlte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } else { - for(UE_id=0;UE_idlte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } - } - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - if (UE_flag==0) { - for (UE_id=0;UE_idbutton_0,1); - fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON"); - } - else { - fl_set_button(form_enb[UE_id]->button_0,0); - fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic OFF"); - } - } - } - else { - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } - else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } - } - */ - form_lte = create_form_lte_scope(); - fl_show_form (form_lte->lte_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "Scope"); - - ret = pthread_create(&thread2, NULL, scope_thread, NULL); - printf("Scope thread created, ret=%d\n",ret); - } - -#endif - -#ifdef EMOS - ret = pthread_create(&thread3, NULL, emos_thread, NULL); - printf("EMOS thread created, ret=%d\n",ret); - ret = pthread_create(&thread4, NULL, gps_thread, NULL); - printf("GPS thread created, ret=%d\n",ret); - ret = pthread_create(&thread5, NULL, log_thread, NULL); - printf("LOG thread created, ret=%d\n",ret); -#endif - - rt_sleep_ns(10*FRAME_PERIOD); - -#ifndef RTAI - pthread_attr_init (&attr_dlsch_threads); - pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE); - //attr_dlsch_threads.priority = 1; - sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_dlsch_threads, &sched_param_dlsch); - pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO); -#endif - - // start the main thread - if (UE_flag == 1) { - /* - #ifdef RTAI - thread1 = rt_thread_create(UE_thread, NULL, 100000000); - #else - error_code = pthread_create(&thread1, &attr_dlsch_threads, UE_thread, NULL); - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return(error_code); - } - else { - LOG_D(HW,"[lte-softmodem.c] Allocate UE_thread successful\n"); - } - #endif - #ifdef DLSCH_THREAD - init_rx_pdsch_thread(); - rt_sleep_ns(FRAME_PERIOD/10); - init_dlsch_threads(); - #endif - printf("UE threads created\n"); - */ - } else { -#ifdef RTAI - thread0 = rt_thread_create(eNB_thread, NULL, 100000000); -#else - error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code); - return(error_code); - } else { - LOG_D(HW,"[lte-softmodem.c] Allocate eNB_thread successful\n"); - } - -#endif -#ifdef ULSCH_THREAD - init_ulsch_threads(); -#endif - printf("eNB threads created\n"); - } - - - // wait for end of program - printf("TYPE TO TERMINATE\n"); - - //getchar(); - while (oai_exit==0) - rt_sleep_ns(FRAME_PERIOD); - - // stop threads -#ifdef XFORMS - printf("waiting for XFORMS thread\n"); - - if (do_forms==1) { - pthread_join(thread2,&status); - /* - fl_hide_form(form_stats->stats_form); - fl_free_form(form_stats->stats_form); - if (UE_flag==1) { - fl_hide_form(form_ue[UE_id]->lte_phy_scope_ue); - fl_free_form(form_ue[UE_id]->lte_phy_scope_ue); - } else { - for(UE_id=0;UE_idlte_phy_scope_enb); - fl_free_form(form_enb[UE_id]->lte_phy_scope_enb); - } - } - */ - fl_hide_form(form_lte->lte_scope); - fl_free_form(form_lte->lte_scope); - } - -#endif - - printf("stopping MODEM threads\n"); - - // cleanup - if (UE_flag == 1) { - /* - #ifdef RTAI - rt_thread_join(thread1); - #else - pthread_join(thread1,&status); - #endif - #ifdef DLSCH_THREAD - cleanup_dlsch_threads(); - cleanup_rx_pdsch_thread(); - #endif - */ - } else { -#ifdef RTAI - rt_thread_join(thread0); -#else - pthread_join(thread0,&status); -#endif -#ifdef ULSCH_THREAD - cleanup_ulsch_threads(); -#endif - } - -#ifdef OPENAIR2 - //cleanup_pdcp_thread(); -#endif - -#ifdef RTAI - stop_rt_timer(); -#endif - - printf("stopping card\n"); - - for (card=0; card0) - error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR); - - printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code); -#endif - - if (ouput_vcd) - VCD_SIGNAL_DUMPER_CLOSE(); - - logClean(); - - return 0; -} - -void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) -{ - p_exmimo_config->framing.eNB_flag = !UE_flag; - p_exmimo_config->framing.tdd_config = 0; - p_exmimo_config->framing.resampling_factor[ant] = 2; - - p_exmimo_config->rf.rf_freq_rx[ant] = 1907600000; - p_exmimo_config->rf.rf_freq_tx[ant] = 1907600000;; - p_exmimo_config->rf.rx_gain[ant][0] = 20; - p_exmimo_config->rf.tx_gain[ant][0] = 10; - p_exmimo_config->rf.rf_mode[ant] = rf_mode; - - p_exmimo_config->rf.rf_local[ant] = build_rflocal(20,25,26,04); - p_exmimo_config->rf.rf_rxdc[ant] = build_rfdc(128, 128); - p_exmimo_config->rf.rf_vcocal[ant] = (0xE<<6) + 0xE; -} - -/* -void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier) { - - int i; - if (phy_vars_ue) { - - if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) { - printf("RX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) { - printf("TX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - // replace RX signal buffers with mmaped HW versions - for (i=0;inb_antennas_rx;i++) { - free(phy_vars_ue->lte_ue_common_vars.rxdata[i]); - phy_vars_ue->lte_ue_common_vars.rxdata[i] = (int32_t*) openair0_exmimo_pci[card].adc_head[i+carrier]; - - - printf("rxdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.rxdata[i]); - } - for (i=0;inb_antennas_tx;i++) { - free(phy_vars_ue->lte_ue_common_vars.txdata[i]); - phy_vars_ue->lte_ue_common_vars.txdata[i] = (int32_t*) openair0_exmimo_pci[card].dac_head[i+carrier]; - - printf("txdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.txdata[i]); - } - } -} - -void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier) { - - int i,j; - - if (phy_vars_eNB) { - if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) { - printf("RX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) { - printf("TX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - // replace RX signal buffers with mmaped HW versions - for (i=0;inb_antennas_rx;i++) { - free(phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]); - phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i] = (int32_t*) openair0_exmimo_pci[card].adc_head[i+carrier]; - - printf("rxdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]); - for (j=0;j<16;j++) { - printf("rxbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j]); - phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j] = 16-j; - } - } - for (i=0;inb_antennas_tx;i++) { - free(phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]); - phy_vars_eNB->lte_eNB_common_vars.txdata[0][i] = (int32_t*) openair0_exmimo_pci[card].dac_head[i+carrier]; - - printf("txdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]); - for (j=0;j<16;j++) { - printf("txbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j]); - phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j] = 16-j; - } - } - } -} -*/ diff --git a/targets/RT/USER/init_rtai.sh b/targets/RT/USER/init_rtai.sh deleted file mode 100755 index 69b127de33..0000000000 --- a/targets/RT/USER/init_rtai.sh +++ /dev/null @@ -1,5 +0,0 @@ -sudo insmod /usr/realtime/modules/rtai_hal.ko -sudo insmod /usr/realtime/modules/rtai_sched.ko -sudo insmod /usr/realtime/modules/rtai_sem.ko -sudo insmod /usr/realtime/modules/rtai_fifos.ko -sudo insmod /usr/realtime/modules/rtai_mbx.ko diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index cd703a95e8..3f27e38726 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -122,11 +122,14 @@ extern int transmission_mode; extern int oaisim_flag; +uint16_t sf_ahead=4; + //pthread_t main_eNB_thread; time_stats_t softmodem_stats_mt; // main thread time_stats_t softmodem_stats_hw; // hw acquisition time_stats_t softmodem_stats_rxtx_sf; // total tx time +time_stats_t nfapi_meas; // total tx time time_stats_t softmodem_stats_rx_sf; // total rx time /* mutex, cond and variable to serialize phy proc TX calls @@ -152,17 +155,69 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif +extern uint8_t nfapi_mode; +extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); +extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); + +//#define TICK_TO_US(ts) (ts.diff) +#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) + + static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { + static double cpu_freq_GHz = 0.0; + + if (cpu_freq_GHz == 0.0) + cpu_freq_GHz = get_cpu_freq_GHz(); + + start_meas(&softmodem_stats_rxtx_sf); + // ******************************************************************* + + if (nfapi_mode == 1) { + + // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick + uint16_t frame = proc->frame_rx; + uint16_t subframe = proc->subframe_rx; + + //add_subframe(&frame, &subframe, 4); + + //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); + start_meas(&nfapi_meas); + oai_subframe_ind(frame, subframe); + stop_meas(&nfapi_meas); + + if (eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| + eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || + eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || + eNB->UL_INFO.cqi_ind.number_of_cqis + ) { + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", + NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, + NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, + NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, + eNB->UL_INFO.cqi_ind.number_of_cqis, + proc->frame_rx, proc->subframe_rx, + proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols); + } + } + + if (nfapi_mode == 1 && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) { + LOG_E(PHY, "eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0"); + return 0; + } + // **************************************** // Common RX procedures subframe n T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx)); // if this is IF5 or 3GPP_eNB - if (eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx); #ifdef Rel14 wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); @@ -172,24 +227,28 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam release_UE_in_freeList(eNB->Mod_id); // UE-specific RX processing for subframe n - phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); + if (nfapi_mode == 0 || nfapi_mode == 1) { + phy_procedures_eNB_uespec_RX(eNB, proc, no_relay ); + } pthread_mutex_lock(&eNB->UL_INFO_mutex); + eNB->UL_INFO.frame = proc->frame_rx; 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); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + // ***************************************** - // TX processing for subframe n+4 + // TX processing for subframe n+sf_ahead // run PHY TX procedures the one after the other for all CCs to avoid race conditions // (may be relaxed in the future for performance reasons) // ***************************************** //if (wait_CCs(proc)<0) return(-1); - - if (oai_exit) return(-1); #if (!defined(UE_EXPANSION_SIM2)) &&(!defined(UE_EXPANSION)) phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1); @@ -197,6 +256,50 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); stop_meas( &softmodem_stats_rxtx_sf ); + + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx); + +#if 0 + LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", + softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, + TICK_TO_US(eNB->phy_proc), + TICK_TO_US(eNB->phy_proc_tx), + TICK_TO_US(eNB->phy_proc_rx), + TICK_TO_US(eNB->rx_prach), + TICK_TO_US(eNB->ofdm_mod_stats), + softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now); + LOG_D(PHY, + "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", + TICK_TO_US(eNB->dlsch_encoding_stats), + TICK_TO_US(eNB->dlsch_modulation_stats), + TICK_TO_US(eNB->dlsch_scrambling_stats), + TICK_TO_US(eNB->dlsch_rate_matching_stats), + TICK_TO_US(eNB->dlsch_turbo_encoding_stats), + TICK_TO_US(eNB->dlsch_interleaving_stats), + TICK_TO_US(eNB->rx_dft_stats)); + + LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ", + TICK_TO_US(eNB->ulsch_channel_estimation_stats), + TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats), + TICK_TO_US(eNB->ulsch_decoding_stats), + TICK_TO_US(eNB->ulsch_demodulation_stats), + TICK_TO_US(eNB->ulsch_rate_unmatching_stats)); + + LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ", + TICK_TO_US(eNB->ulsch_turbo_decoding_stats), + TICK_TO_US(eNB->ulsch_deinterleaving_stats), + TICK_TO_US(eNB->ulsch_demultiplexing_stats), + TICK_TO_US(eNB->ulsch_llr_stats), + TICK_TO_US(eNB->ulsch_tc_init_stats)); + LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", + TICK_TO_US(eNB->ulsch_tc_alpha_stats), + TICK_TO_US(eNB->ulsch_tc_beta_stats), + TICK_TO_US(eNB->ulsch_tc_gamma_stats), + TICK_TO_US(eNB->ulsch_tc_ext_stats), + TICK_TO_US(eNB->ulsch_tc_intl1_stats), + TICK_TO_US(eNB->ulsch_tc_intl2_stats) + ); +#endif return(0); } @@ -222,7 +325,7 @@ static void* eNB_thread_rxtx( void* param ) { eNB_thread_rxtx_status = 0; - sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); + sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); thread_top_init(thread_name,1,850000L,1000000L,2000000L); while (!oai_exit) { @@ -232,13 +335,16 @@ static void* eNB_thread_rxtx( void* param ) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); - - if (oai_exit) break; if (eNB->CC_id==0) + { if (rxtx(eNB,proc,thread_name) < 0) break; + } + + if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + } // while !oai_exit VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); @@ -282,21 +388,16 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) proc->subframe_rx = subframe_rx; if (!oai_exit) { - LOG_D(PHY,"eNB_top in %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n", - (void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach); - T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx->frame_rx = proc->frame_rx; - proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10; - proc_rxtx->frame_tx = (proc->subframe_rx>5) ? (1+proc->frame_rx)&1023 : proc->frame_rx; + proc_rxtx->subframe_tx = (proc->subframe_rx+sf_ahead)%10; + proc_rxtx->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (1+proc->frame_rx)&1023 : proc->frame_rx; proc->frame_tx = proc_rxtx->frame_tx; proc_rxtx->timestamp_tx = proc->timestamp_tx; if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); - LOG_D(PHY,"eNB_top out %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n", - (void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach); } } @@ -322,6 +423,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { } } if (proc->RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return + LOG_E(PHY,"Not all RUs have provided their info\n"); pthread_mutex_unlock(&proc->mutex_RU); return(0); } @@ -338,7 +440,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { /* accept some delay in processing - up to 5ms */ for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { - LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx); + LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx); usleep(500); } if (proc_rxtx->instance_cnt_rxtx == 0) { @@ -346,7 +448,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { return(-1); } - // wake up TX for subframe n+4 + // wake up TX for subframe n+sf_ahead // lock the TX mutex and make sure the thread is ready if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); @@ -360,14 +462,14 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti, - // and proc->subframe_tx = proc->subframe_rx+4 - proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); + // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+sf_ahead + proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->subframe_rx = proc->subframe_rx; - proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; - proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10; - + proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx; + proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; + // the thread can now be woken up if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); @@ -598,10 +700,12 @@ void init_eNB_proc(int inst) { pthread_attr_t *attr_prach_br=NULL; #endif + LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); + for (CC_id=0; CC_idproc; @@ -657,6 +761,8 @@ void init_eNB_proc(int inst) { // attr_te = &proc->attr_te; #endif + LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); + if (eNB->single_thread_flag==0) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); @@ -793,6 +899,8 @@ void init_transport(PHY_VARS_eNB *eNB) { int j; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + LOG_I(PHY, "Initialise transport\n"); + for (i=0; i %p\n",i,j,eNB->dlsch[i][j]); eNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); } } @@ -855,20 +963,33 @@ void init_eNB_afterRU(void) { int inst,CC_id,ru_id,i,aa; PHY_VARS_eNB *eNB; + LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst); for (inst=0;instnum_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); + if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); eNB->frame_parms.nb_antennas_rx = 0; + + LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); + eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); #ifdef Rel14 - for (int ce_level=0;ce_level<4;ce_level++) - eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); + for (int ce_level=0;ce_level<4;ce_level++) { + LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); + eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); + } #endif + + LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); + for (ru_id=0,aa=0;ru_idnum_RU;ru_id++) { eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; @@ -890,6 +1011,36 @@ void init_eNB_afterRU(void) { eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; } } + + + + /* TODO: review this code, there is something wrong. + * In monolithic mode, we come here with nb_antennas_rx == 0 + * (not tested in other modes). + */ + if (eNB->frame_parms.nb_antennas_rx < 1) + { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); + eNB->frame_parms.nb_antennas_rx = 1; + } + else + { + //LOG_I(PHY," Delete code\n"); + } + + if (eNB->frame_parms.nb_antennas_tx < 1) + { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); + eNB->frame_parms.nb_antennas_tx = 1; + } + else + { + //LOG_I(PHY," Delete code\n"); + } + + + + AssertFatal(eNB->frame_parms.nb_antennas_rx >0, "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); @@ -917,7 +1068,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { int inst; PHY_VARS_eNB *eNB; + LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]); + if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **)); + LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n"); for (inst=0;instsingle_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 @@ -943,10 +1098,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); memset((void*)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); LOG_I(PHY,"Setting indication lists\n"); - eNB->UL_INFO.rx_ind.rx_pdu_list = eNB->rx_pdu_list; - eNB->UL_INFO.crc_ind.crc_pdu_list = eNB->crc_pdu_list; - eNB->UL_INFO.sr_ind.sr_pdu_list = eNB->sr_pdu_list; - eNB->UL_INFO.harq_ind.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; eNB->prach_energy_counter = 0; @@ -954,11 +1109,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { } - LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n"); - - - } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 18d9cd42fc..7f5d1d9ab9 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -133,6 +133,7 @@ int attach_rru(RU_t *ru); int connect_rau(RU_t *ru); +extern uint16_t sf_ahead; /*************************************************************/ /* Functions to attach and configure RRU */ @@ -392,8 +393,8 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { proc->frame_rx = f; proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); - proc->subframe_tx = (sf+4)%10; - proc->frame_tx = (sf>5) ? (f+1)&1023 : f; + proc->subframe_tx = (sf+sf_ahead)%10; + proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; if (proc->first_rx == 0) { if (proc->subframe_rx != *subframe){ @@ -595,6 +596,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { uint32_t symbol_number,symbol_mask,symbol_mask_full; int subframe_tx,frame_tx; + LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); symbol_number = 0; symbol_mask = 0; symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1; @@ -696,7 +698,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { for (i=0; inb_rx; i++) rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); old_ts = proc->timestamp_rx; @@ -739,11 +741,10 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { proc->subframe_phy_tx = (proc->subframe_rx+3)%10; proc->frame_phy_tx = (proc->subframe_rx>6) ? (proc->frame_rx+1)&1023 : proc->frame_rx; #else - proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); - proc->subframe_tx = (proc->subframe_rx+4)%10; - proc->frame_tx = (proc->subframe_rx>5) ? (proc->frame_rx+1)&1023 : proc->frame_rx; -#endif - + proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); + proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; + proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; +#endif LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", ru->idx, 0, @@ -778,11 +779,11 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); -// if (rxs != fp->samples_per_tti) -// exit_fun( "problem receiving samples" ); - - - + if (rxs != fp->samples_per_tti) + { + //exit_fun( "problem receiving samples" ); + LOG_E(PHY, "problem receiving samples"); + } } @@ -805,7 +806,6 @@ void tx_rf(RU_t *ru) { if ((SF_type == SF_DL) || (SF_type == SF_S)) { - int siglen=fp->samples_per_tti,flags=1; if (SF_type == SF_S) { @@ -1001,22 +1001,24 @@ static void* ru_thread_prach( void* param ) { thread_top_init("ru_thread_prach",1,500000L,1000000L,20000000L); + while (RC.ru_mask>0) { + usleep(1e6); + LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__); + } + LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); + while (!oai_exit) { if (oai_exit) break; if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - rx_prach(NULL, - ru, - NULL, - NULL, - NULL, - proc->frame_prach, - 0 + prach_procedures( + ru->eNB_list[0] #ifdef Rel14 - ,0 + ,0 #endif - ); + ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } @@ -1166,21 +1168,29 @@ void wakeup_eNBs(RU_t *ru) { int i; PHY_VARS_eNB **eNB_list = ru->eNB_list; - LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d\n",ru->num_eNB,ru->idx); + LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); - if (ru->num_eNB==1) { + if (ru->num_eNB==1 && ru->eNB_top!=0) { // call eNB function directly char string[20]; sprintf(string,"Incoming RU %d",ru->idx); - LOG_D(PHY,"RU %d Waking up eNB\n",ru->idx); + LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx); ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); } else { + LOG_D(PHY,"ru->num_eNB:%d\n", ru->num_eNB); + for (i=0;inum_eNB;i++) - if (ru->wakeup_rxtx(eNB_list[i],ru) < 0) + { + LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); + + if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) + { LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); + } + } } } @@ -1201,6 +1211,10 @@ static inline int wakeup_prach_ru(RU_t *ru) { ru->proc.frame_prach = ru->proc.frame_rx; ru->proc.subframe_prach = ru->proc.subframe_rx; + // DJP - think prach_procedures() is looking at eNB frame_prach + ru->eNB_list[0]->proc.frame_prach = ru->proc.frame_rx; + ru->eNB_list[0]->proc.subframe_prach = ru->proc.subframe_rx; + LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); // the thread can now be woken up AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); @@ -1440,7 +1454,6 @@ static void* ru_thread( void* param ) { init_frame_parms(&ru->frame_parms,1); phy_init_RU(ru); - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); } if (setup_RU_buffers(ru)!=0) { @@ -1496,20 +1509,10 @@ static void* ru_thread( void* param ) { subframe++; } - LOG_D(PHY,"RU thread (proc %p), frame %d (%p), subframe %d (%p)\n", - proc, frame,&frame,subframe,&subframe); - - // synchronization on input FH interface, acquire signals/data and block if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); - - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", - ru->do_prach, - is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), - proc->frame_rx,proc->subframe_rx); - #ifdef UE_EXPANSION if(first_phy_tx == 0) { @@ -1533,10 +1536,25 @@ static void* ru_thread( void* param ) { } first_phy_tx = 0; #endif + LOG_D(PHY,"AFTER fh_south_in - SFN/SF:%d%d RU->proc[RX:%d%d TX:%d%d] RC.eNB[0][0]:[RX:%d%d TX(SFN):%d]\n", + frame,subframe, + proc->frame_rx,proc->subframe_rx, + proc->frame_tx,proc->subframe_tx, + RC.eNB[0][0]->proc.frame_rx,RC.eNB[0][0]->proc.subframe_rx, + RC.eNB[0][0]->proc.frame_tx); + + LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", + ru->do_prach, + is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), + proc->frame_rx,proc->subframe_rx); - if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) wakeup_prach_ru(ru); + if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { + wakeup_prach_ru(ru); + } #ifdef Rel14 - else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) wakeup_prach_ru_br(ru); + else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) { + wakeup_prach_ru_br(ru); + } #endif // adjust for timing offset between RU @@ -1581,7 +1599,7 @@ static void* ru_thread( void* param ) { // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_eNBs(ru); - // wait until eNBs are finished subframe RX n and TX n+4 + // wait until eNBs are finished subframe RX n and TX n+sf_ahead wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread"); @@ -1601,7 +1619,6 @@ static void* ru_thread( void* param ) { continue; } #endif - } @@ -1968,6 +1985,10 @@ void init_RU_proc(RU_t *ru) { pthread_setname_np( proc->pthread_FH, name ); } + else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF + LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); + pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); + } if (get_nprocs()>=2) { if (ru->feprx) init_fep_thread(ru,NULL); @@ -1977,10 +1998,6 @@ void init_RU_proc(RU_t *ru) { } - - - - int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { FH_fmt_options_t fmt = cap->FH_fmt; @@ -2178,10 +2195,13 @@ void init_RU(char *rf_config_file) { RCconfig_RU(); LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); - for (i=0;inum_RU=0; + if (RC.nb_CC != 0) + for (i=0;inum_RU=0; + LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); for (ru_id=0;ru_idrf_config_file = rf_config_file; ru->idx = ru_id; @@ -2189,24 +2209,47 @@ void init_RU(char *rf_config_file) { // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! - + LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); + + if (ru->eNB_list[0] == 0) + { + LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); + ru->eNB_list[0] = RC.eNB[0][0]; + ru->num_eNB=1; + // + // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU + // + } + else + { + LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); + } + eNB0 = ru->eNB_list[0]; - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); + LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); + LOG_D(PHY, "eNB0:%p\n", eNB0); + if (eNB0) + { + if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) + AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); - if (eNB0) { - LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); - memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + if (eNB0) { + LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); + memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - // attach all RU to all eNBs in its list/ - for (i=0;inum_eNB;i++) { - eNB0 = ru->eNB_list[i]; - eNB0->RU_list[eNB0->num_RU++] = ru; + // attach all RU to all eNBs in its list/ + LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); + for (i=0;inum_eNB;i++) { + eNB0 = ru->eNB_list[i]; + eNB0->RU_list[eNB0->num_RU++] = ru; + } } } // LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); - + + LOG_D(PHY,"ru->if_south:%d\n", ru->if_south); + switch (ru->if_south) { case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) if (ru->function == NGFI_RRU_IF5) { // IF5 RRU @@ -2285,7 +2328,8 @@ void init_RU(char *rf_config_file) { if (setup_RU_buffers(ru)!=0) { printf("Exiting, cannot initialize RU Buffers\n"); exit(-1); - }*/ + } + */ break; case REMOTE_IF5: // the remote unit is IF5 RRU diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 35bac3e168..8bc3c65b88 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -101,7 +101,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #endif #include "lte-softmodem.h" - #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -113,9 +112,16 @@ unsigned char scope_enb_num_ue = 2; static pthread_t forms_thread; //xforms #endif //XFORMS +pthread_cond_t nfapi_sync_cond; +pthread_mutex_t nfapi_sync_mutex; +int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex + +uint8_t nfapi_mode = 0; // Default to monolithic mode + pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] @@ -205,6 +211,12 @@ uint64_t num_missed_slots=0; // counter for the number of missed slots extern void reset_opp_meas(void); extern void print_opp_meas(void); +extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag); + +extern void init_eNB_afterRU(void); + int transmission_mode=1; @@ -839,7 +851,7 @@ void init_openair0() { void wait_RUs(void) { - LOG_I(PHY,"Waiting for RUs to be configured ...\n"); + LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); // wait for all RUs to be configured over fronthaul pthread_mutex_lock(&RC.ru_mutex); @@ -848,6 +860,7 @@ void wait_RUs(void) { while (RC.ru_mask>0) { pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); + printf("RC.ru_mask:%02lx\n", RC.ru_mask); } LOG_I(PHY,"RUs configured\n"); @@ -860,19 +873,37 @@ void wait_eNBs(void) { while (waiting==1) { - printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst); - usleep(500000); + printf("Waiting for eNB L1 instances to all get configured ... sleeping 50ms (nb_L1_inst %d)\n",RC.nb_L1_inst); + usleep(50*1000); waiting=0; - for (i=0;iconfigured==0) { waiting=1; break; - } + } + } + } } printf("eNB L1 are configured\n"); } +static inline void wait_nfapi_init(char *thread_name) { + + printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + pthread_mutex_lock( &nfapi_sync_mutex ); + + while (nfapi_sync_var<0) + pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); + + pthread_mutex_unlock(&nfapi_sync_mutex); + + printf( "NFAPI: got sync (%s)\n", thread_name); +} + int main( int argc, char **argv ) { int i; @@ -974,6 +1005,7 @@ int main( int argc, char **argv ) log_set_instance_type (LOG_INSTANCE_ENB); } + printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); // initialize mscgen log after ITTI @@ -993,6 +1025,7 @@ int main( int argc, char **argv ) } #ifdef PDCP_USE_NETLINK + printf("PDCP netlink\n"); netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) pdcp_netlink_init(); @@ -1026,6 +1059,7 @@ int main( int argc, char **argv ) + printf("Before CC \n"); for (CC_id=0; CC_id2 */ cpu_set_t cpuset; @@ -1166,6 +1202,8 @@ int main( int argc, char **argv ) #ifdef XFORMS int UE_id; + printf("XFORMS\n"); + if (do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); @@ -1221,7 +1259,36 @@ int main( int argc, char **argv ) #endif rt_sleep_ns(10*100000000ULL); + + if (nfapi_mode) { + + printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + } + const char *nfapi_mode_str = ""; + + switch(nfapi_mode) { + case 0: + nfapi_mode_str = "MONOLITHIC"; + break; + case 1: + nfapi_mode_str = "PNF"; + break; + case 2: + nfapi_mode_str = "VNF"; + break; + default: + nfapi_mode_str = ""; + break; + } + printf("NFAPI MODE:%s\n", nfapi_mode_str); + + if (nfapi_mode==2) // VNF + wait_nfapi_init("main?"); + + printf("START MAIN THREADS\n"); // start the main threads if (UE_flag == 1) { @@ -1242,15 +1309,18 @@ int main( int argc, char **argv ) } else { 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\n"); + printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); init_eNB(single_thread_flag,wait_for_sync); // for (inst=0;inst0) { printf("Initializing RU threads\n"); init_RU(rf_config_file); @@ -1260,10 +1330,30 @@ int main( int argc, char **argv ) } } + config_sync_var=0; + + if (nfapi_mode==1) { // PNF + wait_nfapi_init("main?"); + } + + printf("wait RUs\n"); wait_RUs(); + printf("ALL RUs READY!\n"); + printf("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) - init_eNB_afterRU(); + printf("ALL RUs ready - init eNBs\n"); + + if (nfapi_mode != 1 && nfapi_mode != 2) + { + printf("Not NFAPI mode - call init_eNB_afterRU()\n"); + init_eNB_afterRU(); + } + else + { + printf("NFAPI mode - DO NOT call init_eNB_afterRU()\n"); + } + printf("ALL RUs ready - ALL eNBs ready\n"); } @@ -1297,38 +1387,35 @@ int main( int argc, char **argv ) //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; } else { - - - + printf("eNB mode\n"); } - - - printf("Sending sync to all threads\n"); - - pthread_mutex_lock(&sync_mutex); sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); + printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); end_configmodule(); + printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); // wait for end of program printf("TYPE TO TERMINATE\n"); //getchar(); - #if defined(ENABLE_ITTI) printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); + printf("Returned from ITTI signal handler\n"); oai_exit=1; + printf("oai_exit=%d\n",oai_exit); #else while (oai_exit==0) rt_sleep_ns(100000000ULL); + printf("Terminating application - oai_exit=%d\n",oai_exit); #endif @@ -1376,6 +1463,9 @@ int main( int argc, char **argv ) pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); + pthread_cond_destroy(&nfapi_sync_cond); + pthread_mutex_destroy(&nfapi_sync_mutex); + pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 diff --git a/targets/RT/USER/make_for_usrp.sh b/targets/RT/USER/make_for_usrp.sh deleted file mode 100755 index 998cd7c462..0000000000 --- a/targets/RT/USER/make_for_usrp.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -############### make nasmesh.ko ############### -sudo rmmod nasmesh -#cd ${OPENAIR2_DIR} && make nasmesh_netlink.ko -#cd ${OPENAIR2_DIR}/NAS/DRIVER/MESH/RB_TOOL/ && make -#make all -sudo insmod $OPENAIR2_DIR/NAS/DRIVER/MESH/nasmesh.ko - -############## Ethernet config #################### -sudo ifconfig eth0 mtu 4000 -sudo sysctl -w net.core.wmem_max=1048576 -sudo sysctl -w net.core.rmem_max=50000000 - -############## rtai modules ################### -if test \! -c /dev/rtai_shm; then - sudo mknod -m 666 /dev/rtai_shm c 10 254 -fi -for n in `seq 0 9`; do - f=/dev/rtf$n - if test \! -c $f; then - sudo mknod -m 666 $f c 150 $n - fi -done -sudo modprobe rtai_hal -sudo modprobe rtai_sched -sudo modprobe rtai_fifos -sudo modprobe rtai_sem -sudo modprobe rtai_mbx -sudo modprobe rtai_msg - -############## make ################### -make lte-softmodem-usrp NAS=1 USRP=1 XFORMS=1 RTAI=1 HARD_RT=1 #DRIVER2013=1 -#make lte-softmodem NAS=1 XFORMS=1 USRP=0 RTAI=1 DRIVER2013=1 -echo DONE! -exit 0 diff --git a/targets/RT/USER/msg_helper.c b/targets/RT/USER/msg_helper.c deleted file mode 100644 index ac99e48ff7..0000000000 --- a/targets/RT/USER/msg_helper.c +++ /dev/null @@ -1,87 +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 - -#include "msg_many.h" - -/* - * Add a task task to ri->worker. - * Return the used index in ri->worker on success - * Return -TM_WORKER_FULL_ERROR if ri->worker full - * Return -TM_WORKER_ERROR else -*/ -int tm_add_task(RT_TASK *task, run_info_t *ri) -{ - if(ri->used >= NUM_THREADS) - return -TM_WORKER_FULL_ERROR; - - rt_sem_wait(ri->update_sem); - (*ri->worker)[ri->used] = task; - ri->used++; - rt_sem_signal(ri->update_sem); - - return ri->used - 1; -} - -/* - * Remove the a hole in worker at index index by - * shift the next slots by one. - * This function assume that update_sem are locked. - * Return the new used counter. -*/ -int _tm_clean_worker(RT_TASK *(*worker)[], int index, int used) -{ - int i; - - for(i = index; i < used; i++) - (*worker)[i] = (*worker)[i + 1]; - - return used - 1; -} - -/* - * Remove a task from ri->worker a index task_index - * Return 0 on success - * Return -TM_WORKER_ERROR else -*/ -int tm_del_task(int task_index, run_info_t *ri) -{ - rt_sem_wait(ri->update_sem); - ri->used = _tm_clean_worker(ri->worker, task_index, ri->used); - rt_sem_signal(ri->update_sem); - - return 0; -} - -/* - * Return next index to use on ri->worker. - * It depends on the old_index and ri->used. - * Return -TM_WORKER_ERROR if ri->used == 0. -*/ -inline int tm_get_next_task_index(int old_index, run_info_t *ri) -{ - if(ri->used == 0) - return -TM_WORKER_ERROR; - - return (old_index + 1) % ri->used; -} - diff --git a/targets/RT/USER/msg_many.c b/targets/RT/USER/msg_many.c deleted file mode 100644 index 17e03c6c5a..0000000000 --- a/targets/RT/USER/msg_many.c +++ /dev/null @@ -1,181 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "msg_many.h" - -static void *msg_test_thread(void *arg) -{ - RT_TASK *self; - RT_TASK *sender_task; - thread_info_t *ti = (thread_info_t *)arg; - run_info_t *ri = ti->ri; - unsigned int msg; - int counter = 0; - char name[6]; - int task_index; - - /* Build custom task name for each thread */ - snprintf(name, 6, "%s%03i", THREAD_NAME_PREFIX, ti->thread_num); - - self = rt_task_init_schmod(nam2num(name), 0, 0, 0, SCHED_FIFO, 0xF); - mlockall(MCL_CURRENT | MCL_FUTURE); - - rt_make_hard_real_time(); - - task_index = tm_add_task(self, ri); - - if(task_index != -TM_WORKER_FULL_ERROR) { - while (*(ri->exit_condition) == 0) { - // wait only one PERIOD to avoid wait for ever - sender_task = rt_receive_timed(ri->sender, &msg, ri->period); - - //sender_task = rt_receive(0, &msg); - if(sender_task == ri->sender) - counter++; - } - - rt_printk("%s: counter == %i\n", name, counter); - tm_del_task(task_index, ri); - } else { - rt_printk("%s: Worker array full!\n", name); - } - - rt_make_soft_real_time(); - - rt_task_delete(self); - - free((void *) ti); - - return 0; -} - - -int main(void) -{ - RT_TASK *self; - RT_TASK *tmp_worker_task; - RT_TASK *worker_tasks[NUM_THREADS]; - int worker_threads[NUM_THREADS]; - RTIME now; - unsigned int i, ii; - run_info_t ri; - thread_info_t *ti; - uint8_t exit_condition = 0; - int fail_count = 0; - int old_index = 0; - uint8_t lost; - - // make main thread LXRT soft realtime - self = rt_task_init_schmod(nam2num("MAINTK"), 10, 0, 0, SCHED_FIFO, 0xF); - mlockall(MCL_CURRENT | MCL_FUTURE); - - rt_make_hard_real_time(); - rt_set_periodic_mode(); - start_rt_timer(0); - - /* Build all information need to run in main and the thread */ - ri.sender = self; - ri.exit_condition = &exit_condition; - ri.period = nano2count(PERIOD); - ri.update_sem = rt_sem_init(nam2num("MUTEX"), 1); - - if(ri.update_sem == 0) - exit(-1); - - ri.used = 0; - ri.worker = &worker_tasks; - - now = rt_get_time() + ri.period; - rt_task_make_periodic(self, now, ri.period); - - /* start all threads */ - for(i = 0; i < NUM_THREADS; i++) { - ti = (thread_info_t *)malloc(sizeof(thread_info_t)); - - if(ti == NULL) { - rt_printk("MAINTK: can't get memory!\n"); - exit(-1); - } - - ti->ri = &ri; - ti->thread_num = i; - worker_threads[i] = rt_thread_create(msg_test_thread, ti , 10000); - } - - rt_sleep(NUM_THREADS * ri.period); - - rt_printk("start\n"); - - for(i = 0; i < THRESHOLD; i++) { - rt_task_wait_period(); - lost = 1; - - for(ii = 0; ii < ri.used; ii++) { - old_index = tm_get_next_task_index(old_index, &ri); - - if(old_index == -TM_WORKER_ERROR) { - rt_printk("MAINTK: No Tasks!\n"); - break; - } - - tmp_worker_task = rt_send_if(worker_tasks[old_index], i); - - if(tmp_worker_task == worker_tasks[old_index]) { - lost = 0; - break; - } - } - - if(lost) - fail_count++; - } - - rt_printk("fail_count == %i\n", fail_count); - - // cleanup - exit_condition = 1; - rt_make_soft_real_time(); - - rt_task_delete(self); - - /* wait for the worker threadss */ - for(ii = 0; ii < ri.used; ii++) { - rt_thread_join(worker_threads[ii]); - } - - stop_rt_timer(); - return 0; -} diff --git a/targets/RT/USER/msg_many.h b/targets/RT/USER/msg_many.h deleted file mode 100644 index 5b9d465e33..0000000000 --- a/targets/RT/USER/msg_many.h +++ /dev/null @@ -1,53 +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 __MSG_MANY_H__ -#define __MSG_MANY_H__ -#include - -#define PERIOD 500000 /* in nano seconds */ -#define THRESHOLD 1000000 -#define THREAD_NAME_PREFIX "TK" -#define NUM_THREADS 10 - -#define TM_WORKER_FULL_ERROR 1 -#define TM_WORKER_ERROR 2 - -typedef struct run_info { - RT_TASK *sender; - uint8_t *exit_condition; - long long period; - SEM *update_sem; /* protect the task array */ - int used; /* counter of used slots in worker */ - RT_TASK *(*worker)[]; /* declare worker as pointer to array of pointer to RT_TASK */ -} run_info_t; - -typedef struct thread_info { - run_info_t *ri; - uint8_t thread_num; -} thread_info_t; - -int tm_add_task(RT_TASK *task, run_info_t *ri); -int tm_del_task(int task_index, run_info_t *ri); -inline int tm_get_next_task_index(int old_index, run_info_t *ri); - -#endif - diff --git a/targets/RT/USER/pnf.gtkw b/targets/RT/USER/pnf.gtkw new file mode 100644 index 0000000000..979d632138 --- /dev/null +++ b/targets/RT/USER/pnf.gtkw @@ -0,0 +1,54 @@ +[*] +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Tue Jul 25 20:26:12 2017 +[*] +[dumpfile] "/tmp/openair_dump_eNB.vcd" +[dumpfile_mtime] "Tue Jul 25 20:11:55 2017" +[dumpfile_size] 19201475 +[savefile] "/home/papillon/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw" +[timestart] 29023604000 +[size] 1236 578 +[pos] 309 0 +*-20.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[sst_width] 386 +[signals_width] 262 +[sst_expanded] 1 +[sst_vpaned_height] 146 +@28 +functions.trx_read +functions.trx_write +@24 +variables.trx_ts[63:0] +variables.trx_tst[63:0] +@25 +variables.frame_number_RX0_RU[63:0] +variables.subframe_number_RX0_RU[63:0] +@25 +variables.frame_number_TX0_RU[63:0] +variables.subframe_number_TX0_RU[63:0] +@24 +functions.phy_procedures_ru_feprx0 +functions.phy_procedures_ru_feprx1 +functions.phy_procedures_eNb_rx_uespec0 +functions.phy_procedures_eNb_tx0 +functions.eNB_thread_rxtx1 +functions.phy_enb_prach_rx +functions.phy_enb_rs_tx +functions.phy_enb_pdcch_tx +functions.nfapi_subframe +functions.generate_pcfich +functions.generate_dci0 +functions.pdcch_scrambling +functions.pdcch_modulation +functions.pdcch_interleaving +functions.pdcch_tx +functions.generate_dlsch +functions.generate_phich +functions.udp_enb_task +functions.phy_procedures_ru_feptx_ofdm0 +functions.phy_procedures_ru_feptx_ofdm1 +functions.phy_procedures_ru_feptx_prec0 +functions.phy_procedures_ru_feptx_prec1 +functions.phy_enb_prach_rx +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/targets/RT/USER/rrh.c b/targets/RT/USER/rrh.c deleted file mode 100644 index 88bd3f644d..0000000000 --- a/targets/RT/USER/rrh.c +++ /dev/null @@ -1,1220 +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 - */ - -/** ethernet_lib : API to stream I/Q samples over standard ethernet (RRH component) -* -* Authors: Raymond Knopp , Riadh Ghaddab -* -* Changelog: -* 06.10.2014: Initial version -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common_lib.h" - -#define BUF_LEN 4096+32 -#define RRH_eNB_PORT 50000 -#define RRH_eNB_DEST_IP "127.0.0.1" -#define RRH_UE_PORT 51000 -#define RRH_UE_DEST_IP "127.0.0.1" - -#define FRAME_MAX_SIZE 307200//76800 -#define DEFAULT_PERIOD_NS 133333//200000 - -#define START_CMD 1 -#define PRINTF_PERIOD 3750 - -typedef struct { - int eNB_port; - char eNB_dest_ip[20]; - int UE_port; - char UE_dest_ip[20]; - struct timespec time_req; -} rrh_desc_t; - -typedef struct { - int32_t nsamps; - int32_t antenna_index_eNB_rx; - int32_t antenna_index_eNB_tx; - int sockid_eNB; - struct sockaddr clientaddr; - socklen_t clientaddrlen; -} rrh_eNB_desc_t; - -typedef struct { - int32_t nsamps; - int32_t antenna_index_UE_rx; - int32_t antenna_index_UE_tx; - int sockid_UE; - struct sockaddr clientaddr; - socklen_t clientaddrlen; -} rrh_UE_desc_t; - -int rrh_exit=0; - -int32_t tx_buffer_eNB[4][(1+(sizeof(openair0_timestamp)>>2))+FRAME_MAX_SIZE],rx_buffer_eNB[4][(1+(sizeof(openair0_timestamp)>>2))+FRAME_MAX_SIZE]; -int32_t tx_buffer_UE[4][(1+(sizeof(openair0_timestamp)>>2))+FRAME_MAX_SIZE],rx_buffer_UE[4][(1+(sizeof(openair0_timestamp)>>2))+FRAME_MAX_SIZE]; -void *rrh_eNB_thread_status; -void *rrh_UE_thread_status; -int32_t counter_UE_rx[4]= {0,0,0,0}; -int32_t counter_UE_tx[4]= {0,0,0,0}; -int32_t counter_eNB_rx[4]= {0,0,0,0}; -int32_t counter_eNB_tx[4]= {0,0,0,0}; -int32_t overflow_rx_buffer_UE[4]= {0,0,0,0}; -int32_t overflow_rx_buffer_eNB[4]= {0,0,0,0}; -int32_t nsamps_eNB[4]= {0,0,0,0}; -int32_t nsamps_UE[4]= {0,0,0,0}; -int32_t UE_tx_started=0,eNB_tx_started=0, UE_rx_started=0,eNB_rx_started=0; -int32_t RT_FLAG=0, NRT_FLAG=1; -openair0_timestamp nrt_eNB_counter[4]= {0,0,0,0}; -openair0_timestamp nrt_UE_counter[4]= {0,0,0,0}; - -openair0_timestamp timestamp_eNB_tx[4],timestamp_eNB_rx[4]= {0,0,0,0}; -openair0_timestamp timestamp_UE_tx[4],timestamp_UE_rx[4]= {0,0,0,0}; -openair0_timestamp hw_counter=0; - -pthread_cond_t sync_UE_cond[4]; -pthread_mutex_t sync_UE_mutex[4]; -pthread_cond_t sync_eNB_cond[4]; -pthread_mutex_t sync_eNB_mutex[4]; -pthread_mutex_t timer_mutex; - -int sync_UE_rx[4]= {-1,-1,-1,-1}; -int sync_eNB_rx[4]= {-1,-1,-1,-1}; - -//functions prototype -void timer_signal_handler(int); -void *timer_proc(void *); -void *rrh_proc_eNB_thread(); -void *rrh_proc_UE_thread(); -void *rrh_UE_thread(void *); -void *rrh_UE_rx_thread(void *); -void *rrh_UE_tx_thread(void *); -void *rrh_eNB_thread(void *); -void *rrh_eNB_rx_thread(void *); -void *rrh_eNB_tx_thread(void *); - -void timer_signal_handler(int sig) -{ - - if (sig == SIGALRM) { - pthread_mutex_lock(&timer_mutex); - hw_counter ++; - //printf("[RRH] : hw_counter : %d\n",(int)hw_counter); - pthread_mutex_unlock(&timer_mutex); - } - - -} - - -void *timer_proc(void *arg) -{ - timer_t timerid; // timer ID for timer - //struct sigevent event; // event to deliver - struct itimerspec *timer = (struct itimerspec*)arg; // the timer data structure - struct itimerspec *old_value; - - - //printf("Starting the timer\n"); - if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) { - fprintf (stderr, "couldn't create a timer\n"); - perror (NULL); - exit (EXIT_FAILURE); - } - - signal(SIGALRM, timer_signal_handler); - // and start it! - timer_settime (timerid, 0, timer, old_value); - - while (!rrh_exit) { - sleep(1); - } - - timer_delete(timerid); - return (0); - - -} - - -void *rrh_proc_eNB_thread() -{ - - //rrh_desc_t *rrh_desc = (rrh_desc_t *)arg; - int antenna_index,i; - openair0_timestamp truncated_timestamp, truncated_timestamp_final, last_hw_counter=0; - struct timespec time_req, time_rem; - int16_t *rxp,*txp; - - time_req.tv_sec = 0; - time_req.tv_nsec = 1000; - - while (rrh_exit==0) { - //wait until some data has been copied - for (antenna_index=0; antenna_index<4; antenna_index++) { - if (sync_eNB_rx[antenna_index]==0) { - if (!eNB_tx_started) { - eNB_tx_started=1; // set this flag to 1 to indicate that eNB started - - if (RT_FLAG==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_FLAG==1) { - if (hw_counter > last_hw_counter+1) { - printf("L"); - // goto end_copy_eNB; - } else { - //printf("hw_counter : %llu, last_hw_counter : %llu\n",hw_counter,last_hw_counter); - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req,&time_rem); - } - } - } - - truncated_timestamp = timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE); - truncated_timestamp_final = (timestamp_eNB_tx[antenna_index]+nsamps_eNB[antenna_index])%FRAME_MAX_SIZE; - - if ((truncated_timestamp + nsamps_eNB[antenna_index]) > FRAME_MAX_SIZE) { - if ((timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE < nsamps_eNB[antenna_index]) && (UE_rx_started==1)) { - overflow_rx_buffer_UE[antenna_index]++; - printf("UE Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_UE[antenna_index],(int)truncated_timestamp); - - if (NRT_FLAG==1) { - while ((timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE) < nsamps_eNB[antenna_index]) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_UE[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp)>>2)]; - txp = (int16_t*)&tx_buffer_eNB[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp)>>2)]; - - for (i=0; i<(FRAME_MAX_SIZE<<1)-(truncated_timestamp<<1); i++) { - rxp[i] = txp[i]>>6; - } - - rxp = (int16_t*)&rx_buffer_UE[antenna_index][(sizeof(openair0_timestamp)>>2)]; - txp = (int16_t*)&tx_buffer_eNB[antenna_index][0]; - - for (i=0; i>6; - } - - /* memcpy(&rx_buffer_UE[antenna_index][truncated_timestamp + (sizeof(openair0_timestamp)>>2)],&tx_buffer_eNB[antenna_index][truncated_timestamp],(FRAME_MAX_SIZE<<2)-(truncated_timestamp<<2)); - memcpy(&rx_buffer_UE[antenna_index][(sizeof(openair0_timestamp)>>2)],&tx_buffer_eNB[antenna_index][0],(nsamps_eNB[antenna_index]<<2)-(FRAME_MAX_SIZE<<2)+(truncated_timestamp<<2));*/ - } else { - if (((truncated_timestamp < (timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE)) && (truncated_timestamp_final > (timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE))) && (UE_rx_started==1)) { - overflow_rx_buffer_UE[antenna_index]++; - printf("UE Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_UE[antenna_index],(int)truncated_timestamp); - - if (NRT_FLAG==1) { - while (truncated_timestamp_final > timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_UE[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp))]; - txp = (int16_t*)&tx_buffer_eNB[antenna_index][truncated_timestamp]; - - for (i=0; i<(nsamps_eNB[antenna_index]); i++) { - rxp[i] =txp[i]>>6; - } - - /* - memcpy(&rx_buffer_UE[antenna_index][truncated_timestamp + (sizeof(openair0_timestamp)>>2)],&tx_buffer_eNB[antenna_index][truncated_timestamp],(nsamps_eNB[antenna_index]<<2));*/ - } - - - // end_copy_eNB : - last_hw_counter=hw_counter; - pthread_mutex_lock(&sync_eNB_mutex[antenna_index]); - sync_eNB_rx[antenna_index]--; - pthread_mutex_unlock(&sync_eNB_mutex[antenna_index]); - - } - } - - } - - return(0); -} - -void *rrh_proc_UE_thread() -{ - - //rrh_desc_t *rrh_desc = (rrh_desc_t *)arg; - int antenna_index,i; - openair0_timestamp truncated_timestamp, truncated_timestamp_final, last_hw_counter=0; - struct timespec time_req, time_rem; - int16_t *txp,*rxp; - - time_req.tv_sec = 0; - time_req.tv_nsec = 1000; - - - while (rrh_exit==0) { - //wait until some data has been copied - for (antenna_index=0; antenna_index<4; antenna_index++) { - if (sync_UE_rx[antenna_index]==0) { - if (!UE_tx_started) { - UE_tx_started=1; //Set this flag to 1 to indicate that a UE started retrieving data - - if (RT_FLAG==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_FLAG==1) { - if (hw_counter > last_hw_counter+1) { - printf("L1"); - // goto end_copy_UE; - } else { - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req,&time_rem); - } - } - } - - truncated_timestamp = timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE); - truncated_timestamp_final = (timestamp_UE_tx[antenna_index]+nsamps_UE[antenna_index])%FRAME_MAX_SIZE; - - if ((truncated_timestamp + nsamps_UE[antenna_index]) > FRAME_MAX_SIZE) { - if ((timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE < nsamps_UE[antenna_index]) && (eNB_rx_started==1)) { - overflow_rx_buffer_eNB[antenna_index]++; - printf("eNB Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_eNB[antenna_index],(int)truncated_timestamp); - - if (NRT_FLAG==1) { - while ((timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE) < nsamps_UE[antenna_index]) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp)>>2)]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp)>>2)]; - - for (i=0; i<(FRAME_MAX_SIZE<<1)-(truncated_timestamp<<1); i++) { - rxp[i] = txp[i]>>6; - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][(sizeof(openair0_timestamp)>>2)]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][0]; - - for (i=0; i>6; - } - - /* - memcpy(&rx_buffer_eNB[antenna_index][truncated_timestamp + (sizeof(openair0_timestamp)>>2)],&tx_buffer_UE[antenna_index][truncated_timestamp],(FRAME_MAX_SIZE<<2)-(truncated_timestamp<<2)); - memcpy(&rx_buffer_eNB[antenna_index][(sizeof(openair0_timestamp)>>2)],&tx_buffer_UE[antenna_index][0],(nsamps_UE[antenna_index]<<2)-(FRAME_MAX_SIZE<<2)+(truncated_timestamp<<2));*/ - - } else { - if (((truncated_timestamp < (timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE)) && (truncated_timestamp_final > (timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE))) && (eNB_rx_started==1)) { - overflow_rx_buffer_eNB[antenna_index]++; - printf("eNB Overflow[%d] : %d, timestamp : %d\n",antenna_index,overflow_rx_buffer_eNB[antenna_index],(int)truncated_timestamp); - - if (NRT_FLAG==1) { - while (truncated_timestamp_final > timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE) - nanosleep(&time_req,&time_rem); - } - } - - rxp = (int16_t*)&rx_buffer_eNB[antenna_index][truncated_timestamp+(sizeof(openair0_timestamp))]; - txp = (int16_t*)&tx_buffer_UE[antenna_index][truncated_timestamp]; - - for (i=0; i<(nsamps_eNB[antenna_index]); i++) { - rxp[i] =txp[i]>>6; - } - - /* memcpy(&rx_buffer_eNB[antenna_index][truncated_timestamp+ (sizeof(openair0_timestamp)>>2)],&tx_buffer_UE[antenna_index][truncated_timestamp],(nsamps_UE[antenna_index]<<2));*/ - } - - //end_copy_UE : - last_hw_counter=hw_counter; - pthread_mutex_lock(&sync_UE_mutex[antenna_index]); - sync_UE_rx[antenna_index]--; - pthread_mutex_unlock(&sync_UE_mutex[antenna_index]); - - } - } - - } - - return(0); -} - - -void *rrh_UE_rx_thread(void *arg) -{ - - struct sockaddr clientaddr; - socklen_t clientaddrlen; - rrh_UE_desc_t *rrh_UE_rx_desc = (rrh_UE_desc_t *)arg; - struct timespec time0,time1,time2; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_sent; - int antenna_index, nsamps; - int trace_cnt=0; - int sockid; - char str[INET_ADDRSTRLEN]; - unsigned long long max_rx_time=0, min_rx_time=133333, total_rx_time=0, average_rx_time=133333, s_period=0, trial=0; - - openair0_timestamp temp, last_hw_counter=0; - - antenna_index = rrh_UE_rx_desc->antenna_index_UE_rx; - nsamps = rrh_UE_rx_desc->nsamps; - sockid = rrh_UE_rx_desc->sockid_UE; - - - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - //printf("Waiting for eNB ...\n"); - //printf("[RRH eNB RX thread] received parameters : nsamps : %d, antenna_index : %d\n",nsamps,antenna_index); - clientaddr = rrh_UE_rx_desc->clientaddr; - clientaddrlen = rrh_UE_rx_desc->clientaddrlen; - - inet_ntop(AF_INET, &(((struct sockaddr_in*)&clientaddr)->sin_addr), str, INET_ADDRSTRLEN); - printf("Received UE RX request for antenna %d, nsamps %d (from %s:%d)\n",antenna_index,nsamps,str, - ntohs(((struct sockaddr_in*)&clientaddr)->sin_port)); - - while (rrh_exit == 0) { - if (!UE_rx_started) { - UE_rx_started=1; //Set this flag to 1 to indicate that a UE started retrieving data - - if (RT_FLAG==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_FLAG==1) { - if (hw_counter > last_hw_counter+1) { - printf("L1"); - // goto end_copy_UE; - } else { - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - } - - clock_gettime(CLOCK_MONOTONIC,&time1); - - // send return - temp=*(openair0_timestamp*)&rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)]; - *(openair0_timestamp*)&rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)]=timestamp_UE_rx[antenna_index]; - - if ((timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)+nsamps) > FRAME_MAX_SIZE) { // Wrap around if nsamps exceeds the buffer limit - if (((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE)) < ((timestamp_UE_rx[antenna_index]+nsamps)%(FRAME_MAX_SIZE))) && (eNB_tx_started==1)) { - printf("UE underflow wraparound timestamp_UE_rx : %d, timestamp_eNB_tx : %d\n",(int)(timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)),(int)(timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE)); - - if (NRT_FLAG==1) { - while ((timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE) < ((timestamp_UE_rx[antenna_index]+nsamps)%(FRAME_MAX_SIZE))) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - - if ((bytes_sent = sendto(sockid, - &rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)], - ((FRAME_MAX_SIZE)<<2) - ((timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE))<<2) + sizeof(openair0_timestamp), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH UE : sendto for RX"); - - if ((bytes_sent = sendto(sockid, - &rx_buffer_UE[antenna_index][0], - (nsamps<<2) - ((FRAME_MAX_SIZE)<<2) + ((timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE))<<2), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH UE : sendto for RX"); - } else { - if (((timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE)< timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE) - && (((timestamp_UE_rx[antenna_index]+nsamps)%FRAME_MAX_SIZE) > (timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE)) && (eNB_tx_started==1) ) { - printf("UE underflow timestamp_UE_rx : %d, timestamp_eNB_tx : %d\n",(int)(timestamp_UE_rx[antenna_index]%FRAME_MAX_SIZE),(int)(timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE)); - - if (NRT_FLAG==1) { - while (((timestamp_UE_rx[antenna_index]+nsamps)%FRAME_MAX_SIZE) > (timestamp_eNB_tx[antenna_index]%FRAME_MAX_SIZE)) { - nanosleep(&time_req_1us,&time_rem_1us); - } - } - } - - - if ((bytes_sent = sendto(sockid, - &rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)], - (nsamps<<2)+sizeof(openair0_timestamp), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH UE thread: sendto for RX"); - } - - //printf("bytes_sent %d(timestamp_UE_rx[%d] %d)\n",(int)bytes_sent,antenna_index,(int)timestamp_UE_rx[antenna_index]); - *(openair0_timestamp*)&rx_buffer_UE[antenna_index][timestamp_UE_rx[antenna_index]%(FRAME_MAX_SIZE)]=temp; - timestamp_UE_rx[antenna_index]+=nsamps; - last_hw_counter=hw_counter; - - clock_gettime(CLOCK_MONOTONIC,&time2); - - if (trace_cnt++ > 10) { - total_rx_time = (unsigned int)(time2.tv_nsec - time0.tv_nsec); - - if (total_rx_time < 0) total_rx_time=1000000000-total_rx_time; - - if ((total_rx_time > 0) && (total_rx_time < 1000000000)) { - trial++; - - if (total_rx_time < min_rx_time) - min_rx_time = total_rx_time; - - if (total_rx_time > max_rx_time) - max_rx_time = total_rx_time; - - average_rx_time = (long long unsigned int)((average_rx_time*trial)+total_rx_time)/(trial+1); - } - - if (s_period++ == PRINTF_PERIOD) { - s_period=0; - printf("Average UE RX time : %lu\tMax RX time : %lu\tMin RX time : %lu\n",average_rx_time,max_rx_time,min_rx_time); - - } - - //printf("RX: t1 %llu (time from last send), t2 %llu (sendto of %lu bytes) total time : %llu\n",(long long unsigned int)(time1.tv_nsec - time0.tv_nsec), (long long unsigned int)(time2.tv_nsec - time1.tv_nsec), - // (nsamps<<2)+sizeof(openair0_timestamp),(long long unsigned int)(time2.tv_nsec - time0.tv_nsec)); - - } - - memcpy(&time0,&time2,sizeof(struct timespec)); - - - } //while (rrh_exit==0) - - return(0); - -} - - -void *rrh_UE_tx_thread(void *arg) -{ - struct sockaddr clientaddr; - socklen_t clientaddrlen; - struct timespec time0a,time0,time1,time2; - rrh_UE_desc_t *rrh_UE_tx_desc = (rrh_UE_desc_t *)arg; - // struct timespec time_rem; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_received; - int antenna_index, nsamps; - int8_t buf[BUF_LEN]; - int trace_cnt=0; - int sockid; - - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - - antenna_index = rrh_UE_tx_desc->antenna_index_UE_tx; - nsamps = rrh_UE_tx_desc->nsamps; - sockid = rrh_UE_tx_desc->sockid_UE; - - while (rrh_exit == 0) { - - clock_gettime(CLOCK_MONOTONIC,&time0a); - - bytes_received = recvfrom(sockid,buf,BUF_LEN,0,&clientaddr,&clientaddrlen); - timestamp_eNB_tx[antenna_index] = *(openair0_timestamp*)(buf+4); - - clock_gettime(CLOCK_MONOTONIC,&time1); - - if (NRT_FLAG==1) { - nrt_UE_counter[antenna_index]++; - } - - //printf("Received UE TX request for antenna %d, nsamps %d, timestamp %d bytes_received %d\n",antenna_index,nsamps,(int)timestamp_UE_tx[antenna_index],(int)bytes_received); - if ((timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE)+nsamps) > FRAME_MAX_SIZE) { // Wrap around if nsamps exceeds the buffer limit - memcpy(&tx_buffer_UE[antenna_index][timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE)],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t), - (FRAME_MAX_SIZE<<2)-((timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE))<<2)); - memcpy(&tx_buffer_UE[antenna_index][0],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t)+(FRAME_MAX_SIZE*4)-((timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE))<<2), - (nsamps<<2)-((FRAME_MAX_SIZE-(timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE)))<<2)); - //printf("Received UE TX samples for antenna %d, nsamps %d (%d)\n",antenna_index,nsamps,(int)(bytes_received>>2)); - } else { - memcpy(&tx_buffer_UE[antenna_index][timestamp_UE_tx[antenna_index]%(FRAME_MAX_SIZE)],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t),(nsamps<<2)); - } - - //printf("Received UE TX samples for antenna %d, nsamps %d (%d)\n",antenna_index,nsamps,(int)(bytes_received>>2)); - - while (sync_UE_rx[antenna_index]==0) - nanosleep(&time_req_1us,&time_rem_1us); - - pthread_mutex_lock(&sync_UE_mutex[antenna_index]); - sync_UE_rx[antenna_index]++; - - if (!sync_UE_rx[antenna_index]) { - counter_UE_tx[antenna_index]=(counter_UE_tx[antenna_index]+nsamps)%FRAME_MAX_SIZE; - nsamps_UE[antenna_index]=nsamps; - } else { - printf("rrh_eNB_proc thread is busy, will exit\n"); - exit(-1); - } - - pthread_mutex_unlock(&sync_UE_mutex[antenna_index]); - - clock_gettime(CLOCK_MONOTONIC,&time2); - - memcpy(&time0,&time2,sizeof(struct timespec)); - - } - - return(0); - -} - - - -void *rrh_UE_thread(void *arg) -{ - - int sockid=-1; - struct sockaddr_in serveraddr; - struct sockaddr clientaddr; - socklen_t clientaddrlen; - rrh_desc_t *rrh_desc = (rrh_desc_t *)arg; - char str[INET_ADDRSTRLEN]; - //int8_t msg_header[4+sizeof(openair0_timestamp)]; - int8_t buf[BUF_LEN]; - int16_t cmd; //,nsamps,antenna_index; - ssize_t bytes_received; - // struct timespec time_rem; - // ssize_t bytes_sent; - // openair0_timestamp temp; - // openair0_timestamp last_hw_counter=0; - struct timespec time_req_1us, time_rem_1us; - - rrh_UE_desc_t rrh_UE_desc; - pthread_t UE_rx_thread, UE_tx_thread; - pthread_attr_t attr_UE_rx, attr_UE_tx; - struct sched_param sched_param_UE_rx, sched_param_UE_tx; - int error_code_UE_rx, error_code_UE_tx; - - time_req_1us.tv_sec = 0; - time_req_1us.tv_nsec = 1000; - - while (rrh_exit==0) { - - - sockid=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); - - if (sockid==-1) { - perror("Cannot create UE socket: "); - rrh_exit=1; - } - - - bzero((char *)&serveraddr,sizeof(serveraddr)); - serveraddr.sin_family=AF_INET; - serveraddr.sin_port=htons(rrh_desc->UE_port); - inet_pton(AF_INET,rrh_desc->UE_dest_ip,&serveraddr.sin_addr.s_addr); - - inet_ntop(AF_INET, &(serveraddr.sin_addr), str, INET_ADDRSTRLEN); - printf("Binding to UE socket for %s:%d\n",str,ntohs(serveraddr.sin_port)); - - if (bind(sockid,(struct sockaddr *)&serveraddr,sizeof(serveraddr))<0) { - perror("Cannot bind to UE socket: "); - rrh_exit = 1; - } - - // now wait for commands from eNB - - // get header info - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - //printf("Waiting for UE ...\n"); - - bytes_received = recvfrom(sockid,buf,BUF_LEN,0,&clientaddr,&clientaddrlen); - cmd = buf[0]; - - rrh_UE_desc.antenna_index_UE_rx = cmd>>1; - rrh_UE_desc.antenna_index_UE_tx = cmd>>1; - //rrh_eNB_desc.timestamp_eNB_tx[rrh_eNB_desc.antenna_index_eNB_tx] = *(openair0_timestamp*)(buf+4); //we don't need timestamp when receiving the first command - rrh_UE_desc.nsamps = *(int16_t *)(buf+2); - rrh_UE_desc.sockid_UE = sockid; - rrh_UE_desc.clientaddr = clientaddr; - rrh_UE_desc.clientaddrlen = clientaddrlen; - - cmd = cmd&1; - inet_ntop(AF_INET, &(((struct sockaddr_in*)&clientaddr)->sin_addr), str, INET_ADDRSTRLEN); - - if (cmd==START_CMD) { - - pthread_attr_init(&attr_UE_rx); - pthread_attr_init(&attr_UE_tx); - sched_param_UE_rx.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_param_UE_tx.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_UE_rx,&sched_param_UE_rx); - pthread_attr_setschedparam(&attr_UE_tx,&sched_param_UE_tx); - pthread_attr_setschedpolicy(&attr_UE_rx,SCHED_FIFO); - pthread_attr_setschedpolicy(&attr_UE_tx,SCHED_FIFO); - - error_code_UE_rx = pthread_create(&UE_rx_thread, &attr_UE_rx, rrh_UE_rx_thread, (void *)&rrh_UE_desc); - error_code_UE_tx = pthread_create(&UE_tx_thread, &attr_UE_tx, rrh_UE_tx_thread, (void *)&rrh_UE_desc); - - if (error_code_UE_rx) { - printf("Error while creating UE RX thread\n"); - exit(-1); - } - - if (error_code_UE_tx) { - printf("Error while creating UE TX thread\n"); - exit(-1); - } - - while (rrh_exit==0) - sleep(1); - } - } - - close(sockid); - - rrh_UE_thread_status = 0; - pthread_exit(&rrh_UE_thread_status); - - return(0); -} - - - -void *rrh_eNB_rx_thread(void *arg) -{ - - struct sockaddr clientaddr; - socklen_t clientaddrlen; - rrh_eNB_desc_t *rrh_eNB_rx_desc = (rrh_eNB_desc_t *)arg; - struct timespec time0,time1,time2; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_sent; - int antenna_index, nsamps; - int trace_cnt=0; - int sockid; - char str[INET_ADDRSTRLEN]; - unsigned long long max_rx_time=0, min_rx_time=133333, total_rx_time=0, average_rx_time=133333, s_period=0, trial=0; - - openair0_timestamp temp, last_hw_counter=0; - - antenna_index = rrh_eNB_rx_desc->antenna_index_eNB_rx; - nsamps = rrh_eNB_rx_desc->nsamps; - sockid = rrh_eNB_rx_desc->sockid_eNB; - - - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - //printf("Waiting for eNB ...\n"); - //printf("[RRH eNB RX thread] received parameters : nsamps : %d, antenna_index : %d\n",nsamps,antenna_index); - clientaddr = rrh_eNB_rx_desc->clientaddr; - clientaddrlen = rrh_eNB_rx_desc->clientaddrlen; - - inet_ntop(AF_INET, &(((struct sockaddr_in*)&clientaddr)->sin_addr), str, INET_ADDRSTRLEN); - printf("Received eNB RX request for antenna %d, nsamps %d (from %s:%d)\n",antenna_index,nsamps,str, - ntohs(((struct sockaddr_in*)&clientaddr)->sin_port)); - - while (rrh_exit == 0) { - //printf("Received eNB RX request for antenna %d, nsamps %d (from %s:%d)\n",antenna_index,nsamps,str, - // ntohs(((struct sockaddr_in*)&clientaddr)->sin_port)); - - if (!eNB_rx_started) { - eNB_rx_started=1; // set this flag to 1 to indicate that eNB started - - if (RT_FLAG==1) { - last_hw_counter=hw_counter; - } - } else { - if (RT_FLAG==1) { - if (hw_counter > last_hw_counter+1) { - printf("L"); - // goto end_copy_eNB; - } else { - while (hw_counter < last_hw_counter+1) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - } - - clock_gettime(CLOCK_MONOTONIC,&time1); - - // send return - temp=*(openair0_timestamp*)&rx_buffer_eNB[antenna_index][timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)]; - *(openair0_timestamp*)&rx_buffer_eNB[antenna_index][timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)]=timestamp_eNB_rx[antenna_index]; - - if ((timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)+nsamps) > FRAME_MAX_SIZE) { // Wrap around if nsamps exceeds the buffer limit - if ((timestamp_UE_tx[antenna_index]%FRAME_MAX_SIZE < ((timestamp_eNB_rx[antenna_index]+nsamps)%FRAME_MAX_SIZE)) && (UE_tx_started==1)) { - printf("eNB underflow\n"); - - if (NRT_FLAG==1) { - while ((timestamp_UE_tx[antenna_index]%FRAME_MAX_SIZE) < nsamps) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - - - if ((bytes_sent = sendto(sockid, - &rx_buffer_eNB[antenna_index][timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)], - ((FRAME_MAX_SIZE)<<2) - ((timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE))<<2) + sizeof(openair0_timestamp), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH eNB : sendto for RX"); - - if ((bytes_sent = sendto(sockid, - &rx_buffer_eNB[antenna_index][0], - (nsamps<<2) - ((FRAME_MAX_SIZE)<<2) + ((timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE))<<2), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH eNB : sendto for RX"); - } else { - if (((timestamp_eNB_rx[antenna_index]%FRAME_MAX_SIZE)< timestamp_UE_tx[antenna_index]%FRAME_MAX_SIZE) - && (((timestamp_eNB_rx[antenna_index]+nsamps)%FRAME_MAX_SIZE) > (timestamp_UE_tx[antenna_index]%FRAME_MAX_SIZE)) && (UE_tx_started==1)) { - printf("eNB underflow\n"); - - if (NRT_FLAG==1) { - while (((timestamp_eNB_rx[antenna_index]+nsamps)%FRAME_MAX_SIZE) > (timestamp_UE_tx[antenna_index]%FRAME_MAX_SIZE)) - nanosleep(&time_req_1us,&time_rem_1us); - } - } - - if ((bytes_sent = sendto(sockid, - &rx_buffer_eNB[antenna_index][timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)], - (nsamps<<2)+sizeof(openair0_timestamp), - 0, - (struct sockaddr*)&clientaddr, - sizeof(struct sockaddr)))<0) - perror("RRH eNB : sendto for RX"); - - } - - //printf("bytes_sent %d(timestamp_eNB_rx[%d] %d)\n",(int)bytes_sent,antenna_index,(int)timestamp_eNB_rx[antenna_index]); - - - *(openair0_timestamp*)&rx_buffer_eNB[antenna_index][timestamp_eNB_rx[antenna_index]%(FRAME_MAX_SIZE)]=temp; - timestamp_eNB_rx[antenna_index]+=nsamps; - last_hw_counter=hw_counter; - - clock_gettime(CLOCK_MONOTONIC,&time2); - - if (trace_cnt++ > 10) { - total_rx_time = (unsigned int)(time2.tv_nsec - time0.tv_nsec); - - if (total_rx_time < 0) total_rx_time=1000000000-total_rx_time; - - if ((total_rx_time > 0) && (total_rx_time < 1000000000)) { - trial++; - - if (total_rx_time < min_rx_time) - min_rx_time = total_rx_time; - - if (total_rx_time > max_rx_time) - max_rx_time = total_rx_time; - - average_rx_time = (long long unsigned int)((average_rx_time*trial)+total_rx_time)/(trial+1); - } - - if (s_period++ == PRINTF_PERIOD) { - s_period=0; - printf("Average eNB RX time : %lu\tMax RX time : %lu\tMin RX time : %lu\n",average_rx_time,max_rx_time,min_rx_time); - - } - - //printf("RX: t1 %llu (time from last send), t2 %llu (sendto of %lu bytes) total time : %llu\n",(long long unsigned int)(time1.tv_nsec - time0.tv_nsec), (long long unsigned int)(time2.tv_nsec - time1.tv_nsec), - // (nsamps<<2)+sizeof(openair0_timestamp),(long long unsigned int)(time2.tv_nsec - time0.tv_nsec)); - - } - - memcpy(&time0,&time2,sizeof(struct timespec)); - - - } //while (rrh_exit==0) - - return(0); - -} - - -void *rrh_eNB_tx_thread(void *arg) -{ - - struct sockaddr clientaddr; - socklen_t clientaddrlen; - struct timespec time0a,time0,time1,time2; - rrh_eNB_desc_t *rrh_eNB_tx_desc = (rrh_eNB_desc_t *)arg; - // struct timespec time_rem; - struct timespec time_req_1us, time_rem_1us; - ssize_t bytes_received; - int antenna_index, nsamps; - int8_t buf[BUF_LEN]; - int trace_cnt=0; - int sockid; - - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - //printf("Waiting for eNB ...\n"); - - antenna_index = rrh_eNB_tx_desc->antenna_index_eNB_tx; - nsamps = rrh_eNB_tx_desc->nsamps; - sockid = rrh_eNB_tx_desc->sockid_eNB; - - while (rrh_exit == 0) { - - clock_gettime(CLOCK_MONOTONIC,&time0a); - - bytes_received = recvfrom(sockid,buf,BUF_LEN,0,&clientaddr,&clientaddrlen); - timestamp_eNB_tx[antenna_index] = *(openair0_timestamp*)(buf+4); - - clock_gettime(CLOCK_MONOTONIC,&time1); - - if (NRT_FLAG==1) { - nrt_eNB_counter[antenna_index]++; - } - - //printf("Received eNB TX request for antenna %d, nsamps %d, timestamp %d bytes_received %d\n",antenna_index,nsamps,(int)timestamp_eNB_tx[antenna_index],(int)bytes_received); - - if ((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE)+nsamps) > FRAME_MAX_SIZE) { // Wrap around if nsamps exceeds the buffer limit - memcpy(&tx_buffer_eNB[antenna_index][timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE)],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t), - ((FRAME_MAX_SIZE)<<2)-((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE))<<2)); - //printf("Done first part size : %d\n",(int32_t)(((FRAME_MAX_SIZE)<<2)-((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE))<<2))); - memcpy(&tx_buffer_eNB[antenna_index][0],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t) + ((FRAME_MAX_SIZE)<<2) -((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE))<<2), - (nsamps<<2)-((FRAME_MAX_SIZE)<<2)+((timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE))<<2)); - //printf("Received eNB TX samples for antenna %d, nsamps %d (%d)\n",antenna_index,nsamps,(int)(bytes_received>>2)); - } else { - memcpy(&tx_buffer_eNB[antenna_index][timestamp_eNB_tx[antenna_index]%(FRAME_MAX_SIZE)],buf+sizeof(openair0_timestamp)+2*sizeof(int16_t),nsamps<<2); - } - - while (sync_eNB_rx[antenna_index]==0) - nanosleep(&time_req_1us,&time_rem_1us); - - //printf("launching eNB proc\n"); - pthread_mutex_lock(&sync_eNB_mutex[antenna_index]); - sync_eNB_rx[antenna_index]++; - - if (!sync_eNB_rx[antenna_index]) { - counter_eNB_tx[antenna_index]=(counter_eNB_tx[antenna_index]+nsamps)%FRAME_MAX_SIZE; - nsamps_eNB[antenna_index]=nsamps; - } else { - printf("rrh_eNB_proc thread is busy, will exit\n"); - exit(-1); - } - - pthread_mutex_unlock(&sync_eNB_mutex[antenna_index]); - - clock_gettime(CLOCK_MONOTONIC,&time2); - - //if (trace_cnt++ < 10) - // printf("TX: t0 %llu (time from previous run) t1 %llu (time of memcpy TX samples), t2 %llu (total time)\n",(long long unsigned int)(time1.tv_nsec - time0.tv_nsec), - // (long long unsigned int)(time2.tv_nsec - time1.tv_nsec), - // (long long unsigned int)(time2.tv_nsec - time0.tv_nsec)); - - memcpy(&time0,&time2,sizeof(struct timespec)); - - - - } - - return(0); - -} - -void *rrh_eNB_thread(void *arg) -{ - - int sockid=-1; - struct sockaddr_in serveraddr; - struct sockaddr clientaddr; - socklen_t clientaddrlen; - rrh_desc_t *rrh_desc = (rrh_desc_t *)arg; - char str[INET_ADDRSTRLEN]; - //int8_t msg_header[4+sizeof(openair0_timestamp)]; - int8_t buf[BUF_LEN]; - int16_t cmd; //,nsamps,antenna_index; - ssize_t bytes_received; - //ssize_t bytes_sent; - //openair0_timestamp temp, last_hw_counter=0; - //struct timespec time_rem; - struct timespec time_req_1us, time_rem_1us; - //struct timespec time0a,time0,time1,time2; - //int trace_cnt=0; - rrh_eNB_desc_t rrh_eNB_desc; - pthread_t eNB_rx_thread, eNB_tx_thread; - pthread_attr_t attr_eNB_rx, attr_eNB_tx; - struct sched_param sched_param_eNB_rx, sched_param_eNB_tx; - int error_code_eNB_rx, error_code_eNB_tx; - - time_req_1us.tv_sec = 0; - time_req_1us.tv_nsec = 1000; - - - while (rrh_exit==0) { - - - sockid=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); - - if (sockid==-1) { - perror("Cannot create eNB socket: "); - rrh_exit=1; - } - - - bzero((char *)&serveraddr,sizeof(serveraddr)); - serveraddr.sin_family=AF_INET; - serveraddr.sin_port=htons(rrh_desc->eNB_port); - inet_pton(AF_INET,rrh_desc->eNB_dest_ip,&serveraddr.sin_addr.s_addr); - - inet_ntop(AF_INET, &(serveraddr.sin_addr), str, INET_ADDRSTRLEN); - printf("Binding to eNB socket for %s:%d\n",str,ntohs(serveraddr.sin_port)); - - if (bind(sockid,(struct sockaddr *)&serveraddr,sizeof(serveraddr))<0) { - perror("Cannot bind to eNB socket: "); - rrh_exit = 1; - } - - // now wait for commands from eNB - - // get header info - bzero((void*)&clientaddr,sizeof(struct sockaddr)); - clientaddrlen = sizeof(struct sockaddr); - //printf("Waiting for eNB ...\n"); - - - - bytes_received = recvfrom(sockid,buf,BUF_LEN,0,&clientaddr,&clientaddrlen); - cmd = buf[0]; - rrh_eNB_desc.antenna_index_eNB_rx = cmd>>1; - rrh_eNB_desc.antenna_index_eNB_tx = cmd>>1; - //rrh_eNB_desc.timestamp_eNB_tx[rrh_eNB_desc.antenna_index_eNB_tx] = *(openair0_timestamp*)(buf+4); //we don't need timestamp when receiving the first command - rrh_eNB_desc.nsamps = *(int16_t *)(buf+2); - rrh_eNB_desc.sockid_eNB = sockid; - rrh_eNB_desc.clientaddr = clientaddr; - rrh_eNB_desc.clientaddrlen = clientaddrlen; - - //cmd = cmd&1; - cmd = cmd|1;//in order to make cmd evalution dummy (the first message from lte to rrh has changed, see: @ethernet_lib.c trx_start_func has been substituted by trx_request_func ) - inet_ntop(AF_INET, &(((struct sockaddr_in*)&clientaddr)->sin_addr), str, INET_ADDRSTRLEN); - - if (cmd==START_CMD) { - - pthread_attr_init(&attr_eNB_rx); - pthread_attr_init(&attr_eNB_tx); - sched_param_eNB_rx.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_param_eNB_tx.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&attr_eNB_rx,&sched_param_eNB_rx); - pthread_attr_setschedparam(&attr_eNB_tx,&sched_param_eNB_tx); - pthread_attr_setschedpolicy(&attr_eNB_rx,SCHED_FIFO); - pthread_attr_setschedpolicy(&attr_eNB_tx,SCHED_FIFO); - - error_code_eNB_rx = pthread_create(&eNB_rx_thread, &attr_eNB_rx, rrh_eNB_rx_thread, (void *)&rrh_eNB_desc); - error_code_eNB_tx = pthread_create(&eNB_tx_thread, &attr_eNB_tx, rrh_eNB_tx_thread, (void *)&rrh_eNB_desc); - - if (error_code_eNB_rx) { - printf("Error while creating eNB RX thread\n"); - exit(-1); - } - - if (error_code_eNB_tx) { - printf("Error while creating eNB TX thread\n"); - exit(-1); - } - - while (rrh_exit==0) - sleep(1); - - } - - - } //while (rrh_exit==0) - - close(sockid); - - rrh_eNB_thread_status = 0; - pthread_exit(&rrh_eNB_thread_status); - - return(0); -} - - -void signal_handler(int sig) -{ - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("trying to exit gracefully...\n"); - rrh_exit = 1; - } -} - -int main(int argc, char **argv) -{ - - pthread_t main_rrh_eNB_thread, main_rrh_UE_thread, main_rrh_proc_eNB_thread, main_rrh_proc_UE_thread, main_timer_proc_thread; - pthread_attr_t attr, attr_proc, attr_timer; - struct sched_param sched_param_rrh, sched_param_rrh_proc, sched_param_timer; - int error_code_eNB, error_code_UE, error_code_proc_eNB, error_code_proc_UE, error_code_timer; - int i; - int opt; - int nsecs=0, rt_period=0; - rrh_desc_t rrh; - struct itimerspec timer; - - - rrh.time_req.tv_sec = 0; - rrh.time_req.tv_nsec = 0; - - rrh.eNB_port = RRH_eNB_PORT; - strcpy(rrh.eNB_dest_ip,RRH_eNB_DEST_IP); - rrh.UE_port = RRH_UE_PORT; - strcpy(rrh.UE_dest_ip ,RRH_UE_DEST_IP); - - nsecs = 0; - - while ((opt = getopt(argc, argv, "t:rE:U:")) != -1) { - switch (opt) { - case 't': - rt_period = atoi(optarg); - RT_FLAG=1; - NRT_FLAG=0; - break; - - case 'r': - rt_period = DEFAULT_PERIOD_NS; - RT_FLAG=1; - NRT_FLAG=0; - break; - - case 'E': - strcpy(rrh.eNB_dest_ip,optarg); - break; - - case 'U': - strcpy(rrh.UE_dest_ip,optarg); - break; - - default: /* '?' */ - fprintf(stderr, "Usage: %s [-d nsecs]\n", argv[0]); - exit(-1); - } - } - - // if (optind >= argc) { - // fprintf(stderr, "Expected argument after options\n"); - // exit(EXIT_FAILURE); - // } - - // setup the timer (1s delay, 1s reload) - timer.it_value.tv_sec = rt_period/1000000000; - timer.it_value.tv_nsec = rt_period%1000000000; - timer.it_interval.tv_sec = rt_period/1000000000; - timer.it_interval.tv_nsec = rt_period%1000000000; - - - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - - - pthread_attr_init(&attr); - sched_param_rrh.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_init(&attr_proc); - sched_param_rrh_proc.sched_priority = sched_get_priority_max(SCHED_FIFO-1); - pthread_attr_init(&attr_timer); - sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO-2); - - pthread_attr_setschedparam(&attr,&sched_param_rrh); - pthread_attr_setschedpolicy(&attr,SCHED_FIFO); - pthread_attr_setschedparam(&attr_proc,&sched_param_rrh_proc); - pthread_attr_setschedpolicy(&attr_proc,SCHED_FIFO-1); - pthread_attr_setschedparam(&attr_timer,&sched_param_timer); - pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO-2); - - for (i=0; i<4; i++) { - pthread_mutex_init(&sync_eNB_mutex[i],NULL); - pthread_cond_init(&sync_eNB_cond[i],NULL); - pthread_mutex_init(&sync_UE_mutex[i],NULL); - pthread_cond_init(&sync_UE_cond[i],NULL); - } - - pthread_mutex_init(&timer_mutex,NULL); - - error_code_eNB = pthread_create(&main_rrh_eNB_thread, &attr, rrh_eNB_thread, (void *)&rrh); - error_code_UE = pthread_create(&main_rrh_UE_thread, &attr, rrh_UE_thread, (void *)&rrh); - error_code_proc_UE = pthread_create(&main_rrh_proc_UE_thread, &attr_proc, rrh_proc_UE_thread, NULL); - error_code_proc_eNB = pthread_create(&main_rrh_proc_eNB_thread, &attr_proc, rrh_proc_eNB_thread, NULL); - error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timer); - - if (error_code_eNB) { - printf("Error while creating eNB thread\n"); - exit(-1); - } - - if (error_code_UE) { - printf("Error while creating UE thread\n"); - exit(-1); - } - - if (error_code_proc_UE) { - printf("Error while creating UE proc thread\n"); - exit(-1); - } - - if (error_code_proc_eNB) { - printf("Error while creating eNB proc thread\n"); - exit(-1); - } - - if (error_code_timer) { - printf("Error while creating timer proc thread\n"); - exit(-1); - } - - printf("TYPE TO TERMINATE\n"); - - while (rrh_exit==0) - sleep(1); - - - //pthread_join(main_rrh_eNB_thread,&rrh_eNB_thread_status); - return 0; -} diff --git a/targets/RT/USER/rrh.gtkw b/targets/RT/USER/rrh.gtkw deleted file mode 100644 index 891f23ada5..0000000000 --- a/targets/RT/USER/rrh.gtkw +++ /dev/null @@ -1,195 +0,0 @@ -[*] -[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Fri Jan 29 16:34:46 2016 -[*] -[dumpfile] "/tmp/openair_dump_rrh.vcd" -[dumpfile_mtime] "Fri Jan 29 16:20:55 2016" -[dumpfile_size] 224259458 -[savefile] "/home/guepe/openairinterface5g_rrh/openairinterface5g/targets/RT/USER/rrh.gtkw" -[timestart] 31315875900 -[size] 1004 1028 -[pos] 926 -1 -*-17.429794 31316090054 -1 -1 -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] 224 -[signals_width] 261 -[sst_expanded] 1 -[sst_vpaned_height] 278 -@24 -[color] 1 -variables.hw_frame_rx[63:0] -[color] 1 -variables.hw_subframe_rx[63:0] -@28 -[color] 1 -functions.eNB_rx -functions.eNB_rx_sleep -[color] 3 -functions.trx_read_rf -[color] 7 -functions.trx_write -@c00024 -variables.rxcnt[63:0] -@28 -(0)variables.rxcnt[63:0] -(1)variables.rxcnt[63:0] -(2)variables.rxcnt[63:0] -(3)variables.rxcnt[63:0] -(4)variables.rxcnt[63:0] -(5)variables.rxcnt[63:0] -(6)variables.rxcnt[63:0] -(7)variables.rxcnt[63:0] -(8)variables.rxcnt[63:0] -(9)variables.rxcnt[63:0] -(10)variables.rxcnt[63:0] -(11)variables.rxcnt[63:0] -(12)variables.rxcnt[63:0] -(13)variables.rxcnt[63:0] -(14)variables.rxcnt[63:0] -(15)variables.rxcnt[63:0] -(16)variables.rxcnt[63:0] -(17)variables.rxcnt[63:0] -(18)variables.rxcnt[63:0] -(19)variables.rxcnt[63:0] -(20)variables.rxcnt[63:0] -(21)variables.rxcnt[63:0] -(22)variables.rxcnt[63:0] -(23)variables.rxcnt[63:0] -(24)variables.rxcnt[63:0] -(25)variables.rxcnt[63:0] -(26)variables.rxcnt[63:0] -(27)variables.rxcnt[63:0] -(28)variables.rxcnt[63:0] -(29)variables.rxcnt[63:0] -(30)variables.rxcnt[63:0] -(31)variables.rxcnt[63:0] -(32)variables.rxcnt[63:0] -(33)variables.rxcnt[63:0] -(34)variables.rxcnt[63:0] -(35)variables.rxcnt[63:0] -(36)variables.rxcnt[63:0] -(37)variables.rxcnt[63:0] -(38)variables.rxcnt[63:0] -(39)variables.rxcnt[63:0] -(40)variables.rxcnt[63:0] -(41)variables.rxcnt[63:0] -(42)variables.rxcnt[63:0] -(43)variables.rxcnt[63:0] -(44)variables.rxcnt[63:0] -(45)variables.rxcnt[63:0] -(46)variables.rxcnt[63:0] -(47)variables.rxcnt[63:0] -(48)variables.rxcnt[63:0] -(49)variables.rxcnt[63:0] -(50)variables.rxcnt[63:0] -(51)variables.rxcnt[63:0] -(52)variables.rxcnt[63:0] -(53)variables.rxcnt[63:0] -(54)variables.rxcnt[63:0] -(55)variables.rxcnt[63:0] -(56)variables.rxcnt[63:0] -(57)variables.rxcnt[63:0] -(58)variables.rxcnt[63:0] -(59)variables.rxcnt[63:0] -(60)variables.rxcnt[63:0] -(61)variables.rxcnt[63:0] -(62)variables.rxcnt[63:0] -(63)variables.rxcnt[63:0] -@1401200 --group_end -@24 -variables.pck_rx[63:0] -variables.rx_ts[63:0] -@c00024 -variables.tx_seq_num[63:0] -@28 -(0)variables.tx_seq_num[63:0] -(1)variables.tx_seq_num[63:0] -(2)variables.tx_seq_num[63:0] -(3)variables.tx_seq_num[63:0] -(4)variables.tx_seq_num[63:0] -(5)variables.tx_seq_num[63:0] -(6)variables.tx_seq_num[63:0] -(7)variables.tx_seq_num[63:0] -(8)variables.tx_seq_num[63:0] -(9)variables.tx_seq_num[63:0] -(10)variables.tx_seq_num[63:0] -(11)variables.tx_seq_num[63:0] -(12)variables.tx_seq_num[63:0] -(13)variables.tx_seq_num[63:0] -(14)variables.tx_seq_num[63:0] -(15)variables.tx_seq_num[63:0] -(16)variables.tx_seq_num[63:0] -(17)variables.tx_seq_num[63:0] -(18)variables.tx_seq_num[63:0] -(19)variables.tx_seq_num[63:0] -(20)variables.tx_seq_num[63:0] -(21)variables.tx_seq_num[63:0] -(22)variables.tx_seq_num[63:0] -(23)variables.tx_seq_num[63:0] -(24)variables.tx_seq_num[63:0] -(25)variables.tx_seq_num[63:0] -(26)variables.tx_seq_num[63:0] -(27)variables.tx_seq_num[63:0] -(28)variables.tx_seq_num[63:0] -(29)variables.tx_seq_num[63:0] -(30)variables.tx_seq_num[63:0] -(31)variables.tx_seq_num[63:0] -(32)variables.tx_seq_num[63:0] -(33)variables.tx_seq_num[63:0] -(34)variables.tx_seq_num[63:0] -(35)variables.tx_seq_num[63:0] -(36)variables.tx_seq_num[63:0] -(37)variables.tx_seq_num[63:0] -(38)variables.tx_seq_num[63:0] -(39)variables.tx_seq_num[63:0] -(40)variables.tx_seq_num[63:0] -(41)variables.tx_seq_num[63:0] -(42)variables.tx_seq_num[63:0] -(43)variables.tx_seq_num[63:0] -(44)variables.tx_seq_num[63:0] -(45)variables.tx_seq_num[63:0] -(46)variables.tx_seq_num[63:0] -(47)variables.tx_seq_num[63:0] -(48)variables.tx_seq_num[63:0] -(49)variables.tx_seq_num[63:0] -(50)variables.tx_seq_num[63:0] -(51)variables.tx_seq_num[63:0] -(52)variables.tx_seq_num[63:0] -(53)variables.tx_seq_num[63:0] -(54)variables.tx_seq_num[63:0] -(55)variables.tx_seq_num[63:0] -(56)variables.tx_seq_num[63:0] -(57)variables.tx_seq_num[63:0] -(58)variables.tx_seq_num[63:0] -(59)variables.tx_seq_num[63:0] -(60)variables.tx_seq_num[63:0] -(61)variables.tx_seq_num[63:0] -(62)variables.tx_seq_num[63:0] -(63)variables.tx_seq_num[63:0] -@1401200 --group_end -@24 -variables.hw_frame[63:0] -variables.hw_subframe[63:0] -@28 -[color] 1 -functions.eNB_tx -functions.eNB_tx_sleep -[color] 7 -functions.trx_read -[color] 3 -functions.trx_write_rf -@24 -variables.txcnt[63:0] -variables.pck_tx[63:0] -variables.tx_ts[63:0] -@25 -variables.rx_seq_num_prv[63:0] -@24 -variables.rx_seq_num[63:0] -variables.hw_cnt_rx[63:0] -variables.lhw_cnt_rx[63:0] -[color] 3 -variables.cnt[63:0] -[pattern_trace] 1 -[pattern_trace] 0 diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c deleted file mode 100644 index 7aea0484be..0000000000 --- a/targets/RT/USER/rrh_gw.c +++ /dev/null @@ -1,460 +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 rrh_gw.h - * \brief top-level for the remote radio head gateway (RRH_gw) module reusing the ethernet library - * \author Navid Nikaein, Katerina Trilyraki, Raymond Knopp - * \date 2015 - * \version 0.1 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning very experimental - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common_lib.h" -#include "rrh_gw.h" -#include "rt_wrapper.h" -#include "rrh_gw_externs.h" - - -#include "log_if.h" -#include "log_extern.h" -#include "vcd_signal_dumper.h" - -/***************************************************************************************** - * ---------- * - * ------- RRH_BBU_IF ------- RRH_RF_IF -------USRP - COTS_UE- * - * - BBU - --------------- - RRH - ------------- -------BLADERF ---------- * - * ------- ------- -------EXMIMO * - * --------- * - * -------ETH_IF - EMU_UE- * - * --------- * - *****************************************************************************************/ - - -/* local IP/MAC address is detected*/ -char rrh_ip[20] = "0.0.0.0"; -unsigned char rrh_mac[20] = "0:0:0:0:0:0"; -int rrh_port = 50000; // has to be an option - -/* log */ -int16_t glog_level = LOG_DEBUG; -int16_t glog_verbosity = LOG_MED; -int16_t rrh_log_level = LOG_INFO; -int16_t rrh_log_verbosity = LOG_MED; -int16_t enb_log_level = LOG_INFO; -int16_t enb_log_verbosity = LOG_MED; -int16_t ue_log_level = LOG_INFO; -int16_t ue_log_verbosity = LOG_MED; - - -/* flag definitions */ -uint8_t eNB_flag=0; -uint8_t UE_flag=0; -uint8_t EXMIMO_flag=0; -uint8_t USRP_flag=0; -uint8_t RT_flag=0, NRT_flag=1; -uint8_t rrh_exit=0; -uint8_t loopback_flag=0; -uint8_t measurements_flag=0; - -/* Default operation as RRH: - - there are neither eNB nor UE modules - - no RF hardware is specified (NONE_IF) - - default ethernet interface is local */ -uint8_t num_eNB_mod=0; -uint8_t num_UE_mod=0; -char* if_name="lo"; -uint8_t eth_mode=ETH_UDP_MODE; - -rrh_module_t *enb_array; -rrh_module_t *ue_array; - -openair0_vtimestamp hw_counter=0; - -char rf_config_file[1024]; - -static void debug_init(void); -static void get_options(int argc, char *argv[]); -static void print_help(void); - -/*!\fn static rrh_module_t new_module(unsigned int id); -* \brief creation of a eNB/UE module -* \param[in] module id -* \return module -* \note -* @ingroup _oai -*/ -static rrh_module_t new_module(unsigned int id); - -/*!\fn static int get_address(char* if_name, uint8_t flag); - * \brief retrieves IP address from the specified network interface - * \param[in] name of network interface - * \return 0 - * \note - * @ingroup _oai - */ -static int get_address(char* if_name, uint8_t flag); - - - - - -int main(int argc, char **argv) { - - unsigned int i; - rf_config_file[0]='\0'; - /* parse input arguments */ - get_options(argc, argv); - /* initialize logger and signal analyzer */ - debug_init(); - /* */ - set_latency_target(); - /* make a graceful exit when ctrl-c is pressed */ - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - - /* create modules based on input arguments */ - if (eNB_flag==1){ - enb_array=(rrh_module_t*)malloc(num_eNB_mod*sizeof(rrh_module_t)); - for(i=0;i TO TERMINATE\n"); - - while (rrh_exit==0) - sleep(1); - - return EXIT_SUCCESS; -} - - -static rrh_module_t new_module (unsigned int id) { - - rrh_module_t rrh_mod; - openair0_config_t openair0_cfg; - - rrh_mod.id=id; - rrh_mod.loopback=loopback_flag; - rrh_mod.measurements=measurements_flag; - - /* each module is associated with an ethernet device */ - rrh_mod.eth_dev.type=NONE_DEV; - rrh_mod.eth_dev.transp_type=NONE_TP; - /* ethernet device is functioning within RRH */ - rrh_mod.eth_dev.host_type=RRH_HOST; - /* */ - rrh_mod.eth_dev.openair0_cfg = (openair0_config_t*)malloc(sizeof(openair0_config_t)); - memset(rrh_mod.eth_dev.openair0_cfg,0,sizeof(openair0_config_t)); - /* get IP and MAC address */ - get_address(if_name,eth_mode); - - if(eth_mode==ETH_UDP_MODE) { - openair0_cfg.my_addr = &rrh_ip[0]; - openair0_cfg.my_port = rrh_port; - LOG_I(RRH,"UDP mode selected for ethernet.\n"); - } else if (eth_mode==ETH_RAW_MODE) { - openair0_cfg.my_addr = (char*)&rrh_mac[0]; - openair0_cfg.my_port = rrh_port; - LOG_I(RRH,"RAW mode selected for ethernet.\n"); - } - - /* */ - eth_params_t *eth_params = (eth_params_t*)malloc(sizeof(eth_params_t)); - memset(eth_params, 0, sizeof(eth_params_t)); - eth_params->local_if_name = if_name; - eth_params->transp_preference = eth_mode; - - /* ethernet device initialization */ - if (openair0_transport_load(&rrh_mod.eth_dev, &openair0_cfg,eth_params)<0) { - LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n"); - exit(-1); - } - - /* allocate space and specify associated RF device */ - openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device)); - memset(oai_dv,0,sizeof(openair0_device)); - - rrh_mod.devs=oai_dv; - rrh_mod.devs->type=NONE_DEV; - rrh_mod.devs->transp_type=NONE_TP; - rrh_mod.devs->host_type=RRH_HOST; - - return rrh_mod; -} - -static void debug_init(void) { - - /* log initialization */ - logInit(); - set_glog(glog_level, glog_verbosity); - - set_comp_log(RRH, rrh_log_level, rrh_log_verbosity, 1); - //set_comp_log(ENB_LOG, enb_log_level, enb_log_verbosity, 1); - //set_comp_log(UE_LOG, ue_log_level, ue_log_verbosity, 1); - - /* vcd initialization */ - if (ouput_vcd) { - vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd"); - - } -} - - -static void get_options(int argc, char *argv[]) { - - int opt; - - while ((opt = getopt(argc, argv, "xvhlte:n:u:g:r:m:i:f:")) != -1) { - - switch (opt) { - case 'n': - eNB_flag=1; - num_eNB_mod=atoi(optarg); - break; - case 'u': - UE_flag=1; - num_UE_mod=atoi(optarg); - break; - case 'g': - glog_level=atoi(optarg); - break; - case 'i': - if (optarg) { - if_name=strdup(optarg); - printf("RRH interface name is set to %s\n", if_name); - } - break; - case 'm': - eth_mode=atoi(optarg); - break; - case 'r': - //rrh_log_level=atoi(optarg); - break; - case 'e': - //enb_log_level=atoi(optarg); - break; - case 'x': - rt_period = DEFAULT_PERIOD_NS; - RT_flag=1; - NRT_flag=0; - break; - case 'v': - /* extern from vcd */ - ouput_vcd=1; - break; - case 'l': - /*In loopback mode rrh sends back to bbu what it receives*/ - loopback_flag=1; - break; - case 'f': - if (optarg){ - if ((strcmp("null", optarg) == 0) || (strcmp("NULL", optarg) == 0)) { - printf("no configuration filename is provided\n"); - } - else if (strlen(optarg)<=1024){ - // rf_config_file = strdup(optarg); - strcpy(rf_config_file,optarg); - }else { - printf("Configuration filename is too long\n"); - exit(-1); - } - } - break; - case 't': - /* When measurements are enabled statistics related to TX/RX time are printed */ - measurements_flag=1; - break; - case 'h': - print_help(); - exit(-1); - default: /* '?' */ - //fprintf(stderr, "Usage: \n", argv[0]); - exit(-1); - } -} - -} - -static int get_address(char* if_name, uint8_t flag) { - - int fd; - struct ifreq ifr; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - /* I want to get an IPv4 IP address */ - ifr.ifr_addr.sa_family = AF_INET; - /* I want IP address attached to "if_name" */ - strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1); - - if (flag==ETH_UDP_MODE) { - if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) { - perror("IOCTL:"); - exit(-1); - } - snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); - LOG_I(RRH,"%s: IP address: %s\n",if_name,rrh_ip); - } else if (flag==ETH_RAW_MODE) { - if ( ioctl(fd, SIOCGIFHWADDR, &ifr)<0 ) { - perror("IOCTL:"); - exit(-1); - } - ether_ntoa_r ((struct ether_addr *)ifr.ifr_hwaddr.sa_data, (char*)rrh_mac); - LOG_I(RRH,"%s: MAC address: %s\n",if_name,rrh_mac); - } - - close(fd); - return 0; -} - - -static void print_help(void) { - - puts("Usage: \n"); - puts(" sudo -E chrt 99 ./rrh -n1 -g6 -v -t -i lo -m1"); - puts("Options:\n"); - puts("\t -n create eNB module\n"); - puts("\t -u create UE module\n"); - puts("\t -g define global log level\n"); - puts("\t -i set the RRH interface (default lo)\n"); - puts("\t -m set ethernet mode to be used by RRH, valid options: (1:raw, 0:udp) \n"); - puts("\t -r define rrh log level\n"); - puts("\t -e define eNB log level\n"); - puts("\t -x enable real time bahaviour\n"); - puts("\t -v enable vcd dump\n"); - puts("\t -l enable loopback mode\n"); - puts("\t -t enable measurements\n"); - puts("\t -h display info\n"); - -} - - -void *timer_proc(void *arg) { - - timer_t timerid; - struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure - struct itimerspec old_value; - - -#ifdef DEADLINE_SCHEDULER - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = (0.1 * 100) * 10000; // - attr.sched_deadline = rt_period-30000;//(0.1 * 100) * 10000; - attr.sched_period = rt_period;//(0.1 * 100) * 10000; // each TX/RX thread has, as a function of RT PERIOD ?? - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] timer thread: sched_setattr failed\n"); - exit(-1); - } -#endif - - if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) { - fprintf (stderr, "couldn't create a timer\n"); - perror (NULL); - exit (EXIT_FAILURE); - } - - signal(SIGALRM, timer_signal_handler); - LOG_I(RRH,"Timer has started!\n"); - timer_settime (timerid, 0, timer, &old_value); - - while (!rrh_exit) { - sleep(1); - } - - timer_delete(timerid); - - return (0); -} - - -void timer_signal_handler(int sig) { - - if (sig == SIGALRM) { - pthread_mutex_lock(&timer_mutex); - hw_counter ++; - pthread_mutex_unlock(&timer_mutex); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, hw_counter);//USED ELSEWHERE - } -} - - -void signal_handler(int sig) { - - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - printf("trying to exit gracefully...\n"); - rrh_exit = 1; - } -} - -void exit_fun(const char* s) { - if (s != NULL) { - printf("%s %s() Exiting RRH: %s\n",__FILE__, __FUNCTION__, s); - } - rrh_exit = 1; - exit (-1); -} - - diff --git a/targets/RT/USER/rrh_gw.h b/targets/RT/USER/rrh_gw.h deleted file mode 100644 index 97ffa5a893..0000000000 --- a/targets/RT/USER/rrh_gw.h +++ /dev/null @@ -1,104 +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 rrh_gw.h - * \brief header file for remote radio head gateway (RRH_gw) module - * \author Navid Nikaein, Katerina Trilyraki, Raymond Knopp - * \date 2015 - * \version 0.1 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning very experimental - */ - -#ifndef RRH_GW_H_ -#define RRH_GW_H_ - -#include "ethernet_lib.h" -#include "vcd_signal_dumper.h" -#include "assertions.h" - -#define DEFAULT_PERIOD_NS 200000 /* default value is calculated for 25 PRB */ -#define RRH_UE_PORT 51000 -#define RRH_UE_DEST_IP "127.0.0.1" - -/*! \brief RRH supports two types of modules: eNB and UE - each module is associated with an ethernet device (device of ETH_IF) - and optionally with a RF device (device type can be USRP_B200/USRP_X300/BLADERF_IF/EXMIMO_IF/NONE_IF) - UE modules will always have RF device type NONE_IF */ -typedef struct { -/*! \brief module id */ - uint8_t id; -/*! \brief! loopback flag */ -uint8_t loopback; -/*! \brief measurement flag */ -uint8_t measurements; -/*! \brief module's ethernet device */ -openair0_device eth_dev; -/*! \brief pointer to RF module's device (pointer->since it's optional) */ -openair0_device *devs; -}rrh_module_t; - -/*! \fn void timer_signal_handler(int sig) - * \brief this function - * \param[in] signal type - * \return none - * \note - * @ingroup _oai -*/ -void timer_signal_handler(int); - -/*! \fn void *timer_proc(void *arg) - * \brief this function - * \param[in] - * \param[out] - * \return - * \note - * @ingroup _oai - */ -void *timer_proc(void *); - -/*! \fn void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag,uint8_t NRT_flag) - * \brief receive and apply configuration to modules' optional device - * \param[in] *mod_enb pointer to module - * \param[in] RT_flag real time flag - * \return none - * \note - * @ingroup _oai - */ -void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag); - -/*! \fn void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) - * \brief this function - * \param[in] *mod_ue pointer to module - * \param[in] - * \return none - * \note - * @ingroup _oai - */ -void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag); - - - -void signal_handler(int sig); - -#endif diff --git a/targets/RT/USER/rrh_gw_externs.h b/targets/RT/USER/rrh_gw_externs.h deleted file mode 100644 index 0786743399..0000000000 --- a/targets/RT/USER/rrh_gw_externs.h +++ /dev/null @@ -1,48 +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 rrh_gw_extern.h - * \brief rrh gatewy external vars - * \author Navid Nikaein, Katerina Trilyraki, Raymond Knopp - * \date 2015 - * \version 0.1 - * \company Eurecom - * \maintainer: navid.nikaein@eurecom.fr - * \note - * \warning very experimental - */ - -#ifndef RRH_GW_EXTERNS_H_ -#define RRH_GW_EXTERNS_H_ -extern char rf_config_file[1024]; - -extern openair0_timestamp timestamp_UE_tx[4] ,timestamp_UE_rx[4] ,timestamp_eNB_rx[4],timestamp_eNB_tx[4]; -extern openair0_vtimestamp hw_counter; -extern int32_t UE_tx_started,UE_rx_started,eNB_rx_started ,eNB_tx_started; -extern int32_t nsamps_UE[4],nsamps_eNB[4]; -extern int32_t overflow_rx_buffer_eNB[4],overflow_rx_buffer_UE[4]; -extern uint8_t rrh_exit; -extern int32_t **rx_buffer_eNB, **rx_buffer_UE; -extern unsigned int rt_period; -extern pthread_mutex_t timer_mutex; - - -#endif diff --git a/targets/RT/USER/rt_wrapper.c b/targets/RT/USER/rt_wrapper.c index 8751e3c816..c1e5996d44 100644 --- a/targets/RT/USER/rt_wrapper.c +++ b/targets/RT/USER/rt_wrapper.c @@ -345,6 +345,8 @@ void thread_top_init(char *thread_name, exit_fun("Error getting thread priority"); } + pthread_setname_np(pthread_self(), thread_name); + LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(), (policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_RR) ? "SCHED_RR" : diff --git a/targets/RT/USER/sleeptest.c b/targets/RT/USER/sleeptest.c deleted file mode 100644 index ba5cb0ce15..0000000000 --- a/targets/RT/USER/sleeptest.c +++ /dev/null @@ -1,302 +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 lte-softmodem.c -* \brief main program to control HW and scheduling -* \author R. Knopp, F. Kaltenberger -* \date 2012 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rt_wrapper.h" - -#define TIMER_ONESHOT_MODE -#define FRAME_PERIOD 10000000ULL -#define DAQ_PERIOD 500000ULL -#define LTE_SLOTS_PER_FRAME 20 - -#ifdef RTAI -static SEM *mutex; -//static CND *cond; - -static long int thread0; -static long int thread1; -//static long int sync_thread; -#else -#define OPENAIR_THREAD_STACK_SIZE 8192 -#define OPENAIR_THREAD_PRIORITY 255 -pthread_t thread0; -//pthread_t thread1; -pthread_attr_t attr_dlsch_threads; -struct sched_param sched_param_dlsch; -#endif - -int oai_exit = 0; - -struct timing_info_t { - //unsigned int frame, hw_slot, last_slot, next_slot; - RTIME time_min, time_max, time_avg, time_last, time_now; - //unsigned int mbox0, mbox1, mbox2, mbox_target; - unsigned int n_samples; -} timing_info; - -void signal_handler(int sig) -{ - void *array[10]; - size_t size; - - if (sig==SIGSEGV) { - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(-1); - } else { - oai_exit=1; - } -} - -void exit_fun(const char* s) -{ - void *array[10]; - size_t size; - - printf("Exiting: %s\n",s); - - oai_exit=1; - //rt_sleep_ns(FRAME_PERIOD); - - //exit (-1); -} - -int frame=0,slot=0; - -/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ -static void *eNB_thread(void *arg) -{ -#ifdef RTAI - RT_TASK *task; - RTIME now; -#endif - unsigned char last_slot, next_slot; - RTIME time_in, time_diff; - int ret; - -#ifdef RTAI - task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); - printf("Started eNB thread (id %p)\n",task); -#ifndef TIMER_ONESHOT_MODE - now = rt_get_time(); - ret = rt_task_make_periodic(task, now, nano2count(DAQ_PERIOD)); - - if (ret!=0) - printf("Problem with periodic timer\n"); - -#endif -#endif - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - timing_info.time_min = 100000000ULL; - timing_info.time_max = 0; - timing_info.time_avg = 0; - timing_info.n_samples = 0; - - while (!oai_exit) { - time_in = rt_get_time_ns(); -#ifdef TIMER_ONESHOT_MODE - ret = rt_sleep_ns(DAQ_PERIOD); - - if (ret) - printf("eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame,time_in,ret); - -#else - rt_task_wait_period(); -#endif - time_diff = rt_get_time_ns() - time_in; - - if (time_diff > timing_info.time_max) - timing_info.time_max = time_diff; - - if (time_diff < timing_info.time_min) - timing_info.time_min = time_diff; - - timing_info.time_avg = (timing_info.time_avg*timing_info.n_samples + time_diff)/(timing_info.n_samples+1); - timing_info.n_samples++; - - last_slot = (slot)%LTE_SLOTS_PER_FRAME; - - if (last_slot <0) - last_slot+=20; - - next_slot = (slot+3)%LTE_SLOTS_PER_FRAME; - - slot++; - - if (slot==20) { - slot=0; - frame++; - } - } - - printf("eNB_thread: finished, ran %d times.\n",frame); - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - // clean task -#ifdef RTAI - rt_task_delete(task); -#endif - printf("Task deleted. returning\n"); - return 0; -} - - -int main(int argc, char **argv) -{ - -#ifdef RTAI - RT_TASK *task; - RTIME period; -#else - int error_code; -#endif - int i,j,aa; - void *status; - - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - -#ifndef RTAI - check_clock(); -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - -#ifdef RTAI - // make main thread LXRT soft realtime - task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); - - // start realtime timer and scheduler -#ifdef TIMER_ONESHOT_MODE - rt_set_oneshot_mode(); - start_rt_timer(0); - printf("started RTAI timer in oneshot mode\n"); -#else - rt_set_periodic_mode(); - period = start_rt_timer(nano2count(500000)); - printf("started RTAI timer with period %llu ns\n",count2nano(period)); -#endif - - printf("Init mutex\n"); - //mutex = rt_get_adr(nam2num("MUTEX")); - mutex = rt_sem_init(nam2num("MUTEX"), 1); - - if (mutex==0) { - printf("Error init mutex\n"); - exit(-1); - } else - printf("mutex=%p\n",mutex); - -#endif - - rt_sleep_ns(10*FRAME_PERIOD); - -#ifndef RTAI - pthread_attr_init (&attr_dlsch_threads); - pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE); - //attr_dlsch_threads.priority = 1; - sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_dlsch_threads, &sched_param_dlsch); - pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO); -#endif - -#ifdef RTAI - thread0 = rt_thread_create(eNB_thread, NULL, 100000000); -#else - error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL); - - if (error_code!= 0) { - printf("[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code); - return(error_code); - } else { - printf("[lte-softmodem.c] Allocate eNB_thread successful\n"); - } - -#endif - printf("eNB threads created\n"); - - - - // wait for end of program - printf("TYPE TO TERMINATE\n"); - - //getchar(); - while (oai_exit==0) { - - printf("eNB Frame %d, hw_slot %d (time %llu): period %llu, sleep time (avg/min/max/samples) %llu / %llu / %llu / %d, ratio %f\n",frame,slot,rt_get_time_ns(),DAQ_PERIOD,timing_info.time_avg, - timing_info.time_min,timing_info.time_max,timing_info.n_samples,(double)timing_info.time_avg/DAQ_PERIOD); - - - rt_sleep_ns(100*FRAME_PERIOD); - } - - // stop threads -#ifdef RTAI - rt_thread_join(thread0); -#else - pthread_join(thread0,&status); -#endif - -#ifdef RTAI - stop_rt_timer(); -#endif - - return 0; -} - diff --git a/targets/RT/USER/synctest.c b/targets/RT/USER/synctest.c deleted file mode 100644 index ff65231df1..0000000000 --- a/targets/RT/USER/synctest.c +++ /dev/null @@ -1,1318 +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 lte-softmodem.c -* \brief main program to control HW and scheduling -* \author R. Knopp, F. Kaltenberger -* \date 2012 -* \version 0.1 -* \company Eurecom -* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr -* \note -* \warning -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rt_wrapper.h" - -#include "PHY/types.h" -//#include "PHY/defs.h" -#include "openair0_lib.h" - -#include "UTIL/LOG/log.h" -#include "UTIL/LOG/vcd_signal_dumper.h" - -#if defined(ENABLE_ITTI) -# include "intertask_interface_init.h" -# include "timer.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# endif -#endif - -#ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" -#include "stats.h" -// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) -// at eNB 0, an UL scope for every UE -FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; -FD_lte_phy_scope_enb *form_enb[NUMBER_OF_UE_MAX]; -FD_stats_form *form_stats=NULL; -char title[255]; -unsigned char scope_enb_num_ue = 1; -#endif //XFORMS - -#ifdef EMOS -#include -#include - -//#define CHANSOUNDER_FIFO_SIZE 10485760 // 10 Mbytes FIFO -#define CHANSOUNDER_FIFO_SIZE 20971520 // 20 Mbytes FIFO -#define CHANSOUNDER_FIFO_MINOR 4 // minor of the FIFO device - this is /dev/rtf3 -#define CHANSOUNDER_FIFO_DEV "/dev/rtf4" -#endif - -#define TIMER_ONESHOT_MODE -#define FRAME_PERIOD 100000000ULL -#define DAQ_PERIOD 66667ULL -#define LTE_SLOTS_PER_FRAME 20 -#define RESAMPLING_FACTOR 2 -#define SAMPLES_PER_SLOT (15360/(1<stats_text, stats_buffer); - //rewind (UE_stats); - //fwrite (stats_buffer, 1, len, UE_stats); - - phy_scope_UE(form_ue[UE_id], - PHY_vars_UE_g[UE_id], - eNB_id, - UE_id,7); - - } else { - len = dump_eNB_stats (PHY_vars_eNB_g[0], stats_buffer, 0); - fl_set_object_label(form_stats->stats_text, stats_buffer); - - //rewind (eNB_stats); - //fwrite (stats_buffer, 1, len, eNB_stats); - for(UE_id=0; UE_id=5 - ret = gps_open("127.0.0.1","2947",gps_data); - - if (ret!=0) -#else - gps_data = gps_open("127.0.0.1","2947"); - - if (gps_data == NULL) -#endif - { - printf("[EMOS] Could not open GPS\n"); - //exit(-1); - } - -#if GPSD_API_MAJOR_VERSION>=4 - else if (gps_stream(gps_data, WATCH_ENABLE,NULL) != 0) -#else - else if (gps_query(gps_data, "w+x") != 0) -#endif - { - //sprintf(tmptxt,"Error sending command to GPS, gps_data = %x", gps_data); - printf("[EMOS] Error sending command to GPS\n"); - //exit(-1); - } else - printf("[EMOS] Opened GPS, gps_data=%p\n", gps_data); - - /* - if (UE_flag==0) - channel_buffer_size = sizeof(fifo_dump_emos_eNB); - else - channel_buffer_size = sizeof(fifo_dump_emos_UE); - */ - - // allocate memory for NO_FRAMES_DISK channes estimations - fifo2file_buffer = malloc(NO_ESTIMATES_DISK*channel_buffer_size); - fifo2file_ptr = fifo2file_buffer; - - if (fifo2file_buffer == NULL) { - printf("[EMOS] Cound not allocate memory for fifo2file_buffer\n"); - exit(EXIT_FAILURE); - } - - if ((fifo = open(CHANSOUNDER_FIFO_DEV, O_RDONLY)) < 0) { - fprintf(stderr, "[EMOS] Error opening the fifo\n"); - exit(EXIT_FAILURE); - } - - - time(&starttime_tmp); - localtime_r(&starttime_tmp,&starttime); - snprintf(dumpfile_name,1024,"/tmp/%s_data_%d%02d%02d_%02d%02d%02d.EMOS", - (UE_flag==0) ? "eNB" : "UE", - 1900+starttime.tm_year, starttime.tm_mon+1, starttime.tm_mday, starttime.tm_hour, starttime.tm_min, starttime.tm_sec); - - dumpfile_id = fopen(dumpfile_name,"w"); - - if (dumpfile_id == NULL) { - fprintf(stderr, "[EMOS] Error opening dumpfile %s\n",dumpfile_name); - exit(EXIT_FAILURE); - } - - - printf("[EMOS] starting dump, channel_buffer_size=%d ...\n",channel_buffer_size); - - while (!oai_exit) { - bytes = rtf_read_timed(fifo, fifo2file_ptr, channel_buffer_size,100); - - if (bytes<=0) - continue; - - /* - if (UE_flag==0) - printf("eNB: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_eNB*)fifo2file_ptr)->frame_tx,bytes); - else - printf("UE: count %d, frame %d, read: %d bytes from the fifo\n",counter, ((fifo_dump_emos_UE*)fifo2file_ptr)->frame_rx,bytes); - */ - - fifo2file_ptr += channel_buffer_size; - counter ++; - total_bytes += bytes; - - if ((counter%NO_ESTIMATES_DISK)==0) { - //reset stuff - fifo2file_ptr = fifo2file_buffer; - //counter = 0; - - //flush buffer to disk - if (fwrite(fifo2file_buffer, sizeof(char), NO_ESTIMATES_DISK*channel_buffer_size, dumpfile_id) != NO_ESTIMATES_DISK*channel_buffer_size) { - fprintf(stderr, "[EMOS] Error writing to dumpfile\n"); - exit(EXIT_FAILURE); - } - - /* - if (gps_data) - { - if (gps_poll(gps_data) != 0) { - printf("[EMOS] problem polling data from gps\n"); - } - else { - printf("[EMOS] lat %g, lon %g\n",gps_data->fix.latitude,gps_data->fix.longitude); - } - if (fwrite(&(gps_data->fix), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t)) - { - printf("[EMOS] Error writing to dumpfile, stopping recording\n"); - exit(EXIT_FAILURE); - } - } - else - { - printf("[EMOS] WARNING: No GPS data available, storing dummy packet\n"); - if (fwrite(&(dummy_gps_data), sizeof(char), sizeof(struct gps_fix_t), dumpfile_id) != sizeof(struct gps_fix_t)) - { - printf("[EMOS] Error writing to dumpfile, stopping recording\n"); - exit(EXIT_FAILURE); - } - } - */ - } - - if ((counter%2000)==0) - printf("[EMOS] count %d (%d sec), total bytes wrote %llu\n", counter, counter/2000, total_bytes); - } - - free(fifo2file_buffer); - fclose(dumpfile_id); - close(fifo); - - pthread_exit((void*) arg); - -} -#endif - -/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */ -static void *eNB_thread(void *arg) -{ -#ifdef RTAI - RT_TASK *task; - RTIME now; -#endif - unsigned char slot=0,last_slot, next_slot; - int hw_slot,frame=0; - unsigned int msg1; - unsigned int aa,slot_offset, slot_offset_F; - int diff; - int delay_cnt; - RTIME time_in, time_diff; - int mbox_target=0,mbox_current=0; - int i,ret; - int tx_offset; - int bytes; - -#ifdef RTAI - task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); - LOG_D(HW,"Started eNB thread (id %p)\n",task); -#ifndef TIMER_ONESHOT_MODE - now = rt_get_time(); - ret = rt_task_make_periodic(task, now, nano2count(500000LL)); - - if (ret!=0) - LOG_E(HW,"Problem with periodic timer\n"); - -#endif -#endif - -#ifdef HARD_RT - rt_make_hard_real_time(); -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - - timing_info.time_min = 100000000ULL; - timing_info.time_max = 0; - timing_info.time_avg = 0; - timing_info.n_samples = 0; - - while (!oai_exit) { - hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; - //LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]); - //this is the mbox counter where we should be - //mbox_target = ((((slot+1)%20)*15+1)>>1)%150; - mbox_target = mbox_bounds[slot]; - //this is the mbox counter where we are - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD) - if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround - diff = 150-mbox_current+mbox_target; - else if ((mbox_current<15) && (mbox_target>=135)) - diff = -150+mbox_target-mbox_current; - else - diff = mbox_target - mbox_current; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_ENB, slot); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_ENB, frame); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *((volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0])); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff); - - time_in = rt_get_time_ns(); - //LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in); - //LOG_D(HW,"eNB Frame %d, time %llu: sleeping for %llu (slot %d, hw_slot %d, diff %d, mbox %d, delay_cnt %d)\n", frame, time_in, diff*DAQ_PERIOD,slot,hw_slot,diff,((volatile unsigned int *)DAQ_MBOX)[0],delay_cnt); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1); -#ifdef TIMER_ONESHOT_MODE - //ret = rt_sleep_ns(DAQ_PERIOD * (slot%4==0?6:8)); - ret = rt_sleep_ns(500000); - - if (ret) - LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in); - -#else - rt_task_wait_period(); -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0); - - //hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15; - //LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns()); - - mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0]; - - if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround - diff = 150-mbox_current+mbox_target; - else if ((mbox_current<15) && (mbox_target>=135)) - diff = -150+mbox_target-mbox_current; - else - diff = mbox_target - mbox_current; - - - last_slot = (slot)%LTE_SLOTS_PER_FRAME; - - if (last_slot <0) - last_slot+=20; - - next_slot = (slot+3)%LTE_SLOTS_PER_FRAME; - - slot++; - - if (slot==20) { - slot=0; - frame++; - } - - if (frame==1000) - oai_exit=1; - -#if defined(ENABLE_ITTI) - itti_update_lte_time(frame, slot); -#endif - } - - LOG_D(HW,"eNB_thread: finished, ran %d times.\n",frame); - -#ifdef HARD_RT - rt_make_soft_real_time(); -#endif - - // clean task -#ifdef RTAI - rt_task_delete(task); -#endif - LOG_D(HW,"Task deleted. returning\n"); - return 0; -} - - -int main(int argc, char **argv) -{ - -#ifdef RTAI - RT_TASK *task; - RTIME period; -#endif - int i,j,aa; - void *status; - - /* - uint32_t rf_mode_max[4] = {55759,55759,55759,55759}; - uint32_t rf_mode_med[4] = {39375,39375,39375,39375}; - uint32_t rf_mode_byp[4] = {22991,22991,22991,22991}; - */ - uint32_t my_rf_mode = RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX; - uint32_t rf_mode_base = TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM; - uint32_t rf_mode[4] = {my_rf_mode,0,0,0}; - uint32_t rf_local[4] = {8255000,8255000,8255000,8255000}; // UE zepto - //{8254617, 8254617, 8254617, 8254617}; //eNB khalifa - //{8255067,8254810,8257340,8257340}; // eNB PETRONAS - - uint32_t rf_vcocal[4] = {910,910,910,910}; - uint32_t rf_vcocal_850[4] = {2015, 2015, 2015, 2015}; - uint32_t rf_rxdc[4] = {32896,32896,32896,32896}; - uint32_t rxgain[4] = {20,20,20,20}; - uint32_t txgain[4] = {20,20,20,20}; - - uint16_t Nid_cell = 0; - uint8_t cooperation_flag=0, transmission_mode=1, abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - - int c; - char do_forms=0; - unsigned int fd; - unsigned int tcxo = 114; - - int amp; - uint8_t prach_fmt; - int N_ZC; - - char rxg_fname[100]; - char txg_fname[100]; - char rflo_fname[100]; - char rfdc_fname[100]; - FILE *rxg_fd=NULL; - FILE *txg_fd=NULL; - FILE *rflo_fd=NULL; - FILE *rfdc_fd=NULL; - unsigned int rxg_max[4]= {133,133,133,133}, rxg_med[4]= {127,127,127,127}, rxg_byp[4]= {120,120,120,120}; - int tx_max_power=0; - - char line[1000]; - int l; - int ret, ant; - int ant_offset=0; - - int error_code; - char *itti_dump_file = NULL; - - const struct option long_options[] = { - {"calib-ue-rx", required_argument, NULL, 256}, - {"calib-ue-rx-med", required_argument, NULL, 257}, - {"calib-ue-rx-byp", required_argument, NULL, 258}, - {"debug-ue-prach", no_argument, NULL, 259}, - {"no-L2-connect", no_argument, NULL, 260}, - {NULL, 0, NULL, 0} - }; - - //mode = normal_txrx; - - - while ((c = getopt_long (argc, argv, "C:K:O:ST:UdF:V",long_options,NULL)) != -1) { - switch (c) { - case 'V': - ouput_vcd = 1; - break; - - case 'd': - do_forms=1; - break; - - case 'U': - UE_flag = 1; - break; - - case 'C': - carrier_freq[0] = atoi(optarg); - carrier_freq[1] = atoi(optarg); - carrier_freq[2] = atoi(optarg); - carrier_freq[3] = atoi(optarg); - break; - - case 'S': - fs4_test=1; - break; - - case 'T': - tcxo=atoi(optarg); - break; - - case 'K': -#if defined(ENABLE_ITTI) - itti_dump_file = strdup(optarg); -#else - printf("-K option is disabled when ENABLE_ITTI is not defined\n"); -#endif - break; - - case 'O': -#if defined(ENABLE_USE_MME) - EPC_MODE_ENABLED = 1; - - if (optarg == NULL) { /* No IP address provided: use localhost */ - memcpy(&EPC_MODE_MME_ADDRESS[0], "127.0.0.1", 10); - } else { - uint8_t ip_length = strlen(optarg) + 1; - memcpy(&EPC_MODE_MME_ADDRESS[0], optarg, - ip_length > 16 ? 16 : ip_length); - } - -#else - printf("You enabled mme mode without s1ap compiled...\n"); -#endif - break; - - case 'F': - sprintf(rxg_fname,"%srxg.lime",optarg); - rxg_fd = fopen(rxg_fname,"r"); - - if (rxg_fd) { - printf("Loading RX Gain parameters from %s\n",rxg_fname); - l=0; - - while (fgets(line, sizeof(line), rxg_fd)) { - if ((strlen(line)==0) || (*line == '#')) continue; //ignore empty or comment lines - else { - if (l==0) sscanf(line,"%d %d %d %d",&rxg_max[0],&rxg_max[1],&rxg_max[2],&rxg_max[3]); - - if (l==1) sscanf(line,"%d %d %d %d",&rxg_med[0],&rxg_med[1],&rxg_med[2],&rxg_med[3]); - - if (l==2) sscanf(line,"%d %d %d %d",&rxg_byp[0],&rxg_byp[1],&rxg_byp[2],&rxg_byp[3]); - - l++; - } - } - } else - printf("%s not found, running with defaults\n",rxg_fname); - - sprintf(txg_fname,"%stxg.lime",optarg); - txg_fd = fopen(txg_fname,"r"); - - if (txg_fd) { - printf("Loading TX Gain parameters from %s\n",txg_fname); - l=0; - - while (fgets(line, sizeof(line), txg_fd)) { - if ((strlen(line)==0) || (*line == '#')) { - continue; //ignore empty or comment lines - } else { - if (l==0) sscanf(line,"%d %d %d %d",&txgain[0],&txgain[1],&txgain[2],&txgain[3]); - - if (l==1) sscanf(line,"%d",&tx_max_power); - - l++; - } - } - } else - printf("%s not found, running with defaults\n",txg_fname); - - sprintf(rflo_fname,"%srflo.lime",optarg); - rflo_fd = fopen(rflo_fname,"r"); - - if (rflo_fd) { - printf("Loading RF LO parameters from %s\n",rflo_fname); - fscanf(rflo_fd,"%d %d %d %d",&rf_local[0],&rf_local[1],&rf_local[2],&rf_local[3]); - } else - printf("%s not found, running with defaults\n",rflo_fname); - - sprintf(rfdc_fname,"%srfdc.lime",optarg); - rfdc_fd = fopen(rfdc_fname,"r"); - - if (rfdc_fd) { - printf("Loading RF DC parameters from %s\n",rfdc_fname); - fscanf(rfdc_fd,"%d %d %d %d",&rf_rxdc[0],&rf_rxdc[1],&rf_rxdc[2],&rf_rxdc[3]); - } else - printf("%s not found, running with defaults\n",rfdc_fname); - - break; - - /* - case 256: - mode = rx_calib_ue; - rx_input_level_dBm = atoi(optarg); - printf("Running with UE calibration on (LNA max), input level %d dBm\n",rx_input_level_dBm); - break; - case 257: - mode = rx_calib_ue_med; - rx_input_level_dBm = atoi(optarg); - printf("Running with UE calibration on (LNA med), input level %d dBm\n",rx_input_level_dBm); - break; - case 258: - mode = rx_calib_ue_byp; - rx_input_level_dBm = atoi(optarg); - printf("Running with UE calibration on (LNA byp), input level %d dBm\n",rx_input_level_dBm); - break; - case 259: - mode = debug_prach; - break; - case 260: - mode = no_L2_connect; - break; - */ - default: - break; - } - } - - if (UE_flag==1) - printf("configuring for UE\n"); - else - printf("configuring for eNB\n"); - - //randominit (0); - //set_taus_seed (0); - - // initialize the log (see log.h for details) - logInit(); - -#if defined(ENABLE_ITTI) - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); - -# if defined(ENABLE_USE_MME) - - if (itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0) { - LOG_E(EMU, "Create task failed"); - LOG_D(EMU, "Initializing SCTP task interface: FAILED\n"); - return -1; - } - - if (itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(EMU, "Create task failed"); - LOG_D(EMU, "Initializing S1AP task interface: FAILED\n"); - return -1; - } - -# endif - - if (itti_create_task(TASK_L2L1, l2l1_task, NULL) < 0) { - LOG_E(EMU, "Create task failed"); - LOG_D(EMU, "Initializing L2L1 task interface: FAILED\n"); - return -1; - } - - // Handle signals until all tasks are terminated - // itti_wait_tasks_end(); -#endif - - if (ouput_vcd) { - if (UE_flag==1) - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); - else - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); - } - -#ifdef PDCP_USE_NETLINK - netlink_init(); -#endif - - // to make a graceful exit when ctrl-c is pressed - signal(SIGSEGV, signal_handler); - signal(SIGINT, signal_handler); - -#ifndef RTAI - check_clock(); -#endif - - g_log->log_component[HW].level = LOG_DEBUG; - g_log->log_component[HW].flag = LOG_HIGH; -#ifdef OPENAIR2 - g_log->log_component[PHY].level = LOG_INFO; -#else - g_log->log_component[PHY].level = LOG_INFO; -#endif - g_log->log_component[PHY].flag = LOG_HIGH; - g_log->log_component[MAC].level = LOG_INFO; - g_log->log_component[MAC].flag = LOG_HIGH; - g_log->log_component[RLC].level = LOG_INFO; - g_log->log_component[RLC].flag = LOG_HIGH; - g_log->log_component[PDCP].level = LOG_INFO; - g_log->log_component[PDCP].flag = LOG_HIGH; - g_log->log_component[OTG].level = LOG_INFO; - g_log->log_component[OTG].flag = LOG_HIGH; - g_log->log_component[RRC].level = LOG_INFO; - g_log->log_component[RRC].flag = LOG_HIGH; - - - // Initialize card - ret = openair0_open(); - - if ( ret != 0 ) { - if (ret == -1) - printf("Error opening /dev/openair0"); - - if (ret == -2) - printf("Error mapping bigshm"); - - if (ret == -3) - printf("Error mapping RX or TX buffer"); - - return(ret); - } - - printf ("Detected %d number of cards, %d number of antennas.\n", openair0_num_detected_cards, openair0_num_antennas[card]); - - p_exmimo_config = openair0_exmimo_pci[card].exmimo_config_ptr; - p_exmimo_id = openair0_exmimo_pci[card].exmimo_id_ptr; - - printf("Card %d: ExpressMIMO %d, HW Rev %d, SW Rev 0x%d\n", card, p_exmimo_id->board_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev); - - if (p_exmimo_id->board_swrev>=BOARD_SWREV_CNTL2) - p_exmimo_config->framing.eNB_flag = 0; - else - p_exmimo_config->framing.eNB_flag = !UE_flag; - - p_exmimo_config->framing.tdd_config = DUPLEXMODE_FDD + TXRXSWITCH_LSB; - - for (ant=0; ant<4; ant++) - p_exmimo_config->framing.resampling_factor[ant] = RESAMPLING_FACTOR; - - /* - for (ant=0;antnb_antennas_tx,frame_parms->nb_antennas_rx);ant++) - p_exmimo_config->rf.rf_mode[ant] = rf_mode_base; - for (ant=0;antnb_antennas_tx;ant++) - p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX); - for (ant=0;antnb_antennas_rx;ant++) - p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX); - for (ant=max(frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx);ant<4;ant++) { - p_exmimo_config->rf.rf_mode[ant] = 0; - carrier_freq[ant] = 0; //this turns off all other LIMEs - } - */ - - ant_offset = 0; - - for (ant=0; ant<4; ant++) { - if (ant==ant_offset) { - //if (1) { - p_exmimo_config->rf.rf_mode[ant] = rf_mode_base; - //p_exmimo_config->rf.rf_mode[ant] += (TXEN + DMAMODE_TX); - p_exmimo_config->rf.rf_mode[ant] += (RXEN + DMAMODE_RX); - } else { - p_exmimo_config->rf.rf_mode[ant] = 0; - carrier_freq[ant] = 0; //this turns off all other LIMEs - } - } - - for (ant = 0; ant<4; ant++) { - p_exmimo_config->rf.do_autocal[ant] = 1; - p_exmimo_config->rf.rf_freq_rx[ant] = carrier_freq[ant]; - p_exmimo_config->rf.rf_freq_tx[ant] = carrier_freq[ant]; - p_exmimo_config->rf.rx_gain[ant][0] = rxgain[ant]; - p_exmimo_config->rf.tx_gain[ant][0] = txgain[ant]; - - p_exmimo_config->rf.rf_local[ant] = rf_local[ant]; - p_exmimo_config->rf.rf_rxdc[ant] = rf_rxdc[ant]; - - if ((carrier_freq[ant] >= 850000000) && (carrier_freq[ant] <= 865000000)) { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal_850[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = DD_TDD; - } else if ((carrier_freq[ant] >= 1900000000) && (carrier_freq[ant] <= 2000000000)) { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = B19G_TDD; - } else { - p_exmimo_config->rf.rf_vcocal[ant] = rf_vcocal[ant]; - p_exmimo_config->rf.rffe_band_mode[ant] = 0; - } - - p_exmimo_config->rf.rffe_gain_txlow[ant] = 31; - p_exmimo_config->rf.rffe_gain_txhigh[ant] = 31; - p_exmimo_config->rf.rffe_gain_rxfinal[ant] = 52; - p_exmimo_config->rf.rffe_gain_rxlow[ant] = 31; - } - - - number_of_cards = openair0_num_detected_cards; - /* - if (p_exmimo_id->board_exmimoversion==1) //ExpressMIMO1 - openair_daq_vars.timing_advance = 138; - else //ExpressMIMO2 - openair_daq_vars.timing_advance = 0; - */ - - openair0_dump_config(card); - - printf("EXMIMO_CONFIG: rf_mode 0x %x %x %x %x, [0]: TXRXEn %d, TXLPFEn %d, TXLPF %d, RXLPFEn %d, RXLPF %d, RFBB %d, LNA %d, LNAGain %d, RXLPFMode %d, SWITCH %d, rf_rxdc %d, rf_local %d, rf_vcocal %d\n", - p_exmimo_config->rf.rf_mode[0], - p_exmimo_config->rf.rf_mode[1], - p_exmimo_config->rf.rf_mode[2], - p_exmimo_config->rf.rf_mode[3], - (p_exmimo_config->rf.rf_mode[0]&3), // RXen+TXen - (p_exmimo_config->rf.rf_mode[0]&4)>>2, //TXLPFen - (p_exmimo_config->rf.rf_mode[0]&TXLPFMASK)>>3, //TXLPF - (p_exmimo_config->rf.rf_mode[0]&128)>>7, //RXLPFen - (p_exmimo_config->rf.rf_mode[0]&RXLPFMASK)>>8, //TXLPF - (p_exmimo_config->rf.rf_mode[0]&RFBBMASK)>>16, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&LNAMASK)>>12, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&LNAGAINMASK)>>14, // RFBB mode - (p_exmimo_config->rf.rf_mode[0]&RXLPFMODEMASK)>>19, // RXLPF mode - (p_exmimo_config->framing.tdd_config&TXRXSWITCH_MASK)>>1, // Switch mode - p_exmimo_config->rf.rf_rxdc[0], - p_exmimo_config->rf.rf_local[0], - p_exmimo_config->rf.rf_vcocal[0]); - - for (ant=0; ant<4; ant++) - p_exmimo_config->rf.do_autocal[ant] = 0; - -#ifdef EMOS - error_code = rtf_create(CHANSOUNDER_FIFO_MINOR,CHANSOUNDER_FIFO_SIZE); - - if (error_code==0) - printf("[OPENAIR][SCHED][INIT] Created EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR); - else if (error_code==ENODEV) - printf("[OPENAIR][SCHED][INIT] Problem: EMOS FIFO %d is greater than or equal to RTF_NO\n",CHANSOUNDER_FIFO_MINOR); - else if (error_code==ENOMEM) - printf("[OPENAIR][SCHED][INIT] Problem: cannot allocate memory for EMOS FIFO %d\n",CHANSOUNDER_FIFO_MINOR); - else - printf("[OPENAIR][SCHED][INIT] Problem creating EMOS FIFO %d, error_code %d\n",CHANSOUNDER_FIFO_MINOR,error_code); - -#endif - - mlockall(MCL_CURRENT | MCL_FUTURE); - -#ifdef RTAI - // make main thread LXRT soft realtime - task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); - - // start realtime timer and scheduler -#ifdef TIMER_ONESHOT_MODE - rt_set_oneshot_mode(); - start_rt_timer(0); - printf("started RTAI timer inoneshot mode\n"); -#else - rt_set_periodic_mode(); - period = start_rt_timer(nano2count(500000)); - printf("started RTAI timer with period %llu ns\n",count2nano(period)); -#endif - - printf("Init mutex\n"); - //mutex = rt_get_adr(nam2num("MUTEX")); - mutex = rt_sem_init(nam2num("MUTEX"), 1); - - if (mutex==0) { - printf("Error init mutex\n"); - exit(-1); - } else - printf("mutex=%p\n",mutex); - -#endif - - DAQ_MBOX = (volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0]; - - // this starts the DMA transfers - if (UE_flag!=1) - openair0_start_rt_acquisition(card); - - -#ifdef XFORMS - - if (do_forms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - form_stats = create_form_stats_form(); - - if (UE_flag==1) { - form_ue[UE_id] = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } else { - for(UE_id=0; UE_idlte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - } - } - - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - - if (UE_flag==0) { - for (UE_id=0; UE_idbutton_0,1); - fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic ON"); - } else { - fl_set_button(form_enb[UE_id]->button_0,0); - fl_set_object_label(form_enb[UE_id]->button_0,"DL Traffic OFF"); - } - } - } else { - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } - } - - ret = pthread_create(&thread2, NULL, scope_thread, NULL); - printf("Scope thread created, ret=%d\n",ret); - } - -#endif - -#ifdef EMOS - ret = pthread_create(&thread3, NULL, emos_thread, NULL); - printf("EMOS thread created, ret=%d\n",ret); -#endif - - rt_sleep_ns(10*FRAME_PERIOD); - -#ifndef RTAI - pthread_attr_init (&attr_dlsch_threads); - pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE); - //attr_dlsch_threads.priority = 1; - sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY; - pthread_attr_setschedparam (&attr_dlsch_threads, &sched_param_dlsch); - pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO); -#endif - - // start the main thread - if (UE_flag == 1) { - /* - #ifdef RTAI - thread1 = rt_thread_create(UE_thread, NULL, 100000000); - #else - error_code = pthread_create(&thread1, &attr_dlsch_threads, UE_thread, NULL); - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return(error_code); - } - else { - LOG_D(HW,"[lte-softmodem.c] Allocate UE_thread successful\n"); - } - #endif - #ifdef DLSCH_THREAD - init_rx_pdsch_thread(); - rt_sleep_ns(FRAME_PERIOD/10); - init_dlsch_threads(); - #endif - printf("UE threads created\n"); - */ - } else { -#ifdef RTAI - thread0 = rt_thread_create(eNB_thread, NULL, 100000000); -#else - error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code); - return(error_code); - } else { - LOG_D(HW,"[lte-softmodem.c] Allocate eNB_thread successful\n"); - } - -#endif -#ifdef ULSCH_THREAD - init_ulsch_threads(); -#endif - printf("eNB threads created\n"); - } - - - // wait for end of program - printf("TYPE TO TERMINATE\n"); - - //getchar(); - while (oai_exit==0) - rt_sleep_ns(FRAME_PERIOD); - - // stop threads -#ifdef XFORMS - printf("waiting for XFORMS thread\n"); - - if (do_forms==1) { - pthread_join(thread2,&status); - fl_hide_form(form_stats->stats_form); - fl_free_form(form_stats->stats_form); - - if (UE_flag==1) { - fl_hide_form(form_ue[UE_id]->lte_phy_scope_ue); - fl_free_form(form_ue[UE_id]->lte_phy_scope_ue); - } else { - for(UE_id=0; UE_idlte_phy_scope_enb); - fl_free_form(form_enb[UE_id]->lte_phy_scope_enb); - } - } - } - -#endif - - printf("stopping MODEM threads\n"); - - // cleanup - if (UE_flag == 1) { - /* - #ifdef RTAI - rt_thread_join(thread1); - #else - pthread_join(thread1,&status); - #endif - #ifdef DLSCH_THREAD - cleanup_dlsch_threads(); - cleanup_rx_pdsch_thread(); - #endif - */ - } else { -#ifdef RTAI - rt_thread_join(thread0); -#else - pthread_join(thread0,&status); -#endif -#ifdef ULSCH_THREAD - cleanup_ulsch_threads(); -#endif - } - -#ifdef OPENAIR2 - //cleanup_pdcp_thread(); -#endif - -#ifdef RTAI - stop_rt_timer(); -#endif - - printf("stopping card\n"); - openair0_stop(card); - printf("closing openair0_lib\n"); - openair0_close(); - -#ifdef EMOS - printf("waiting for EMOS thread\n"); - pthread_cancel(thread3); - pthread_join(thread3,&status); -#endif - -#ifdef EMOS - error_code = rtf_destroy(CHANSOUNDER_FIFO_MINOR); - printf("[OPENAIR][SCHED][CLEANUP] EMOS FIFO closed, error_code %d\n", error_code); -#endif - - if (ouput_vcd) - VCD_SIGNAL_DUMPER_CLOSE(); - - logClean(); - - return 0; -} - -void test_config(int card, int ant, unsigned int rf_mode, int UE_flag) -{ - p_exmimo_config->framing.eNB_flag = !UE_flag; - p_exmimo_config->framing.tdd_config = 0; - p_exmimo_config->framing.resampling_factor[ant] = 2; - - p_exmimo_config->rf.rf_freq_rx[ant] = 1907600000; - p_exmimo_config->rf.rf_freq_tx[ant] = 1907600000;; - p_exmimo_config->rf.rx_gain[ant][0] = 20; - p_exmimo_config->rf.tx_gain[ant][0] = 10; - p_exmimo_config->rf.rf_mode[ant] = rf_mode; - - p_exmimo_config->rf.rf_local[ant] = build_rflocal(20,25,26,04); - p_exmimo_config->rf.rf_rxdc[ant] = build_rfdc(128, 128); - p_exmimo_config->rf.rf_vcocal[ant] = (0xE<<6) + 0xE; -} - -/* -void setup_ue_buffers(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, int carrier) { - - int i; - if (phy_vars_ue) { - - if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) { - printf("RX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) { - printf("TX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - // replace RX signal buffers with mmaped HW versions - for (i=0;inb_antennas_rx;i++) { - free(phy_vars_ue->lte_ue_common_vars.rxdata[i]); - phy_vars_ue->lte_ue_common_vars.rxdata[i] = (int32_t*) openair0_exmimo_pci[card].adc_head[i+carrier]; - - - printf("rxdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.rxdata[i]); - } - for (i=0;inb_antennas_tx;i++) { - free(phy_vars_ue->lte_ue_common_vars.txdata[i]); - phy_vars_ue->lte_ue_common_vars.txdata[i] = (int32_t*) openair0_exmimo_pci[card].dac_head[i+carrier]; - - printf("txdata[%d] @ %p\n",i,phy_vars_ue->lte_ue_common_vars.txdata[i]); - } - } -} - -void setup_eNB_buffers(PHY_VARS_eNB *phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms, int carrier) { - - int i,j; - - if (phy_vars_eNB) { - if ((frame_parms->nb_antennas_rx>1) && (carrier>0)) { - printf("RX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - if ((frame_parms->nb_antennas_tx>1) && (carrier>0)) { - printf("TX antennas > 1 and carrier > 0 not possible\n"); - exit(-1); - } - - // replace RX signal buffers with mmaped HW versions - for (i=0;inb_antennas_rx;i++) { - free(phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]); - phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i] = (int32_t*) openair0_exmimo_pci[card].adc_head[i+carrier]; - - printf("rxdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i]); - for (j=0;j<16;j++) { - printf("rxbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j]); - phy_vars_eNB->lte_eNB_common_vars.rxdata[0][i][j] = 16-j; - } - } - for (i=0;inb_antennas_tx;i++) { - free(phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]); - phy_vars_eNB->lte_eNB_common_vars.txdata[0][i] = (int32_t*) openair0_exmimo_pci[card].dac_head[i+carrier]; - - printf("txdata[%d] @ %p\n",i,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i]); - for (j=0;j<16;j++) { - printf("txbuffer %d: %x\n",j,phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j]); - phy_vars_eNB->lte_eNB_common_vars.txdata[0][i][j] = 16-j; - } - } - } -} -*/ diff --git a/targets/SIMU/USER/Makefile b/targets/SIMU/USER/Makefile index 7de5f9382f..ec5f5eb0cc 100644 --- a/targets/SIMU/USER/Makefile +++ b/targets/SIMU/USER/Makefile @@ -29,13 +29,12 @@ endif CFLAGS += -Wpointer-sign -CFLAGS += -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 $(CPUFLAGS) -I/usr/include/X11 #-Wno-packed-bitfield-compat +CFLAGS += -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 $(CPUFLAGS) -I/usr/include/X11 #-Wno-packed-bitfield-compat ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES -CFLAGS += -DOPENAIR_LTE -DPUCCH #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE -CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 -DPHY_ABSTRACTION #-DPHY_ABSTRACTION_UL #-DRLC_UM_TEST_TRAFFIC=1 -CFLAGS += -DNEW_FFT +CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE +CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 #-DRLC_UM_TEST_TRAFFIC=1 #CFLAGS += -DLLR8 CFLAGS += -DPACKAGE_NAME='"oaisim"' @@ -48,15 +47,6 @@ DISABLE_XER_PRINT=0 MSG_PRINT=1 endif -ifndef OPENAIR_EMU -export OPENAIR_EMU=1 -CFLAGS += -DOAISIM -endif - -ifdef EMOS -CFLAGS+=-DEMOS -endif - ifeq ($(LOCALIZATION), 1) CFLAGS += -DLOCALIZATION endif @@ -141,8 +131,6 @@ CFLAGS += -DSTOP_ON_IP_TRAFFIC_OVERLOAD endif -ifeq ($(MIH_C_MEDIEVAL_EXTENSIONS), 1) -CFLAGS += -DMIH_C_MEDIEVAL_EXTENSIONS ifeq ($(USE_3GPP_ADDR_AS_LINK_ADDR), 1) CFLAGS += -DUSE_3GPP_ADDR_AS_LINK_ADDR endif @@ -179,7 +167,7 @@ ifdef OAI_NW_DRIVER_TYPE_ETHERNET CFLAGS+=-DOAI_NW_DRIVER_TYPE_ETHERNET endif -CFLAGS += -DENABLE_FXP -DOAI_EMU -DENABLE_USE_CPU_EXECUTION_TIME +CFLAGS += -DENABLE_USE_CPU_EXECUTION_TIME ifndef DISABLE_XER_PRINT CFLAGS += -DXER_PRINT endif @@ -272,7 +260,7 @@ endif # Check if libpgm is installed and use it if found instead of the unreliable # multicast ifeq ($(PGM_FOUND), 1) -CFLAGS += $(PGM_CFLAGS) -DENABLE_PGM_TRANSPORT +CFLAGS += $(PGM_CFLAGS) LIBS += $(PGM_LIBS) endif diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index 91fc1cd059..b31c47ba95 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -403,9 +403,6 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM { int32_t **txdata,**rxdata; -#ifdef PHY_ABSTRACTION_UL - int32_t att_eNB_id=-1; -#endif uint8_t UE_id=0; uint8_t nb_antennas_rx = UE2RU[0][0][CC_id]->nb_rx; // number of rx antennas at eNB @@ -418,14 +415,6 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM uint8_t hold_channel=0; -#ifdef PHY_ABSTRACTION_UL - double min_path_loss=-200; - uint16_t ul_nb_rb=0 ; - uint16_t ul_fr_rb=0; - int ulnbrb2 ; - int ulfrrb2 ; - uint8_t harq_pid; -#endif double s_re0[30720]; double s_re1[30720]; double *s_re[2]; @@ -450,38 +439,6 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM r_im0[1] = r_im01; if (abstraction_flag!=0) { -#ifdef PHY_ABSTRACTION_UL - // wire this to 0 until we figure this out - int eNB_id=0; - - for (UE_id=0; UE_idN_RB_UL,frame_parms->N_RB_UL*12+1); - - // REceived power at the eNB - rx_pwr = signal_energy_fp2(UE2RU[UE_id][eNB_id][CC_id]->ch[0], - UE2RU[UE_id][eNB_id][CC_id]->channel_length)*UE2RU[UE_id][att_eNB_id][CC_id]->channel_length; // calculate the rx power at the eNB - } - - // write_output("SINRch.m","SINRch",PHY_vars_eNB_g[att_eNB_id]->sinr_dB_eNB,frame_parms->N_RB_UL*12+1,1,1); - if(subframe>1 && subframe <5) { - harq_pid = subframe2harq_pid(frame_parms,frame,subframe); - ul_nb_rb = RC.eNB[att_eNB_id][CC_id].ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->nb_rb; - ul_fr_rb = RC.eNB[att_eNB_id][CC_id].ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->first_rb; - } - - if(ul_nb_rb>1 && (ul_fr_rb < 25 && ul_fr_rb > -1)) { - number_rb_ul = ul_nb_rb; - first_rbUL = ul_fr_rb; - init_snr_up(UE2RU[UE_id][att_eNB_id][CC_id],enb_data[att_eNB_id], ue_data[UE_id],PHY_vars_eNB_g[att_eNB_id][CC_id]->sinr_dB,&PHY_vars_UE_g[att_eNB_id][CC_id]->N0,ul_nb_rb,ul_fr_rb); - - } - } //UE_id - -#else - -#endif } else { //without abstraction pthread_mutex_lock(&UE_output_mutex[ru_id]); diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 778f250a78..ae139b797f 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1358,9 +1358,6 @@ void init_ocm(void) if (abstraction_flag) { get_beta_map(); -#ifdef PHY_ABSTRACTION_UL - get_beta_map_up(); -#endif get_MIESM_param(); //load_pbch_desc(); @@ -1566,117 +1563,6 @@ void update_ocm() void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime) { -#if defined(USER_MODE) && defined(OAI_EMU) - - //int rrc_state=0; - - if (oai_emulation.info.otg_enabled ==1 ) { - - int dst_id, app_id; - Packet_otg_elt_t *otg_pkt; - - for (dst_id = 0; dst_id < NUMBER_OF_UE_MAX; dst_id++) { - for_times += 1; - - // generate traffic if the ue is rrc reconfigured state - //if ((rrc_state=mac_eNB_get_rrc_status(enb_module_idP, dst_id)) > 2 /*RRC_CONNECTED*/ ) { - if (mac_eNB_get_rrc_status(enb_module_idP, oai_emulation.info.eNB_ue_module_id_to_rnti[enb_module_idP][dst_id]) > 2 ){ - if_times += 1; - - for (app_id=0; app_idotg_pkt).sdu_buffer = (uint8_t*) packet_gen(enb_module_idP, dst_id + NB_eNB_INST, app_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); - - if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { - otg_times += 1; - (otg_pkt->otg_pkt).rb_id = DTCH-2; // app could be binded to a given DRB - (otg_pkt->otg_pkt).module_id = enb_module_idP; - (otg_pkt->otg_pkt).dst_id = dst_id; - (otg_pkt->otg_pkt).is_ue = 0; - (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_DATA; - //Adding the packet to the OTG-PDCP buffer - pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP])); - LOG_D(EMU,"[eNB %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d for app id %d \n", - (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id, app_id); - } else { - free(otg_pkt); - otg_pkt=NULL; - } - } - } - } - -#if defined(Rel10) || defined(Rel14) - mbms_service_id_t service_id; - mbms_session_id_t session_id; - rb_id_t rb_id; - - // MBSM multicast traffic - if (ctime >= 500 ) {// only generate when UE can receive MTCH (need to control this value) - for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount - for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH - if (pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].instanciated_instance == TRUE) { // this service/session is configured - - otg_pkt = malloc (sizeof(Packet_otg_elt_t)); - // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n", service_id, session_id, service_id*maxSessionPerPMCH + session_id); - rb_id = pdcp_mbms_array_eNB[enb_module_idP][service_id][session_id].rb_id; - (otg_pkt->otg_pkt).sdu_buffer = (uint8_t*) packet_gen_multicast(enb_module_idP, session_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); - - if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { - (otg_pkt->otg_pkt).rb_id = rb_id; - (otg_pkt->otg_pkt).module_id = enb_module_idP; - (otg_pkt->otg_pkt).dst_id = session_id; - (otg_pkt->otg_pkt).is_ue = FALSE; - //Adding the packet to the OTG-PDCP buffer - (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; - pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[enb_module_idP])); - LOG_D(EMU, "[eNB %d] ADD packet (%p) multicast to OTG buffer for dst %d on rb_id %d\n", - (otg_pkt->otg_pkt).module_id, otg_pkt, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); - } else { - //LOG_I(EMU, "OTG returns null \n"); - free(otg_pkt); - otg_pkt=NULL; - } - - - // old version - /* // MBSM multicast traffic - #if defined(Rel10) || defined(Rel14) - if (frame >= 46) {// only generate when UE can receive MTCH (need to control this value) - for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount - for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH - // LOG_I(OTG,"DUY:frame %d, pdcp_mbms_array[module_id][rb_id].instanciated_instance is %d\n",frame,pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].instanciated_instance); - if ((pdcp_mbms_array[module_idP][service_id*maxSessionPerPMCH + session_id].instanciated_instance== module_idP + 1) && (eNB_flag == 1)){ // this service/session is configured - // LOG_T(OTG,"multicast packet gen for (service/mch %d, session/lcid %d)\n", service_id, session_id); - // Duy add - LOG_I(OTG, "frame %d, multicast packet gen for (service/mch %d, session/lcid %d, rb_id %d)\n",frame, service_id, session_id,service_id*maxSessionPerPMCH + session_id); - // end Duy add - rb_id = pdcp_mbms_array[module_id][service_id*maxSessionPerPMCH + session_id].rb_id; - otg_pkt=(uint8_t*) packet_gen_multicast(module_idP, session_id, ctime, &pkt_size); - if (otg_pkt != NULL) { - LOG_D(OTG,"[eNB %d] sending a multicast packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", eNB_index, module_idP, rb_id, module_idP, session_id, pkt_size); - pdcp_data_req(module_id, frame, eNB_flag, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, pkt_size, otg_pkt,PDCP_TM); - free(otg_pkt); - } - } - } - } - } // end multicast traffic - #endif - */ - - - } - } - } - - } // end multicast traffic - -#endif - } - -#else #if 0 // defined(EXMIMO) || defined(OAI_USRP) if (otg_enabled==1) { ctime = frame * 100; @@ -1703,57 +1589,11 @@ void update_otg_eNB(module_id_t enb_module_idP, unsigned int ctime) } } } - -#endif #endif } void update_otg_UE(module_id_t ue_mod_idP, unsigned int ctime) { -#if defined(USER_MODE) && defined(OAI_EMU) - - int app_id; - if (oai_emulation.info.otg_enabled ==1 ) { - module_id_t dst_id, src_id; //dst_id = eNB_index - module_id_t module_id = ue_mod_idP+NB_eNB_INST; - - src_id = module_id; - - for (dst_id=0; dst_id 2 /*RRC_CONNECTED*/) { - for (app_id=0; app_idotg_pkt).sdu_buffer = (uint8_t*) packet_gen(src_id, dst_id, app_id, ctime, &((otg_pkt->otg_pkt).sdu_buffer_size)); - - if ((otg_pkt->otg_pkt).sdu_buffer != NULL) { - (otg_pkt->otg_pkt).rb_id = DTCH-2; - (otg_pkt->otg_pkt).module_id = module_id; - (otg_pkt->otg_pkt).dst_id = dst_id; - (otg_pkt->otg_pkt).is_ue = 1; - //Adding the packet to the OTG-PDCP buffer - (otg_pkt->otg_pkt).mode = PDCP_TRANSMISSION_MODE_DATA; - pkt_list_add_tail_eurecom(otg_pkt, &(otg_pdcp_buffer[module_id])); - LOG_D(EMU, "[UE %d] ADD pkt to OTG buffer with size %d for dst %d on rb_id %d \n", - (otg_pkt->otg_pkt).module_id, otg_pkt->otg_pkt.sdu_buffer_size, (otg_pkt->otg_pkt).dst_id,(otg_pkt->otg_pkt).rb_id); - } else { - free(otg_pkt); - otg_pkt=NULL; - } - } - } - } - } - -#endif } #endif diff --git a/targets/SIMU/USER/sinr_sim.c b/targets/SIMU/USER/sinr_sim.c index 522f4147ce..7c752ce432 100644 --- a/targets/SIMU/USER/sinr_sim.c +++ b/targets/SIMU/USER/sinr_sim.c @@ -475,70 +475,6 @@ void init_snr(channel_desc_t* eNB2UE, node_desc_t *enb_data, node_desc_t *ue_dat }//switch }//function ends -#ifdef PHY_ABSTRACTION_UL -void init_snr_up(channel_desc_t* UE2eNB, node_desc_t *enb_data, node_desc_t *ue_data, double* sinr_dB, double* N0,uint16_t nb_rb,uint16_t fr_rb) -{ - - int return_value; - double thermal_noise; - int count; - int aarx; - - // nb_rb = phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb; - /* Thermal noise is calculated using 10log10(K*T*B) K = Boltzmann's constant T = room temperature B = bandwidth */ - thermal_noise = -174 + 10*log10(UE2eNB->sampling_rate*1e6); //value in dBm - *N0 = thermal_noise + enb_data->rx_noise_level;//? all the element have the same noise level????? - double lambda ; - double residual; - double sinrlin; - double residual_db; - residual = 0 ; - int ccc; - /* - for (count = (fr_rb*12) ; count < (12 * (fr_rb+nb_rb)); count++) - { - residual += ( 1 / ( pow((UE2eNB -> chF[0][count].x),2) + pow((UE2eNB -> chF[0][count].y),2))); - } - *///sinreff(nn) = ((sum((1/p).*(snrm(nn,:)./(snrm(nn,:)+1)),2).^(-1) )-1).^-1; - - sinrlin = 0 ; - lambda = 0; - - ////First calculate SINRs of subcarriers just like OFDM - for (count = (fr_rb*12) ; count < (12 * (fr_rb+nb_rb)); count++) { - sinr_dB[count] = ue_data->tx_power_dBm - + UE2eNB->path_loss_dB - - (thermal_noise + enb_data->rx_noise_level) - + 10 * log10 (pow(UE2eNB->chF[0][count].x, 2) - + pow(UE2eNB->chF[0][count].y, 2)); - - - } - - //Then apply formula : - if(nb_rb > 0) { - //calculate lambdas and fill the same with all but just use one of them when necessary for abstraction - for (count = fr_rb*12; count < (12 * (fr_rb+nb_rb)); count++) { - sinrlin = pow((sinr_dB[count]/10),10); // convert SINR to linear - lambda += (sinrlin / (sinrlin + 1)) ; - } - - for (count = fr_rb*12; count < (12 * (fr_rb+nb_rb)); count++) { - sinr_dB[count] = pow(lambda,2) /(((nb_rb)*lambda)-pow(lambda,2)) ; - sinr_dB[count] = 10*log10(sinr_dB[count]) ; //save it in db - } - - printf("tx_power %g, path_loss %g, sinr_dB[0] %g\n",ue_data->tx_power_dBm ,UE2eNB->path_loss_dB,sinr_dB[count-1]); - - for (ccc = 0; ccc < 301 ; ccc++ ) { - SINRpost_eff[ccc] = 0; - SINRpost_eff[ccc] = sinr_dB[ccc]; - } - } -}//function ends - -#endif - void calculate_sinr(channel_desc_t* eNB2UE, node_desc_t *enb_data, node_desc_t *ue_data, double *sinr_dB, uint16_t nb_rb) { @@ -737,60 +673,7 @@ void get_MIESM_param() free(file_path); } -#ifdef PHY_ABSTRACTION_UL -void get_beta_map_up() -{ - char *file_path = NULL; - int table_len = 0; - int mcs = 0; - char *sinr_bler; - char buffer[1000]; - FILE *fp; - file_path = (char*) malloc(512); - - for (mcs = 0; mcs < MCS_COUNT; mcs++) { - sprintf(file_path,"%s/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/awgn_abst/awgn_snr_bler_mcs%d_up.csv",getenv("OPENAIR1_DIR"),mcs); - fp = fopen(file_path,"r"); - - if (fp == NULL) { - LOG_W(OCM,"ERROR: Unable to open the file %s, try an alternative path\n", file_path); - memset(file_path, 0, 512); - sprintf(file_path,"AWGN/awgn_snr_bler_mcs%d.csv",mcs); - LOG_I(OCM,"Opening the alternative path %s\n", file_path); - fp = fopen(file_path,"r"); - - if (fp == NULL) { - LOG_E(OCM,"ERROR: Unable to open the file %s, exisitng\n", file_path); - exit(-1); - } - } - - // else { - fgets(buffer, 1000, fp); - table_len=0; - - while (!feof(fp)) { - sinr_bler = strtok(buffer, ","); - sinr_bler_map_up[mcs][0][table_len] = atof(sinr_bler); - sinr_bler = strtok(NULL,","); - sinr_bler_map_up[mcs][1][table_len] = atof(sinr_bler); - table_len++; - fgets(buffer, 1000, fp); - } - - fclose(fp); - // } - LOG_D(OCM,"Print the table for mcs %d\n",mcs); - - for (table_len = 0; table_len < 16; table_len++) - LOG_D(OCM,"%lf %lf \n ",sinr_bler_map_up[mcs][0][table_len],sinr_bler_map_up[mcs][1][table_len]); - } - - free(file_path); -} - -#endif diff --git a/targets/TEST/AT_COMMANDS/Makefile b/targets/TEST/AT_COMMANDS/Makefile index 2939b30c01..fc5f550329 100755 --- a/targets/TEST/AT_COMMANDS/Makefile +++ b/targets/TEST/AT_COMMANDS/Makefile @@ -6,7 +6,7 @@ OPENAIR2_TOP = $(OPENAIR2_DIR) OPENAIR3_TOP = $(OPENAIR3_DIR) OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -m32 -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 +CFLAGS += -m32 -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES @@ -23,8 +23,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION #-DEMIT_ASN_DEBUG=1 - #include $(OPENAIR1_DIR)/PHY/Makefile.inc #include $(OPENAIR1_DIR)/SCHED/Makefile.inc diff --git a/targets/TEST/OAI/case01.py b/targets/TEST/OAI/case01.py index cdc3bd9eb4..9595f7e35d 100644 --- a/targets/TEST/OAI/case01.py +++ b/targets/TEST/OAI/case01.py @@ -246,7 +246,7 @@ def execute(oai, user, pw, host, logfile,logdir,debug,timeout): log.start() test = '14' name = 'Compile oai.rel8.itti.ral.make' - conf = 'make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel8=1' + conf = 'make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel8=1' trace = logdir + '/log_' + case + test + '.txt;' tee = ' 2>&1 | tee ' + trace diag = 'check the compilation errors for ITTI Rel8' @@ -254,7 +254,7 @@ def execute(oai, user, pw, host, logfile,logdir,debug,timeout): oai.send('make cleanall;') oai.send('make cleanasn1;') oai.send('rm -f ./oaisim.rel8.itti.ral.'+host) - oai.send_expect_false('make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel8=1 -j4' + tee, makerr1, timeout) + oai.send_expect_false('make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel8=1 -j4' + tee, makerr1, timeout) oai.send('cp ./oaisim ./oaisim.rel8.itti.ral.'+host) except log.err, e: log.fail(case, test, name, conf, e.value, diag, logfile,trace) @@ -265,7 +265,7 @@ def execute(oai, user, pw, host, logfile,logdir,debug,timeout): log.start() test = '15' name = 'Compile oai.rel10.itti.ral.make' - conf = 'make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel10=1' + conf = 'make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel10=1' trace = logdir + '/log_' + case + test + '.txt;' tee = ' 2>&1 | tee ' + trace diag = 'check the compilation errors for ITTI Rel10' @@ -273,7 +273,7 @@ def execute(oai, user, pw, host, logfile,logdir,debug,timeout): oai.send('make cleanall;') oai.send('make cleanasn1;') oai.send('rm -f ./oaisim.rel10.itti.ral.'+host) - oai.send_expect_false('make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 USER_MODE=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel10=1 -j4' + tee, makerr1, timeout) + oai.send_expect_false('make DISABLE_XER_PRINT=1 LINK_ENB_PDCP_TO_IP_DRIVER=1 OAI_NW_DRIVER_TYPE_ETHERNET=1 ENABLE_ITTI=1 OPENAIR2=1 ENABLE_RAL=1 MIH_C_MEDIEVAL_EXTENSIONS=1 RLC_STOP_ON_LOST_PDU=1 Rel10=1 -j4' + tee, makerr1, timeout) oai.send('cp ./oaisim ./oaisim.rel10.itti.ral.'+host) except log.err, e: log.fail(case, test, name, conf, e.value, diag, logfile,trace) diff --git a/targets/TEST/PACKET_TRACER/Makefile b/targets/TEST/PACKET_TRACER/Makefile index 46fa86037c..e7a4e70bf9 100755 --- a/targets/TEST/PACKET_TRACER/Makefile +++ b/targets/TEST/PACKET_TRACER/Makefile @@ -6,21 +6,17 @@ OPENAIR2_TOP = $(OPENAIR2_DIR) OPENAIR3_TOP = $(OPENAIR3_DIR) OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -m32 -DPHYSIM -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 +CFLAGS += -m32 -DPHYSIM -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES -CFLAGS += -DOPENAIR_LTE -DPUCCH #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE -CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 -DPHY_ABSTRACTION -DOAI_EMU +CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE +CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 CFLAGS += -DEMIT_ASN_DEBUG=1 ifndef OPENAIR2 OPENAIR2=1 endif -ifndef OPENAIR_EMU -export OPENAIR_EMU=1 -endif - # activate OCG and libxml only under linux ifeq ($(linux),1) CFLAGS += -I/usr/include/libxml2 -L/usr/local/lib -I/usr/include/atlas -L/usr/X11R6/lib @@ -61,8 +57,6 @@ ifdef TRAFFIC_TM5 CFLAGS += -DRLC_UM_TEST_TRAFFIC=1 -DFULL_BUFFER=1 endif -CFLAGS += -DOAI_EMU - include $(OPENAIR1_DIR)/PHY/Makefile.inc include $(OPENAIR1_DIR)/SCHED/Makefile.inc include $(OPENAIR2_DIR)/LAYER2/Makefile.inc diff --git a/targets/TEST/PDCP/Makefile b/targets/TEST/PDCP/Makefile index 66af847af5..805cabe7cb 100755 --- a/targets/TEST/PDCP/Makefile +++ b/targets/TEST/PDCP/Makefile @@ -8,7 +8,7 @@ OPENAIR3 = $(OPENAIR3_DIR) EXE_FILE_NAME = test_pdcp -CFLAGS += -m32 -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 +CFLAGS += -m32 -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES @@ -25,8 +25,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION #-DEMIT_ASN_DEBUG=1 - #include $(OPENAIR1_DIR)/PHY/Makefile.inc #include $(OPENAIR1_DIR)/SCHED/Makefile.inc diff --git a/targets/TEST/PDCP/with_rlc/Makefile.data_bearer b/targets/TEST/PDCP/with_rlc/Makefile.data_bearer index 00f07c1b92..d1397d3f49 100755 --- a/targets/TEST/PDCP/with_rlc/Makefile.data_bearer +++ b/targets/TEST/PDCP/with_rlc/Makefile.data_bearer @@ -8,7 +8,7 @@ OPENAIR3 = $(OPENAIR3_DIR) EXE_FILE_NAME = test_pdcp_rlc -CFLAGS += -m32 -DPHYSIM -DNODE_RG -DUSER_MODE -DPC_TARGET -DPC_DSP -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 +CFLAGS += -m32 -DPHYSIM -DNODE_RG -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DMAX_MODULES=1 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES @@ -25,8 +25,6 @@ ifdef PDCP_USE_NETLINK CFLAGS += -DPDCP_USE_NETLINK -DLINUX -DDEBUG_CONTROL endif -CFLAGS += -DPHY_ABSTRACTION #-DEMIT_ASN_DEBUG=1 - #include $(OPENAIR1_DIR)/PHY/Makefile.inc #include $(OPENAIR1_DIR)/SCHED/Makefile.inc diff --git a/targets/TEST/RLC_AM_V9.3.0/Makefile b/targets/TEST/RLC_AM_V9.3.0/Makefile index 9c807cd826..8884d7b667 100755 --- a/targets/TEST/RLC_AM_V9.3.0/Makefile +++ b/targets/TEST/RLC_AM_V9.3.0/Makefile @@ -8,27 +8,18 @@ OPENAIR2_TOP = $(OPENAIR2_DIR) OPENAIR3_TOP = $(OPENAIR3_DIR) OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -m32 -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 +CFLAGS += -m32 -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES -CFLAGS += -DOPENAIR_LTE -DPUCCH #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE -CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 -DPHY_ABSTRACTION #-DPHY_ABSTRACTION_UL #-DRLC_UM_TEST_TRAFFIC=1 -CFLAGS += -DNEW_FFT +CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE +CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 #-DRLC_UM_TEST_TRAFFIC=1 #CFLAGS += -DLLR8 ifndef OPENAIR2 OPENAIR2=1 endif -ifndef OPENAIR_EMU -export OPENAIR_EMU=1 -endif - -ifdef EMOS -CFLAGS+=-DEMOS -endif - ifdef TRAFFIC_TM5 CFLAGS += -DRLC_UM_TEST_TRAFFIC=1 #-DFULL_BUFFER=1 endif @@ -114,7 +105,7 @@ endif CFLAGS += $(shell if [ `uname -o` = "Cygwin" ] ; then echo "-DCYGWIN" ;fi) -CFLAGS += -DENABLE_FXP -DOAI_EMU -DENABLE_USE_CPU_EXECUTION_TIME +CFLAGS += -DENABLE_USE_CPU_EXECUTION_TIME ifneq ($(USE_MME), R8) UPDATE_RELEASE_9=1 diff --git a/targets/TEST/RLC_UM_V9.3.0/Makefile b/targets/TEST/RLC_UM_V9.3.0/Makefile index b01ea156f4..919def5f1e 100755 --- a/targets/TEST/RLC_UM_V9.3.0/Makefile +++ b/targets/TEST/RLC_UM_V9.3.0/Makefile @@ -8,27 +8,18 @@ OPENAIR2_TOP = $(OPENAIR2_DIR) OPENAIR3_TOP = $(OPENAIR3_DIR) OPENAIR3 = $(OPENAIR3_DIR) -CFLAGS += -m32 -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 +CFLAGS += -m32 -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -I/usr/include/X11 ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES -CFLAGS += -DOPENAIR_LTE -DPUCCH #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE -CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 -DPHY_ABSTRACTION #-DPHY_ABSTRACTION_UL #-DRLC_UM_TEST_TRAFFIC=1 -CFLAGS += -DNEW_FFT +CFLAGS += -DOPENAIR_LTE #-DOFDMA_ULSCH -DIFFT_FPGA -DIFFT_FPGA_UE +CFLAGS += -DMAC_CONTEXT=1 -DPHY_CONTEXT=1 #-DRLC_UM_TEST_TRAFFIC=1 #CFLAGS += -DLLR8 ifndef OPENAIR2 OPENAIR2=1 endif -ifndef OPENAIR_EMU -export OPENAIR_EMU=1 -endif - -ifdef EMOS -CFLAGS+=-DEMOS -endif - ifdef TRAFFIC_TM5 CFLAGS += -DRLC_UM_TEST_TRAFFIC=1 #-DFULL_BUFFER=1 endif @@ -109,7 +100,7 @@ ifdef OAI_NW_DRIVER_TYPE_ETHERNET CFLAGS+=-DOAI_NW_DRIVER_TYPE_ETHERNET endif -CFLAGS += -DENABLE_FXP -DOAI_EMU -DENABLE_USE_CPU_EXECUTION_TIME +CFLAGS += -DENABLE_USE_CPU_EXECUTION_TIME ifneq ($(USE_MME), R8) UPDATE_RELEASE_9=1