Merge with develop branch of main OAI repository.

This commit is contained in:
matzakos
2018-02-19 12:27:21 +01:00
421 changed files with 87856 additions and 50640 deletions

View File

@@ -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_USER_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)
@@ -241,6 +241,7 @@ add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace")
add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace")
add_boolean_option(DISABLE_LOG_X False "Deactivate all LOG_* macros")
add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode")
add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
@@ -261,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
################################
@@ -484,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")
@@ -586,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 "????")
@@ -611,22 +606,12 @@ add_boolean_option(FLEXRAN_AGENT_SB_IF False "enable FlexRAN
##########################
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")
@@ -636,24 +621,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")
@@ -726,23 +702,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}")
@@ -775,7 +735,6 @@ 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")
@@ -1007,6 +966,7 @@ set(SCHED_SRC
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_eNb.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_ue.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
${OPENAIR1_DIR}/SCHED/prach_procedures.c
${OPENAIR1_DIR}/SCHED/ru_procedures.c
# ${OPENAIR1_DIR}/SCHED/phy_mac_stub.c
${OPENAIR1_DIR}/SCHED/pucch_pc.c
@@ -1015,6 +975,17 @@ set(SCHED_SRC
)
add_library(SCHED_LIB ${SCHED_SRC})
set(SCHED_SRC_UE
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_ue.c
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
${OPENAIR1_DIR}/SCHED/ru_procedures.c
${OPENAIR1_DIR}/SCHED/prach_procedures.c
${OPENAIR1_DIR}/SCHED/pucch_pc.c
${OPENAIR1_DIR}/SCHED/pusch_pc.c
${OPENAIR1_DIR}/SCHED/srs_pc.c
)
add_library(SCHED_UE_LIB ${SCHED_SRC_UE})
# nFAPI
#################################
set(NFAPI_COMMON_SRC
@@ -1060,9 +1031,9 @@ 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
${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})
@@ -1148,6 +1119,9 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/CODING/viterbi.c
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
${OPENAIR1_DIR}/PHY/INIT/lte_init.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_ru.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c
${OPENAIR1_DIR}/PHY/INIT/init_top.c
${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
@@ -1163,15 +1137,112 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
)
set(PHY_SRC_UE
# depend on code generation from asn1c
${RRC_FULL_DIR}/asn1_constants.h
# actual source
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/power_control.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_decoding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/uci_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pbch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/edci.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/group_hopping.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/srs_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/drs_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_coding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_decoding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c
${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c
${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/adjust_gain.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_uespec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
${OPENAIR1_DIR}/PHY/CODING/crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c
${OPENAIR1_DIR}/PHY/CODING/viterbi.c
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_ru.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c
${OPENAIR1_DIR}/PHY/INIT/init_top.c
${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/cdot_prod.c
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
)
if (${SMBV})
set(PHY_SRC "${PHY_SRC} ${OPENAIR1_DIR}/PHY/TOOLS/smbv.c")
endif (${SMBV})
if (${COMPILATION_AVX2} STREQUAL "True")
set(PHY_SRC ${PHY_SRC} ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c)
set(PHY_SRC_UE ${PHY_SRC_UE} ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c)
endif ()
add_library(PHY ${PHY_SRC})
add_library(PHY_UE ${PHY_SRC_UE})
#Layer 2 library
#####################
@@ -1225,15 +1296,62 @@ set(L2_SRC
${RRC_DIR}/rrc_eNB_UE_context.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set(L2_SRC_UE
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
${PDCP_DIR}/pdcp.c
${PDCP_DIR}/pdcp_fifo.c
${PDCP_DIR}/pdcp_sequence_manager.c
${PDCP_DIR}/pdcp_primitives.c
${PDCP_DIR}/pdcp_util.c
${PDCP_DIR}/pdcp_security.c
${PDCP_DIR}/pdcp_netlink.c
${RLC_AM_DIR}/rlc_am.c
${RLC_AM_DIR}/rlc_am_init.c
${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
${RLC_AM_DIR}/rlc_am_timer_reordering.c
${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c
${RLC_AM_DIR}/rlc_am_segment.c
${RLC_AM_DIR}/rlc_am_segments_holes.c
${RLC_AM_DIR}/rlc_am_in_sdu.c
${RLC_AM_DIR}/rlc_am_receiver.c
${RLC_AM_DIR}/rlc_am_retransmit.c
${RLC_AM_DIR}/rlc_am_windows.c
${RLC_AM_DIR}/rlc_am_rx_list.c
${RLC_AM_DIR}/rlc_am_reassembly.c
${RLC_AM_DIR}/rlc_am_status_report.c
${RLC_TM_DIR}/rlc_tm.c
${RLC_TM_DIR}/rlc_tm_init.c
${RLC_UM_DIR}/rlc_um.c
${RLC_UM_DIR}/rlc_um_fsm.c
${RLC_UM_DIR}/rlc_um_control_primitives.c
${RLC_UM_DIR}/rlc_um_segment.c
${RLC_UM_DIR}/rlc_um_reassembly.c
${RLC_UM_DIR}/rlc_um_receiver.c
${RLC_UM_DIR}/rlc_um_dar.c
${RLC_DIR}/rlc_mac.c
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
set (MAC_SRC
${PHY_INTERFACE_DIR}/phy_stub_UE.c
${PHY_INTERFACE_DIR}/IF_Module.c
${MAC_DIR}/main.c
${MAC_DIR}/main_ue.c
${MAC_DIR}/ue_procedures.c
${MAC_DIR}/ra_procedures.c
${MAC_DIR}/l1_helpers.c
${MAC_DIR}/rar_tools.c
${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/eNB_scheduler.c
${MAC_DIR}/eNB_scheduler_dlsch.c
${MAC_DIR}/eNB_scheduler_ulsch.c
@@ -1243,8 +1361,19 @@ set (MAC_SRC
${MAC_DIR}/eNB_scheduler_RA.c
${MAC_DIR}/pre_processor.c
${MAC_DIR}/config.c
${MAC_DIR}/config_ue.c
)
set (MAC_SRC_UE
${MAC_DIR}/main_ue.c
${MAC_DIR}/ue_procedures.c
${MAC_DIR}/ra_procedures.c
${MAC_DIR}/l1_helpers.c
${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/config_ue.c
)
if (FLEXRAN_AGENT_SB_IF)
set (MAC_SRC ${MAC_SRC}
@@ -1266,6 +1395,11 @@ add_library(L2
${ENB_APP_SRC})
# ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c)
add_library(L2_UE
${L2_SRC_UE}
${MAC_SRC_UE}
)
include_directories(${NFAPI_USER_DIR})
if (FLEXRAN_AGENT_SB_IF)
@@ -1305,26 +1439,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
##########################
@@ -1674,7 +1788,6 @@ ${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
@@ -1866,13 +1979,13 @@ add_executable(lte-softmodem
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${GTPU_need_ITTI}
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
@@ -1882,7 +1995,7 @@ add_executable(lte-softmodem
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
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
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -1908,12 +2021,14 @@ add_executable(lte-softmodem-nos1
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
${OPENAIR_DIR}/common/utils/system.c
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
@@ -1949,6 +2064,7 @@ add_executable(lte-softmodem-stub-nos1
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
@@ -1957,7 +2073,7 @@ add_executable(lte-softmodem-stub-nos1
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
#${GTPU_need_ITTI}
${RTAI_SOURCE}
#${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
@@ -1996,6 +2112,7 @@ add_executable(lte-softmodem-stub
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
@@ -2004,7 +2121,7 @@ add_executable(lte-softmodem-stub
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${GTPU_need_ITTI}
${RTAI_SOURCE}
#${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
@@ -2026,27 +2143,6 @@ target_link_libraries (lte-softmodem-stub ${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
@@ -2099,7 +2195,7 @@ add_executable(oaisim
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${GTPU_need_ITTI}
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${XFORMS_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -2131,10 +2227,10 @@ 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_UE_LIB PHY_UE LFDS L2 ${MSC_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB
-Wl,--end-group )
-Wl,--end-group z dl)
target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp z
@@ -2152,7 +2248,7 @@ add_executable(oaisim_nos1
${x2ap_h}
${OPENAIR_BIN_DIR}/messages_xml.h
${OPENAIR_TARGETS}/RT/USER/lte-ue.c
${OPENAIR_TARGETS}/RT/USER/lte-enb.c
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
@@ -2165,7 +2261,7 @@ add_executable(oaisim_nos1
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_DIR}/common/utils/system.c
${XFORMS_SOURCE}
${T_SOURCE}
@@ -2175,8 +2271,8 @@ add_executable(oaisim_nos1
target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
target_link_libraries (oaisim_nos1
-Wl,--start-group
RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} SIMU SECU_OSA ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
-Wl,--end-group )
RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_UE_LIB PHY_UE LFDS ${MSC_LIB} ${ITTI_LIB} SIMU L2_UE ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7
-Wl,--end-group z dl )
target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES}
@@ -2283,7 +2379,8 @@ endforeach(myExe)
if (${T_TRACER})
foreach(i
#all "add_executable" definitions (except tests, rb_tool, updatefw)
lte-softmodem lte-softmodem-stub lte-softmodem-nos1 rrh_gw oaisim oaisim_nos1
lte-softmodem lte-softmodem-stub lte-softmodem-nos1 oaisim oaisim_nos1
dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
pdcchsim pucchsim prachsim syncsim
#all "add_library" definitions
@@ -2291,7 +2388,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)
@@ -2353,7 +2450,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}")
@@ -2385,15 +2481,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)

View File

@@ -66,6 +66,7 @@ UE_AUTOTEST_TRACE="False"
UE_DEBUG_TRACE="False"
UE_TIMING_TRACE="False"
DISABLE_LOG_X="False"
USRP_REC_PLAY="False"
BUILD_ECLIPSE=0
trap handle_ctrl_c INT
@@ -99,8 +100,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
@@ -158,6 +157,8 @@ Options
Disable all LOG_* macros
--build-eclipse
Build eclipse project files. Paths are auto corrected by fixprj.sh
--usrp-recplay
Build for I/Q record-playback modes
Usage (first build):
oaisim (eNB + UE): ./build_oai -I --oaisim -x --install-system-files
Eurecom EXMIMO + COTS UE : ./build_oai -I --eNB -x --install-system-files
@@ -216,10 +217,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"
@@ -350,6 +347,10 @@ function main() {
BUILD_TELNETSRV=1
echo_info "Build embedded telnet server"
shift ;;
--usrp-recplay)
USRP_REC_PLAY="True"
echo_info "Enabling USRP record playback mode"
shift 1;;
-h | --help)
print_help
exit 1;;
@@ -364,7 +365,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
@@ -380,15 +381,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,
@@ -542,6 +534,7 @@ function main() {
echo "set (UE_DEBUG_TRACE $UE_DEBUG_TRACE)" >> $cmake_file
echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)" >> $cmake_file
echo "set (DISABLE_LOG_X $DISABLE_LOG_X)" >> $cmake_file
echo "set (USRP_REC_PLAY $USRP_REC_PLAY)" >> $cmake_file
if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then
echo_info "Compiling UE S1 build : enabling Linux and NETLINK"
echo "set (LINUX True )" >> $cmake_file
@@ -787,36 +780,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
@@ -835,13 +798,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

View File

@@ -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 )

View File

@@ -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)

View File

@@ -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 )

View File

@@ -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 )

View File

@@ -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,51 +28,35 @@ 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 )
set ( NAS_ADDRESS_FIX False )
set ( NAS_BUILT_IN_UE False)
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)

View File

@@ -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 )

View File

@@ -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 ;;
@@ -480,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 \
@@ -505,7 +517,6 @@ check_install_oai_software() {
texlive-latex-base \
ethtool \
flex \
gccxml \
gdb \
git \
graphviz \
@@ -516,7 +527,6 @@ check_install_oai_software() {
iptables \
iptables-dev \
libatlas-base-dev \
libatlas-dev \
libblas-dev \
libconfig8-dev \
libffi-dev \
@@ -554,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

View File

@@ -44,11 +44,11 @@ load_module $OPENAIR_DIR/targets/bin/nasmesh.ko
if [ "$1" = "eNB" ]; then
echo "bring up oai0 interface for enb"
sudo ifconfig oai0 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.9 -r 1
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.1 -t 10.0.1.2 -r 1
else
if [ "$1" = "UE" ]; then
echo "bring up oai0 interface for UE"
sudo ifconfig oai0 10.0.1.9 netmask 255.255.255.0 broadcast 10.0.1.255
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.9 -t 10.0.1.1 -r 1
$OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.2 -t 10.0.1.1 -r 1
fi
fi

View File

@@ -59,6 +59,15 @@ char defbool[2]="1";
printf("cfgoptions->strptr %p (&emul_iface %p, emul_iface %p)\n",cfgoptions->strptr,&emul_iface,emul_iface);
sprintf(*(cfgoptions->strptr), "%s",tmpval);
printf("[CONFIG] %s set to %s from command line\n", cfgoptions->optname, tmpval);
/*=======
if (cfgoptions->numelt == 0 ) {
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1);
sprintf(*(cfgoptions->strptr), "%s",tmpval);
} else {
sprintf( (char *)(cfgoptions->strptr), "%s",tmpval);
}
printf_cmdl("[CONFIG] %s set to %s from command line\n", cfgoptions->optname, tmpval);
>>>>>>> main/develop*/
optisset=1;
break;

View File

@@ -129,20 +129,21 @@ int i;
/* default */
if (cfgparam == NULL) {
cfgparam = "libconfig:oaisoftmodem.conf";
tmpflags = tmpflags | CONFIG_NOOOPT;
cfgparam = DEFAULT_CFGMODE ":" DEFAULT_CFGFILENAME;
}
/* parse the config parameters to set the config source */
i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams);
if (i< 0) {
fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno));
cfgmode=strdup("libconfig");
modeparams = strdup("oaisoftmodem.conf");
cfgmode=strdup(DEFAULT_CFGMODE);
modeparams = strdup(DEFAULT_CFGFILENAME);
}
else if ( i == 1 ) {
/* -O argument doesn't contain ":" separator, assume -O <conf file> option, default cfgmode to libconfig
with one parameter, the path to the configuration file */
modeparams=cfgmode;
cfgmode=strdup("libconfig");
cfgmode=strdup(DEFAULT_CFGMODE);
}
cfgptr = malloc(sizeof(configmodule_interface_t));

View File

@@ -46,6 +46,7 @@
#define CONFIG_DEBUGCMDLINE 4 // print command line processing messages
#define CONFIG_HELP 8 // print help message
#define CONFIG_ABORT 16 // config failed,abort execution
#define CONFIG_NOOOPT 32 // no -O option found when parsing command line
typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);

View File

@@ -50,7 +50,11 @@ configmodule_interface_t *config_get_if(void)
char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length)
{
printf_ptrs("-- %s 0x%08lx %i\n",cfgoptions->optname,(uintptr_t)(*ptr),length);
printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length);
if(cfgoptions->numelt > 0) { /* already allocated */
return *ptr;
}
if (*ptr == NULL) {
*ptr = malloc(length);
if ( *ptr != NULL) {
@@ -148,3 +152,7 @@ int config_isparamset(paramdef_t *params,int paramidx)
return 0;
}
}
int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) {
return -1;
}

View File

@@ -38,6 +38,9 @@
extern "C"
{
#endif
#define DEFAULT_CFGFILENAME "oaisoftmodem.conf"
#define DEFAULT_CFGMODE "libconfig"
#define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode )
#define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP )
#define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] )
@@ -51,6 +54,7 @@ extern int config_get(paramdef_t *params,int numparams, char *prefix);
extern int config_isparamset(paramdef_t *params,int paramidx);
extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val);
extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix);
extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx);
#define config_getlist config_get_if()->getlist
#define CONFIG_GETCONFFILE (config_get_if()->cfgP[0])

View File

@@ -104,17 +104,28 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
cfgpath,str,cfgoptions[i].numelt);
str[strlen(str)-1] = 0;
}
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
sprintf( *(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) );
if (cfgoptions[i].numelt == 0 ) {
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
sprintf( *(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) );
} else {
sprintf( (char *)(cfgoptions[i].strptr) , "%s", str);
printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr );
}
} else {
if( cfgoptions[i].defstrval != NULL) {
defval=1;
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr));
if (cfgoptions[i].numelt == 0 ) {
config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr));
} else {
sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr);
}
} else {
notfound=1;
}
@@ -183,7 +194,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
read_intarray(&cfgoptions[i],setting,cfgpath);
} else {
if( cfgoptions[i].defintarrayval != NULL) {
config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t));
config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t*));
cfgoptions[i].iptr=cfgoptions[i].defintarrayval;
defval=1;
for (int j=0; j<cfgoptions[i].numelt ; j++) {

View File

@@ -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

View File

@@ -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

View File

@@ -31,10 +31,6 @@
#include <sys/epoll.h>
#include <sys/eventfd.h>
#ifdef RTAI
# include <rtai_shm.h>
#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
@@ -64,14 +55,6 @@
#include "signals.h"
#include "timer.h"
#ifdef RTAI
# include <rtai.h>
# include <rtai_fifos.h>
# 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)
@@ -83,22 +66,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;
@@ -137,13 +110,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 {
@@ -175,17 +146,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;
@@ -194,20 +154,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);
@@ -219,13 +167,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);
}
@@ -281,27 +223,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;
@@ -358,10 +279,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();
@@ -373,10 +290,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;
}
@@ -394,11 +307,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);
@@ -421,11 +329,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",
@@ -458,17 +361,6 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n");
}
#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) {
@@ -496,11 +388,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;
}
@@ -645,17 +532,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)
@@ -664,11 +543,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;
@@ -685,10 +559,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)
@@ -720,7 +590,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);
@@ -729,7 +598,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)
{
@@ -757,15 +625,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 ++;
@@ -778,15 +637,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);
}
@@ -802,45 +652,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)
{
@@ -921,45 +732,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 ());
@@ -1022,15 +800,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);

View File

@@ -27,10 +27,6 @@
#include <sys/epoll.h>
#ifdef RTAI
# include <rtai_sem.h>
#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

View File

@@ -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++) {

View File

@@ -27,11 +27,7 @@
#ifndef _ITTI_TYPES_H_
#define _ITTI_TYPES_H_
#ifdef USER_MODE
#include <stdint.h>
#else
#include <linux/types.h>
#endif
#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1))

View File

@@ -19,15 +19,8 @@
* contact@openairinterface.org
*/
#ifdef RTAI
# include <rtai_shm.h>
#endif
#include "assertions.h"
#include "memory_pools.h"
#if defined(OAI_EMU) || defined(RTAI)
# include "vcd_signal_dumper.h"
#endif
#if T_TRACER
#include <string.h>
@@ -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);
}

View File

@@ -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

15
nfapi/README Normal file
View File

@@ -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.

View File

@@ -1,176 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
#if 0
#if 0
//DJP
#include <mutex>
#include <queue>
#include <list>
#endif
//DJP struct phy_pdu
typedef struct
{
#if 0
phy_pdu() : buffer_len(1500), buffer(0), len(0)
{
buffer = (char*) malloc(buffer_len);
}
virtual ~phy_pdu()
{
free(buffer);
}
#endif
unsigned buffer_len;
char* buffer;
unsigned len;
} phy_pdu;
// DJP class fapi_private
typedef struct
{
//std::mutex mutex;
//std::queue<phy_pdu*> rx_buffer;
//std::queue<phy_pdu*> free_store;
#if 0
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;
}
#endif
uint32_t byte_count;
uint32_t tick;
uint8_t first_dl_config;
} fapi_private ;
#if defined(__cplusplus)
extern "C"
{
#endif
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;
#if defined(__cplusplus)
}
#endif
#endif
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");
}
}

View File

@@ -1,6 +0,0 @@
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
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

View File

@@ -1,6 +0,0 @@
#if !defined(NFAPI_VNF_H__)
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif

View File

@@ -19,31 +19,33 @@
* contact@openairinterface.org
*/
#ifndef _IOCTL_H
#define _IOCTL_H
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/if.h>
#include <linux/ipv6.h>
#include <linux/in.h>
#include <linux/in6.h>
//#include <linux/netdevice.h>
#include <pthread.h>
//#include <graal_constant.h>
//#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");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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_

View File

@@ -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

View File

201
nfapi/open-nFAPI/LICENSE.md Normal file
View File

@@ -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.

View File

@@ -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)

138
nfapi/open-nFAPI/README.md Normal file
View File

@@ -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 <port> <xml config file>
```
### 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 <address> <port> <xml config file>
```
## 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.

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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 <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <syslog.h>
#include <debug.h>
#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);
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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="<connect>"];
* 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="<create>"];
* 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="<create>"];
* 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="<create>"];
* 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="<start_response>"];
*
* 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="<p7_add_pnf>"];
* 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 LIBs invoke callbacks on the CLIENTs 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 subframes 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 UEs
*/

View File

@@ -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)

View File

@@ -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 <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
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();
}

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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;

View File

@@ -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 <signal.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sched.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <nfapi_interface.h>
#include <nfapi.h>
#include <debug.h>
// 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";
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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_

View File

@@ -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_ */

View File

@@ -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 <sys/types.h>
/*! 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_

File diff suppressed because it is too large Load Diff

View File

@@ -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 <stdlib.h>
#include <string.h>
#include <unistd.h>
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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <stdlib.h>
#include <string.h>
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);
}

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
#include <mutex>
#include <queue>
#include <list>
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<phy_pdu*> rx_buffer;
std::queue<phy_pdu*> 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<phy_pdu*> 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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 <mutex>
#include <map>
#include <queue>
#include <cassert>
class pool_config
{
public:
size_t size;
uint16_t initial_count;
};
class memory_pool
{
std::mutex mutex;
std::map<size_t, std::queue<uint8_t*>> free_store;
std::map<size_t, uint16_t> allocated_store;
void init(std::vector<pool_config> 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<size_t,
std::queue<uint8_t*>>
(c.size, std::queue<uint8_t*>()));
allocated_store.insert(std::pair<size_t, uint16_t>(c.size, 0));
}
}
memory_pool()
{
std::vector<pool_config> 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_

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -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_

View File

@@ -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_

View File

@@ -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_

File diff suppressed because it is too large Load Diff

View File

@@ -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 <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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;
}

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<pnf>
<sync_mode>0</sync_mode>
<location_mode>0</location_mode>
<location_coordinates></location_coordinates>
<dl_config_timing>500</dl_config_timing>
<ul_config_timing>500</ul_config_timing>
<tx_timing>500</tx_timing>
<hi_dci0_timing>500</hi_dci0_timing>
<max_phys>1</max_phys>
<max_total_bandwidth>30</max_total_bandwidth>
<max_total_num_dl_layers>1</max_total_num_dl_layers>
<max_total_num_ul_layers>1</max_total_num_ul_layers>
<shared_bands>0</shared_bands>
<shared_pas>0</shared_pas>
<maximum_total_power>0</maximum_total_power>
<oui>ALPHA</oui>
<phys>
<phy>
<index>88</index>
<port>2500</port>
<address>192.168.1.74</address>
<duplex_mode>1</duplex_mode>
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
<number_of_dl_layers>1</number_of_dl_layers>
<number_of_ul_layers>1</number_of_ul_layers>
<3gpp_release_supported>31</3gpp_release_supported>
<nmm_modes_supported>0</nmm_modes_supported>
<dl_ues_per_subframe>8</dl_ues_per_subframe>
<ul_ues_per_subframe>8</ul_ues_per_subframe>
<!-- todo adn the other release parameters -->
<rfs>
<index>0</index>
</rfs>
<excluded_rfs>
<index>1</index>
</excluded_rfs>
<data>
<udp>
<rx_port>5201</rx_port>
<tx_addr>192.168.1.28</tx_addr>
<tx_port>5200</tx_port>
</udp>
</data>
</phy>
</phys>
<rfs>
<rf>
<index>0</index>
<band>2</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
<rf>
<index>1</index>
<band>3</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
</rfs>
</pnf>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<pnf>
<wireshark_test_mode>1</wireshark_test_mode>
<sync_mode>0</sync_mode>
<location_mode>0</location_mode>
<location_coordinates></location_coordinates>
<dl_config_timing>500</dl_config_timing>
<ul_config_timing>500</ul_config_timing>
<tx_timing>500</tx_timing>
<hi_dci0_timing>500</hi_dci0_timing>
<max_phys>1</max_phys>
<max_total_bandwidth>30</max_total_bandwidth>
<max_total_num_dl_layers>1</max_total_num_dl_layers>
<max_total_num_ul_layers>1</max_total_num_ul_layers>
<shared_bands>0</shared_bands>
<shared_pas>0</shared_pas>
<maximum_total_power>0</maximum_total_power>
<oui>ALPHA</oui>
<phys>
<phy>
<index>88</index>
<port>2500</port>
<address>127.0.0.1</address>
<duplex_mode>1</duplex_mode>
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
<number_of_dl_layers>1</number_of_dl_layers>
<number_of_ul_layers>1</number_of_ul_layers>
<3gpp_release_supported>31</3gpp_release_supported>
<nmm_modes_supported>0</nmm_modes_supported>
<dl_ues_per_subframe>8</dl_ues_per_subframe>
<ul_ues_per_subframe>8</ul_ues_per_subframe>
<!-- todo adn the other release parameters -->
<rfs>
<index>0</index>
</rfs>
<excluded_rfs>
<index>1</index>
</excluded_rfs>
<data>
<udp>
<rx_port>7722</rx_port>
<tx_addr>127.0.0.1</tx_addr>
<tx_port>7733</tx_port>
</udp>
</data>
</phy>
</phys>
<rfs>
<rf>
<index>0</index>
<band>2</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
<rf>
<index>1</index>
<band>3</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
</rfs>
</pnf>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<pnf>
<sync_mode>0</sync_mode>
<location_mode>0</location_mode>
<location_coordinates></location_coordinates>
<dl_config_timing>500</dl_config_timing>
<ul_config_timing>500</ul_config_timing>
<tx_timing>500</tx_timing>
<hi_dci0_timing>500</hi_dci0_timing>
<max_phys>1</max_phys>
<max_total_bandwidth>30</max_total_bandwidth>
<max_total_num_dl_layers>1</max_total_num_dl_layers>
<max_total_num_ul_layers>1</max_total_num_ul_layers>
<shared_bands>0</shared_bands>
<shared_pas>0</shared_pas>
<maximum_total_power>0</maximum_total_power>
<oui>ALPHA</oui>
<phys>
<phy>
<index>89</index>
<port>2510</port>
<address>127.0.0.1</address>
<duplex_mode>1</duplex_mode>
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
<number_of_dl_layers>1</number_of_dl_layers>
<number_of_ul_layers>1</number_of_ul_layers>
<3gpp_release_supported>31</3gpp_release_supported>
<nmm_modes_supported>0</nmm_modes_supported>
<dl_ues_per_subframe>8</dl_ues_per_subframe>
<ul_ues_per_subframe>8</ul_ues_per_subframe>
<!-- todo adn the other release parameters -->
<rfs>
<index>0</index>
</rfs>
<excluded_rfs>
<index>1</index>
</excluded_rfs>
<data>
<udp>
<rx_port>7744</rx_port>
<tx_addr>127.0.0.1</tx_addr>
<tx_port>7755</tx_port>
</udp>
</data>
</phy>
</phys>
<rfs>
<rf>
<index>0</index>
<band>2</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
<rf>
<index>1</index>
<band>3</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
</rfs>
</pnf>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<pnf>
<sync_mode>0</sync_mode>
<location_mode>0</location_mode>
<location_coordinates></location_coordinates>
<dl_config_timing>500</dl_config_timing>
<ul_config_timing>500</ul_config_timing>
<tx_timing>500</tx_timing>
<hi_dci0_timing>500</hi_dci0_timing>
<max_phys>1</max_phys>
<max_total_bandwidth>30</max_total_bandwidth>
<max_total_num_dl_layers>1</max_total_num_dl_layers>
<max_total_num_ul_layers>1</max_total_num_ul_layers>
<shared_bands>0</shared_bands>
<shared_pas>0</shared_pas>
<maximum_total_power>0</maximum_total_power>
<oui>ALPHA</oui>
<phys>
<phy>
<index>88</index>
<port>2500</port>
<address>127.0.0.1</address>
<duplex_mode>1</duplex_mode>
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
<number_of_dl_layers>1</number_of_dl_layers>
<number_of_ul_layers>1</number_of_ul_layers>
<3gpp_release_supported>31</3gpp_release_supported>
<nmm_modes_supported>0</nmm_modes_supported>
<dl_ues_per_subframe>8</dl_ues_per_subframe>
<ul_ues_per_subframe>8</ul_ues_per_subframe>
<rfs>
<index>0</index>
</rfs>
<excluded_rfs/>
</phy>
<phy>
<index>44</index>
<port>2600</port>
<address>127.0.0.1</address>
<duplex_mode>1</duplex_mode>
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
<number_of_dl_layers>1</number_of_dl_layers>
<number_of_ul_layers>1</number_of_ul_layers>
<3gpp_release_supported>31</3gpp_release_supported>
<nmm_modes_supported>0</nmm_modes_supported>
<dl_ues_per_subframe>8</dl_ues_per_subframe>
<ul_ues_per_subframe>8</ul_ues_per_subframe>
<rfs>
<index>1</index>
</rfs>
<excluded_rfs/>
</phy>
</phys>
<rfs>
<rf>
<index>0</index>
<band>2</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
<rf>
<index>1</index>
<band>4</band>
<max_transmit_power>-30</max_transmit_power>
<min_transmit_power>-230</min_transmit_power>
<num_antennas_supported>2</num_antennas_supported>
<min_downlink_frequency>1890</min_downlink_frequency>
<max_downlink_frequency>1890</max_downlink_frequency>
<max_uplink_frequency>1890</max_uplink_frequency>
<min_uplink_frequency>1890</min_uplink_frequency>
</rf>
</rfs>
</pnf>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<vnf>
<vnf_p7_list>
<vnf_p7>
<port>5201</port>
<address>192.168.1.28</address>
<timing_window>10</timing_window>
<periodic_timing_enabled>0</periodic_timing_enabled>
<periodic_timing_window>0</periodic_timing_window>
<aperiodic_timing_enabled>0</aperiodic_timing_enabled>
<data>
<udp>
<rx_port>8891</rx_port>
<tx_addr>192.168.1.28</tx_addr>
<tx_port>8892</tx_port>
</udp>
</data>
</vnf_p7>
</vnf_p7_list>
</vnf>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<vnf>
<vnf_p7_list>
<vnf_p7>
<wireshark_test_mode>1</wireshark_test_mode>
<port>5200</port>
<address>127.0.0.1</address>
<timing_window>10</timing_window>
<periodic_timing_enabled>0</periodic_timing_enabled>
<periodic_timing_window>0</periodic_timing_window>
<aperiodic_timing_enabled>0</aperiodic_timing_enabled>
<data>
<udp>
<rx_port>8891</rx_port>
<tx_addr>127.0.0.1</tx_addr>
<tx_port>8892</tx_port>
</udp>
</data>
</vnf_p7>
</vnf_p7_list>
</vnf>

View File

@@ -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)

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More