From 75ad3da9d978c9101baf7cec3041308b4f2cb457 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Thu, 21 Jan 2021 15:51:30 +0100 Subject: [PATCH 1/5] start new gtpu --- cmake_targets/CMakeLists.txt | 43 +- common/utils/msc/msc.h | 2 +- common/utils/ocp_itti/intertask_interface.h | 1 + executables/main-ocp.c | 1 - executables/nr-ru.c | 1 - executables/nr-softmodem.c | 1 - executables/nr-uesoftmodem.c | 1 - executables/ocp-gnb.c | 1 - executables/softmodem-common.c | 2 + executables/softmodem-common.h | 3 + openair1/PHY/TOOLS/time_meas.c | 1 + openair1/PHY/TOOLS/time_meas.h | 2 +- openair1/SIMULATION/NR_PHY/prachsim.c | 1 + openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h | 2 - openair2/LAYER2/RLC/rlc.c | 2 + openair2/LAYER2/RLC/rlc.h | 12 +- openair2/NETWORK_DRIVER/MESH/device.c | 4 + openair2/NETWORK_DRIVER/UE_IP/device.c | 4 + openair2/RRC/LTE/rrc_eNB.c | 1 + openair2/RRC/LTE/rrc_eNB_GTPV1U.c | 18 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 3 +- openair2/SIMULATION/NR_RRC/itti_sim.c | 1 - openair3/ocp-gtpu/gtp_itf.cpp | 623 +++++++++++++++++++ openair3/ocp-gtpu/gtp_itf.h | 49 ++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 +- targets/COMMON/create_tasks.c | 1 + targets/COMMON/create_tasks_mbms.c | 1 + targets/RT/USER/lte-softmodem.c | 1 - targets/RT/USER/lte-uesoftmodem.c | 1 - 29 files changed, 734 insertions(+), 51 deletions(-) create mode 100644 openair3/ocp-gtpu/gtp_itf.cpp create mode 100644 openair3/ocp-gtpu/gtp_itf.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0b9d925017..0e13d14f0b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -405,6 +405,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(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") +add_boolean_option(NEW_GTPU False "NEW_GTP") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI @@ -413,7 +414,6 @@ add_library(ITTI ) add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) - set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) ################################################## @@ -2217,15 +2217,19 @@ set (GTPV1U_SRC add_library(GTPV1U ${GTPV1U_SRC}) add_dependencies(GTPV1U rrc_flag) -#add_library (GTPV1U_OCP -#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp -#) -#include_directories(${OPENAIR3_DIR}/ocp-gtp) +add_library (GTPV1U_OCP + ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c + ${RRC_DIR}/rrc_eNB_GTPV1U.c +${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp +) +add_dependencies(GTPV1U_OCP rrc_flag) +include_directories(${OPENAIR3_DIR}/ocp-gtp) #NR case set (NR_GTPV1U_SRC ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c ${RRC_DIR}/rrc_eNB_GTPV1U.c + ${GTPV1U_DIR}/gtpv1u_eNB.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c @@ -2235,6 +2239,12 @@ set (NR_GTPV1U_SRC add_library(NR_GTPV1U ${NR_GTPV1U_SRC}) add_dependencies(NR_GTPV1U rrc_flag) +if (${NEW_GTPU}) +set(GTPV1U GTPV1U_OCP) +else() +set(GTPV1U NR_GTPV1U) +endif() + set (MME_APP_SRC ${OPENAIR3_DIR}/MME_APP/mme_app.c ${OPENAIR3_DIR}/MME_APP/mme_config.c @@ -2864,7 +2874,6 @@ add_executable(lte-softmodem ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -2874,7 +2883,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2905,7 +2914,6 @@ add_executable(ocp-enb ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -2915,7 +2923,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l target_link_libraries (ocp-enb -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2985,7 +2993,7 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB - GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON + ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -3018,7 +3026,6 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3027,7 +3034,7 @@ add_executable(nr-softmodem target_link_libraries (nr-softmodem -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} @@ -3057,7 +3064,6 @@ add_executable(ocp-gnb ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c - ${GTPU_need_ITTI} ${XFORMS_SOURCE_NR} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3067,7 +3073,7 @@ add_executable(ocp-gnb target_link_libraries (ocp-gnb -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON @@ -3371,7 +3377,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) add_executable(test_epc_play_scenario @@ -3390,7 +3396,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) @@ -3436,7 +3442,7 @@ if (${T_TRACER}) NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB - CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB + CN_UTILS ${GTPV1U} SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts) if (TARGET ${i}) add_dependencies(${i} generate_T) @@ -3534,7 +3540,6 @@ add_executable(nr-ittisim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c - ${GTPU_need_ITTI} ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3543,7 +3548,7 @@ add_executable(nr-ittisim target_link_libraries (nr-ittisim -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h index b218d58e3d..68b05ffce3 100644 --- a/common/utils/msc/msc.h +++ b/common/utils/msc/msc.h @@ -115,7 +115,7 @@ void msc_log_message( #define MESSAGE_CHART_GENERATOR msc_interface.msc_loaded -msc_interface_t msc_interface; +extern msc_interface_t msc_interface; #define MSC_INIT(arg1,arg2) if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2) #define MSC_START_USE if(msc_interface.msc_loaded) msc_interface.msc_start_use #define MSC_END if(msc_interface.msc_loaded) msc_interface.msc_end diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index a40660eb9e..140340bacd 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -341,6 +341,7 @@ void * rrc_enb_process_msg(void*); TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\ TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ + TASK_DEF(OCP_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\ TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 6e5857d6d1..e6ce40e808 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -78,7 +78,6 @@ int otg_enabled; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int split73; -int usrp_tx_thread = 0; char * split73_config; int split73; AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0}; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index feff0c29c2..3a90edbf20 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -118,7 +118,6 @@ uint16_t sl_ahead; extern int emulate_rf; extern int numerology; -extern int usrp_tx_thread; /*************************************************************/ /* Functions to attach and configure RRU */ diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index fb757a9f47..a46e65624a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -181,7 +181,6 @@ extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; static char *parallel_config = NULL; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1d3288862d..052fb561a0 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -155,7 +155,6 @@ int card_offset = 0; uint64_t num_missed_slots = 0; // counter for the number of missed slots int transmission_mode = 1; int numerology = 0; -int usrp_tx_thread = 0; int oaisim_flag = 0; int emulate_rf = 0; diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c index 67f68f43e3..db416d1487 100644 --- a/executables/ocp-gnb.c +++ b/executables/ocp-gnb.c @@ -70,7 +70,6 @@ uint32_t timing_advance = 0; int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; int config_sync_var=-1; diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 04a58413b5..b88fe29956 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -43,6 +43,8 @@ static softmodem_params_t softmodem_params; char *parallel_config=NULL; char *worker_config=NULL; +msc_interface_t msc_interface; +int usrp_tx_thread = 0; static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS; diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index f8e9b0959f..51f14f218c 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -90,6 +90,7 @@ extern "C" #define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" +#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -113,6 +114,7 @@ extern "C" #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; +extern int usrp_tx_thread; #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ {"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\ @@ -139,6 +141,7 @@ extern "C" {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ {"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \ + {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ } diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index cfa3b93007..37cb93e96b 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -26,6 +26,7 @@ // global var for openair performance profiler int opp_enabled = 0; +double cpu_freq_GHz __attribute__ ((aligned(32))); double get_cpu_freq_GHz(void) { diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index 2deab40f27..e2ceef8405 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -33,7 +33,7 @@ #include // global var to enable openair performance profiler extern int opp_enabled; -double cpu_freq_GHz __attribute__ ((aligned(32)));; +extern double cpu_freq_GHz __attribute__ ((aligned(32)));; #if defined(__x86_64__) || defined(__i386__) typedef struct { diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 1f4db3138a..324a70fb37 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -68,6 +68,7 @@ int sl_ahead = 0; //void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); /* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +msc_interface_t msc_interface; uint64_t get_softmodem_optmask(void) {return 0;} softmodem_params_t *get_softmodem_params(void) {return 0;} diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h index 6da464aa28..bfde1b31f3 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h @@ -21,8 +21,6 @@ # ifndef __RLC_UM_TEST_H__ # define __RLC_UM_TEST_H__ -rlc_um_entity_t um_tx; -rlc_um_entity_t um_rx; void rlc_um_v9_3_0_test_windows_5(void); void rlc_um_v9_3_0_test_windows_10(void); diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 98c8c3e252..84a9cb57bd 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -52,6 +52,8 @@ extern boolean_t pdcp_data_ind( //#define TRACE_RLC_PAYLOAD 1 #define DEBUG_RLC_DATA_REQ 1 +logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ +logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ //----------------------------------------------------------------------------- void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 7e4920a579..3a37723f53 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -133,13 +133,13 @@ typedef struct { #define RLC_MAX_MBMS_LC (LTE_maxSessionPerPMCH * LTE_maxServiceCount) #define RLC_MAX_LC ((max_val_LTE_DRB_Identity+1)* MAX_MOBILES_PER_ENB) -void (*rlc_rrc_data_ind)( +extern void (*rlc_rrc_data_ind)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const sdu_size_t sdu_sizeP, const uint8_t *const sduP) __attribute__ ((aligned(32))); -void (*rlc_rrc_data_conf)( +extern void (*rlc_rrc_data_conf)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const mui_t muiP, @@ -184,8 +184,8 @@ typedef struct rlc_mbms_id_s { //rlc_mbms_t rlc_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h //rlc_mbms_t rlc_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h #define rlc_mbms_enb_get_lcid_by_rb_id(Enb_mOD,rB_iD) rlc_mbms_rbid2lcid_eNB[Enb_mOD][rB_iD] ; @@ -201,8 +201,6 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); -logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ -logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */ #define RLC_COLL_KEY_VALUE(eNB_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \ @@ -250,7 +248,7 @@ logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; (((hash_key_t)(sESSION_ID)) << 37) | \ (((hash_key_t)(0x0000000000000001)) << 63)) -hash_table_t *rlc_coll_p __attribute__ ((aligned(32))); +extern hash_table_t *rlc_coll_p __attribute__ ((aligned(32))); /*! \fn tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP) * \brief Serialize a list of transport blocks coming from RLC in order to be processed by MAC. diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index 5690b9b153..181899cd6e 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -297,7 +297,11 @@ int nas_change_mtu(struct net_device *dev, int mtu) } //--------------------------------------------------------------------------- +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) void nas_tx_timeout(struct net_device *dev) +#else +void nas_tx_timeout(struct net_device *dev, unsigned int x) +#endif { //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 32f9442747..e3c0f92ec7 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -302,7 +302,11 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) { } //--------------------------------------------------------------------------- +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) void ue_ip_tx_timeout(struct net_device *dev_pP) { +#else +void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int x) { +#endif //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. ue_ip_priv_t *priv_p = netdev_priv(dev_pP); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 18b7173a08..2564983d47 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -87,6 +87,7 @@ #include "pdcp.h" #include "gtpv1u_eNB_task.h" +#include #include "intertask_interface.h" diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 5c25d2dbcf..6111bec6a5 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -40,6 +40,7 @@ # include "common/ran_context.h" +#include extern RAN_CONTEXT_t RC; @@ -181,21 +182,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__); return; } + gtpv1u_enb_delete_tunnel_req_t tmp={0}; - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0, - "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", - ue_context_pP->ue_context.eNB_ue_s1ap_id); - - MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg))); - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs; + tmp.rnti = ue_context_pP->ue_context.rnti; + tmp.from_gnb = 0; + tmp.num_erab = ue_context_pP->ue_context.nb_of_e_rabs; for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab]; - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi; + tmp.eps_bearer_id[e_rab] = gtp_ebi; } - itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); + gtpv1u_delete_s1u_tunnel(enb_mod_idP,&tmp); } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 4be9a50b32..9edfa50f12 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -48,11 +48,12 @@ #include "pdcp_primitives.h" #include "UTIL/OSA/osa_defs.h" -#include "msc.h" +#include #include "LTE_UERadioAccessCapabilityInformation.h" #include "gtpv1u_eNB_task.h" +#include #include "RRC/LTE/rrc_eNB_GTPV1U.h" #include "TLVDecoder.h" diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index d9352f2d0a..86779e0ad9 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -148,7 +148,6 @@ extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; double cpuf; diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp new file mode 100644 index 0000000000..5a5717c726 --- /dev/null +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -0,0 +1,623 @@ +#include +#include +#include +#include +#include + +#include +#include +#include "common/utils/LOG/log.h" +#include +#include +#include +//#include +#include +using namespace std; + +#pragma pack(1) + +typedef struct Gtpv1uMsgHeader { + uint8_t PN:1; + uint8_t S:1; + uint8_t E:1; + uint8_t spare:1; + uint8_t PT:1; + uint8_t version:3; + uint8_t msgType; + uint16_t msgLength; + uint32_t teid; +} __attribute__((packed)) Gtpv1uMsgHeaderT; + +#pragma pack() + + // TS 29.060, table 7.1 defines the possible message types + // here are all the possible messages (3GPP R16) +#define GTP_ECHO_REQ (1) +#define GTP_ECHO_RSP (2) +#define GTP_ERROR_INDICATION (26) +#define GTP_SUPPORTED_EXTENSION_HEADER_INDICATION (31) +#define GTP_END_MARKER (254) +#define GTP_GPDU (255) + + +typedef struct ocp_gtpv1u_bearer_s { + /* TEID used in dl and ul */ + teid_t teid_incoming; ///< eNB TEID + teid_t teid_outgoing; ///< Remote TEID + in_addr_t outgoing_ip_addr; + struct in6_addr outgoing_ip6_addr; + tcp_udp_port_t outgoing_port; + uint16_t seqNum; + uint8_t npduNum; +} ocp_gtpv1u_bearer_t; + +typedef struct { + map bearers; +} teidData_t; + +typedef struct { + rnti_t rnti; +} rntiData_t; + +class gtpEndPoint { + public: + openAddr_t addr; + map ue2te_mapping; + map te2ue_mapping; +}; + +class gtpEndPoints { + public: + pthread_mutex_t gtp_lock=PTHREAD_MUTEX_INITIALIZER; + // the instance id will be the Linux socket handler, as this is uniq + map instances; +}; + +gtpEndPoints globGtp; + +#ifdef __cplusplus +extern "C" { +#endif + +static uint32_t gtpv1uNewTeid(void) { +#ifdef GTPV1U_LINEAR_TEID_ALLOCATION + g_gtpv1u_teid = g_gtpv1u_teid + 1; + return g_gtpv1u_teid; +#else + return random() + random() % (RAND_MAX - 1) + 1; +#endif +} + + +#define GTPV1U_HEADER_SIZE (8) +static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, uint32_t teid, uint8_t *Msg,int msgLen, + bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { + AssertFatal(extHdrFlag==false,"Not developped"); + int headerAdditional=0; + + if ( seqNumFlag || npduNumFlag || extHdrFlag) + headerAdditional=4; + + uint8_t *buffer; + int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen; + AssertFatal((buffer=(uint8_t *) malloc(fullSize)) != NULL, ""); + Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ; + msgHdr->PN=npduNumFlag; + msgHdr->S=seqNumFlag; + msgHdr->E=extHdrFlag; + msgHdr->spare=0; + msgHdr->PT=1; + msgHdr->version=1; + msgHdr->msgType=GTP_GPDU; + msgHdr->msgLength=htons(msgLen); + msgHdr->teid=htonl(teid); + + if(seqNumFlag || extHdrFlag || npduNumFlag) { + *((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000; + *((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00; + *((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00; + } + + memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen); + static struct sockaddr_in to= {0}; + to.sin_family = AF_INET; + to.sin_port = htons(peerPort); + to.sin_addr.s_addr = peerIp ; + LOG_D(GTPU,"sending packet size: %d to %s\n",fullSize, inet_ntoa(to.sin_addr) ); + + if (sendto(h, (void *)buffer, (size_t)fullSize, 0,(struct sockaddr *)&to, sizeof(to) ) != fullSize ) { + LOG_E(GTPU, + "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %u\n", + h, IPV4_ADDR_FORMAT(peerIp), peerPort, fullSize); + free(buffer); + return GTPNOK; + } + + free(buffer); + return !GTPNOK; +} + +static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) { + uint8_t *buffer=req->buffer+req->offset; + size_t length=req->length; + uint64_t rnti=req->rnti; + int rab_id=req->rab_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "Gtpv1uProcessUlpReq failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + auto ptr=ptrRnti->second.bearers; + + if ( ptr.find(rab_id) == ptr.end() ) { + LOG_E(GTPU,"sending a packet to a non existant RNTI:RAB: %lx/%x\n", rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } else + LOG_D(GTPU,"sending a packet to RNTI:RAB:teid %lx/%x/%x, len %lu, oldseq %d, oldnum %d\n", + rnti, rab_id,ptr[rab_id].teid_outgoing,length, ptr[rab_id].seqNum,ptr[rab_id].npduNum ); + + if(seqNumFlag) + ptr[rab_id].seqNum++; + + if(npduNumFlag) + ptr[rab_id].npduNum++; + + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1uCreateAndSendMsg(instance, + ptr[rab_id].outgoing_ip_addr, + ptr[rab_id].outgoing_port, + ptr[rab_id].teid_outgoing, + buffer, length, false, false, false, ptr[rab_id].seqNum, ptr[rab_id].npduNum, 0) ; +} + +static int udpServerSocket(openAddr_s addr) { + LOG_I(GTPU, "Initializing UDP for local address %s with port %s\n", addr.originHost, addr.originService); + int status; + struct addrinfo hints= {0}, *servinfo, *p; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + + if ((status = getaddrinfo(addr.originHost, addr.originService, &hints, &servinfo)) != 0) { + LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); + return -1; + } + + int sockfd=-1; + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + LOG_W(GTPU,"socket: %s\n", strerror(errno)); + continue; + } + + if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(sockfd); + LOG_W(GTPU,"bind: %s\n", strerror(errno)); + continue; + } + + break; // if we get here, we must have connected successfully + } + + if (p == NULL) { + // looped off the end of the list with no successful bind + LOG_E(GTPU,"failed to bind socket: %s %s \n", addr.originHost, addr.originService); + return -1; + } + + freeaddrinfo(servinfo); // all done with this structure + int sendbuff = 1000*1000*10; + AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); + LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff); + return sockfd; +} + +instance_t ocp_gtpv1Init(openAddr_t context) { + pthread_mutex_lock(&globGtp.gtp_lock); + int id=udpServerSocket(context); + + if (id>=0) { + globGtp.instances[id].addr=context; + itti_subscribe_event_fd(OCP_GTPV1_U, id); + } else + LOG_E(GTPU,"can't create GTP-U instance\n"); + + pthread_mutex_unlock(&globGtp.gtp_lock); + + return id; +} + +int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, + const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, + gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) { + LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %d\n", + create_tunnel_req->rnti, + create_tunnel_req->num_tunnels, + create_tunnel_req->sgw_S1u_teid[0]); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + auto it=inst->ue2te_mapping.find(create_tunnel_req->rnti); + + if ( it != inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", create_tunnel_req->rnti); + inst->ue2te_mapping.erase(it); + } + + rntiData_t rntiData= {create_tunnel_req->rnti}; + + for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { + ocp_gtpv1u_bearer_t gtpv1u_ue_data; + uint32_t s1u_teid=gtpv1uNewTeid(); + + while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { + LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid); + s1u_teid=gtpv1uNewTeid(); + }; + + inst->te2ue_mapping[s1u_teid]=rntiData; + + int addrs_length_in_bytes = create_tunnel_req->sgw_addr[i].length / 8; + + switch (addrs_length_in_bytes) { + case 4: + memcpy(>pv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4); + break; + + case 16: + memcpy(>pv1u_ue_data.outgoing_ip6_addr.s6_addr, + create_tunnel_req->sgw_addr[i].buffer, + 16); + break; + + case 20: + memcpy(>pv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4); + memcpy(>pv1u_ue_data.outgoing_ip6_addr.s6_addr, + create_tunnel_req->sgw_addr[i].buffer+4, + 16); + + default: + AssertFatal(false, "SGW Address size impossible"); + } + + gtpv1u_ue_data.teid_incoming = s1u_teid; + gtpv1u_ue_data.outgoing_port=2152; + gtpv1u_ue_data.teid_outgoing= create_tunnel_req->sgw_S1u_teid[i]; + inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]]=gtpv1u_ue_data; + LOG_D(GTPU, "Created tunnel %x for RNTI %x, SGW: " IPV4_ADDR ":%d\n", + s1u_teid, create_tunnel_req->rnti, + IPV4_ADDR_FORMAT(inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_ip_addr), + inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_port ); + create_tunnel_resp->status=0; + create_tunnel_resp->rnti=create_tunnel_req->rnti; + create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; + create_tunnel_resp->enb_S1u_teid[i]=gtpv1u_ue_data.teid_incoming; + create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i]; + //TBD: fix me this is quite bad, for IPv4 only and + // Overcomplex stuff to fill InitialContextSetupResponse in S1AP + int status; + struct addrinfo hints= {0}, *servinfo, *p; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + openAddr_t *addr=&globGtp.instances[instance].addr; + + if ((status = getaddrinfo(addr->originHost, addr->originService, &hints, &servinfo)) != 0) { + LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); + pthread_mutex_unlock(&globGtp.gtp_lock); + return -1; + } + + // TBD: we take the first IPv4 addr, but it should be coded in the right way + for(p = servinfo; p != NULL; p = p->ai_next) + if (p->ai_family == AF_INET) { + struct sockaddr_in *ipv4P=(struct sockaddr_in *)p->ai_addr; + memcpy(create_tunnel_resp->enb_addr.buffer, + &ipv4P->sin_addr.s_addr, sizeof(ipv4P->sin_addr.s_addr)); + create_tunnel_resp->enb_addr.length = sizeof(ipv4P->sin_addr.s_addr); + break; + } + + if ( p == NULL ) + LOG_E(GTPU,"can't translate IP address string: %s\n",addr->originHost); + + freeaddrinfo(servinfo); // all done with this structure + } + + pthread_mutex_unlock(&globGtp.gtp_lock); + return !GTPNOK; +} + +int ocp_gtpv1u_update_s1u_tunnel( + const instance_t instance, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req, + const rnti_t prior_rnti +) { + LOG_D(GTPU, "Start update tunnels for old RNTI %x, new RNTI %x, num_tunnels %d, sgw_S1u_teid %d, eps_bearer_id %d\n", + prior_rnti, + create_tunnel_req->rnti, + create_tunnel_req->num_tunnels, + create_tunnel_req->sgw_S1u_teid[0], + create_tunnel_req->eps_bearer_id[0]); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + + if ( inst->ue2te_mapping.find(create_tunnel_req->rnti) != inst->ue2te_mapping.end() ) { + LOG_E(GTPU,"Update a existing GTP tunnel to a already existing tunnel (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); + } + + auto it=inst->ue2te_mapping.find(prior_rnti); + + if ( it != inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); + gtpv1u_enb_create_tunnel_resp_t tmp; + (void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp); + pthread_mutex_unlock(&globGtp.gtp_lock); + return 0; + } + + inst->ue2te_mapping[create_tunnel_req->rnti]=it->second; + inst->ue2te_mapping.erase(it); + pthread_mutex_unlock(&globGtp.gtp_lock); + return 0; +} + +int ocp_gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP){ + AssertFatal( false, "to be developped\n"); +} + +int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, + const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { + LOG_D(GTPU, "Start delete tunnels for RNTI %x, num_erab %d, eps_bearer_id %d \n", + req_pP->rnti, + req_pP->num_erab, + req_pP->eps_bearer_id[0]); + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + auto it=inst->ue2te_mapping.find(req_pP->rnti); + + if ( it == inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Delete a non existing GTP tunnel\n"); + pthread_mutex_unlock(&globGtp.gtp_lock); + return -1; + } + + for (auto j=it->second.bearers.begin(); + j!=it->second.bearers.end(); + ++j) + inst->te2ue_mapping.erase(j->second.teid_incoming); + + inst->ue2te_mapping.erase(it); + pthread_mutex_unlock(&globGtp.gtp_lock); + return !GTPNOK; +} + +static int Gtpv1uHandleEchoReq(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + +static int Gtpv1uHandleError(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + +static int Gtpv1uHandleSupportedExt(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} + + static int Gtpv1uHandleEndMarker(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + LOG_E(GTPU,"to be dev\n"); + int rc = GTPNOK; + return rc; +} +static int Gtpv1uHandleGpdu(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { + Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *) msgBuf; + + if ( msgHdr->version != 1 || msgHdr->PT != 1 ) { + LOG_E(GTPU, "Received a packet that is not GTP header\n"); + return GTPNOK; + } + + pthread_mutex_lock(&globGtp.gtp_lock); + // the socket Linux file handler is the instance id + auto inst=&globGtp.instances[h]; + auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); + + if ( tunnel == inst->te2ue_mapping.end() ) { + LOG_E(GTPU,"Received a incoming packet on non open teid (%d)\n", msgHdr->teid); + pthread_mutex_unlock(&globGtp.gtp_lock); + return GTPNOK; + } + + int offset=8; + if( msgHdr->E || msgHdr->S ||msgHdr->PN) + offset+=4; + /* + gtpv1u_enb_tunnel_data_ind_t tmp; + protocol_ctxt_t ctxt; + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = 0; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 1; + ctxt.brOption = 0; + result = pdcp_data_req(&ctxt, + SRB_FLAG_YES, + RRC_DCCH_DATA_REQ(msg_p).rb_id, + RRC_DCCH_DATA_REQ(msg_p).muip, + RRC_DCCH_DATA_REQ(msg_p).confirmp, + RRC_DCCH_DATA_REQ(msg_p).sdu_size, + RRC_DCCH_DATA_REQ(msg_p).sdu_p, + RRC_DCCH_DATA_REQ(msg_p).mode, + NULL, NULL); + + + ctxt.rnti = rnti; + pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, + PDCP_TRANSMISSION_MODE_DATA, NULL, NULL); + + MessageDef *msg_p=itti_alloc_new_message_sized(OCP_GTPV1_U,GTPV1U_ENB_TUNNEL_DATA_IND, + sizeof(MessageDef) + msgBufLen); + GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer=(uint8_t *)(msg_p+1); + memcpy(GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer,msgBuf,msgBufLen); + GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).length=msgBufLen; + GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).offset=offset; + pthread_mutex_unlock(&globGtp.gtp_lock); + inst->addr.dlCallBack(msg_p); + */ + // could be a full itti msg, make it in the call back if you need + //itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(0), msg_p); + LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n", + msgBufLen-offset, + ntohl(msgHdr->teid)); + return !GTPNOK; +} + +void gtpv1uReceiver(int h) { + uint8_t udpData[65536]; + int udpDataLen; + socklen_t from_len; + struct sockaddr_in addr; + from_len = (socklen_t)sizeof(struct sockaddr_in); + + if ((udpDataLen = recvfrom(h, udpData, sizeof(udpData), 0, + (struct sockaddr *)&addr, &from_len)) < 0) { + LOG_E(GTPU, "Recvfrom failed %s\n", strerror(errno)); + return; + } else if (udpDataLen == 0) { + LOG_W(GTPU, "Recvfrom returned 0\n"); + return; + } else { + uint8_t msgType = *((uint8_t *)(udpData + 1)); + LOG_D(GTPU, "Received GTP data, msg type: %x\n", msgType); + + switch(msgType) { + case GTP_ECHO_RSP: + break; + + case GTP_ECHO_REQ: + Gtpv1uHandleEchoReq( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_ERROR_INDICATION: + Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION: + Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_END_MARKER: + Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_GPDU: + Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + default: + LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType); + break; + } + } +} + +void *ocp_gtpv1uTask(void *args) { + while(1) { + /* Trying to fetch a message from the message queue. + If the queue is empty, this function will block till a + message is sent to the task. + */ + MessageDef *message_p = NULL; + itti_receive_msg(OCP_GTPV1_U, &message_p); + + if (message_p != NULL ) { + switch (ITTI_MSG_ID(message_p)) { + // DATA TO BE SENT TO UDP + case GTPV1U_ENB_TUNNEL_DATA_REQ: { + gtpv1uSend(ITTI_MESSAGE_GET_INSTANCE(message_p), + >PV1U_ENB_TUNNEL_DATA_REQ(message_p), false, false); + itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); + } + break; + + case TERMINATE_MESSAGE: + break; + + case TIMER_HAS_EXPIRED: + LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p)); + break; + + + case GTPV1U_ENB_DATA_FORWARDING_REQ: + case GTPV1U_ENB_DATA_FORWARDING_IND: + case GTPV1U_ENB_END_MARKER_REQ: + case GTPV1U_ENB_END_MARKER_IND: + case GTPV1U_ENB_S1_REQ: + LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); + abort(); + break; + + default: + LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + abort(); + break; + } + + AssertFatal(EXIT_SUCCESS==itti_free(OCP_GTPV1_U, message_p), "Failed to free memory!\n"); + } + + struct epoll_event *events; + + int nb_events = itti_get_events(OCP_GTPV1_U, &events); + + if (nb_events > 0 && events!= NULL ) + for (int i = 0; i < nb_events; i++) + gtpv1uReceiver(events[i].data.fd); + } + + return NULL; +} + +#ifdef __cplusplus +} +#endif diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h new file mode 100644 index 0000000000..e09f2194eb --- /dev/null +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -0,0 +1,49 @@ +#ifndef __UDP_ITF_H__ +#define __UDP_ITF_H__ +#define GTPNOK -1 + +# define GTPU_HEADER_OVERHEAD_MAX 64 +#ifdef __cplusplus +extern "C" { +#endif + +#include +#if defined(NEW_GTPU) + #define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel + #define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel + #define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel + #define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel + #endif + +typedef struct openAddr_s { + char originHost[HOST_NAME_MAX]; + char originService[HOST_NAME_MAX]; + char destinationHost[HOST_NAME_MAX]; + char destinationService[HOST_NAME_MAX]; + instance_t originInstance; +} openAddr_t; + +// the init function create a gtp instance and return the gtp instance id +// the parameter originInstance will be sent back in each message from gtp to the creator +instance_t ocp_gtpv1Init(openAddr_t context); +void ocp_gtpv1uReceiver(int h); +void ocp_gtpv1uProcessTimeout(int handle,void *arg); +int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, + gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp); +int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req_pP, + const rnti_t prior_rnti + ); +int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); +int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); + + int ocp_gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP); + void *ocp_gtpv1uTask(void *args); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index dd29d01fae..851082f44b 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1329,7 +1329,7 @@ extern "C" { if(is_equal(s->sample_rate, (double)7.68e6)) s->tx_forward_nsamps = 50; - + if (device->recplay_state != NULL) { // record mode device->recplay_state->ms_sample = (iqrec_t *) malloc(openair0_cfg[0].recplay_conf->u_sf_max * sizeof(iqrec_t)); diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 4d57ab4e16..3e0d97f60a 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -42,6 +42,7 @@ # include "enb_app.h" # include "openair2/LAYER2/MAC/mac_proto.h" #include +#include extern RAN_CONTEXT_t RC; diff --git a/targets/COMMON/create_tasks_mbms.c b/targets/COMMON/create_tasks_mbms.c index 5f81592b96..579e851ea7 100644 --- a/targets/COMMON/create_tasks_mbms.c +++ b/targets/COMMON/create_tasks_mbms.c @@ -47,6 +47,7 @@ # include "mce_app.h" # include "mme_app.h" +#include //extern RAN_CONTEXT_t RC; int create_tasks_mbms(uint32_t enb_nb) { diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 0d0dde4ac4..1fa6c594d6 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -170,7 +170,6 @@ extern void init_eNB_afterRU(void); int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -int usrp_tx_thread = 0; THREAD_STRUCT thread_struct; /* struct for ethernet specific parameters given in eNB conf file */ diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 2bf2314f1b..f7dfed80e5 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -168,7 +168,6 @@ extern void get_uethreads_params(void); int transmission_mode=1; -int usrp_tx_thread = 0; char *usrp_args=NULL; From 954b0f559d83304754ee06be8b338e7fc4628eba Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Mon, 25 Jan 2021 12:59:38 +0100 Subject: [PATCH 2/5] new gtp before tests --- cmake_targets/CMakeLists.txt | 4 +- doc/SW_archi.md | 22 ++ openair2/COMMON/gtpv1_u_messages_types.h | 2 + openair2/ENB_APP/enb_config.c | 5 +- openair2/GNB_APP/gnb_config.c | 6 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 3 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 7 +- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 3 +- openair2/RRC/LTE/rrc_eNB.c | 2 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 3 +- openair3/ocp-gtpu/gtp_itf.cpp | 369 +++++++++++----------- openair3/ocp-gtpu/gtp_itf.h | 49 ++- 13 files changed, 274 insertions(+), 203 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 1b93dea0c0..1a4a0a88f7 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2883,8 +2883,8 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE ${GTPV1U} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) diff --git a/doc/SW_archi.md b/doc/SW_archi.md index 412dad402d..f6114c33c2 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -296,6 +296,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern ## inside other threads gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex. +# New GTP +## initialization +Coexistance until full merge with legacy GTP +cmake new option: NEW_GTPU to use the new implementation (it changes for the entire executable) +It is possible to use both old and new GTP in same executable because the itti task and all functions names are different +Current status of new implementation: not tested, X2 not developped, 5G new GTP option not developped, remain issues on data coming from void: muid, enb_flag, ... + +ocp_gtpv1uTask(): this creates only the thread, doesn't configure anything +gtpv1Init(): creates a listening socket to Linux for a given reception and select a local IP address + +newGtpuCreateTunnel() this function will replace the xxx_create_tunnel_xxx() for various cases +This creates a outgoing context for a teid (in input), it computes and return the incoming teid that will be used for incoming packets +These teids and in a "instance", so in a Linux socket: same teid can co-exist for different sockets + Remain here a lack to fill: the information given in the legacy funtions is not enough to fullfil the data needed by the callback +stuff like enb_flag, but also mui and more important data are not given explicitly by any legacy function (gtpv1u_create_s1u_tunnel), but the legacy and the new interface to lower layer (like pdcp) require this data. +The datamodel is still not fully understood, so this data source remain unknown +A new parameter is the callback function: will be pdpcp_data_req() and gtpv_data_req() (x2 case) for existing implementation and later other call backs like the F1-U implementation. + +incoming packets +the gtp layer retrieves the data, the teid, find out the related data: rnti, bearer and quite a lot of other parameters (not clear why, because it looks like all is statefull, so the lower layer should have the context) +if lower layers can be stateless, it is a good idea to keep the context in the gtp layer and pass it to the callback, but the design remain obfuscated. + # NGAP NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)? About all messages are exchanged with RRC thread diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 14b6e7c0b1..a0c1a9e817 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -170,6 +170,8 @@ typedef struct gtpv1u_enb_end_marker_ind_s { typedef struct { in_addr_t enb_ip_address_for_S1u_S12_S4_up; tcp_udp_port_t enb_port_for_S1u_S12_S4_up; + char addrStr[256]; + char portStr[256]; } Gtpv1uS1Req; #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index de77d783c7..9b0bc14f70 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -57,6 +57,7 @@ #include "enb_paramdef.h" #include "proto_agent.h" #include "executables/thread-common.h" +#include extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); @@ -2055,7 +2056,9 @@ int RCconfig_gtpu(void ) { IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address); + sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U); + itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for S1U\n"); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 3785ded9e9..19ff268668 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -57,6 +57,7 @@ //#include "RRC_config_tools.h" #include "gnb_paramdef.h" #include "NR_MAC_gNB/mac_proto.h" +#include #include "NR_asn_constant.h" #include "executables/thread-common.h" @@ -740,8 +741,9 @@ int RCconfig_nr_gtpu(void ) { LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU; } - - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address); + sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU); + itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for NGU\n"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 9b6de7c168..9c5438b589 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -61,6 +61,7 @@ # include "gtpv1u_eNB_task.h" # include "gtpv1u.h" +#include #include "ENB_APP/enb_config.h" @@ -937,7 +938,7 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); packet_forwarded = TRUE; } } else { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index c8ab4499ee..52efc3c03e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s { * \note None * @ingroup _pdcp */ + boolean_t pdcp_data_req( protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, const mui_t muiP, - const confirm_t confirmP, \ + const confirm_t confirmP, const sdu_size_t sdu_buffer_size, unsigned char *const sdu_buffer, const pdcp_transmission_mode_t mode, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id + const uint32_t * sourceL2Id, + const uint32_t * destinationL2Id ); /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 9b33b2715d..1e5ec1ee59 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -33,6 +33,7 @@ /* from OAI */ #include "pdcp.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" +#include #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -442,7 +443,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); //printf("\n"); - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); } } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 2564983d47..5624bf80d8 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -5034,7 +5034,7 @@ void rrc_eNB_handover_ue_context_release( ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, ctxt_pP->module_id, msg_delete_tunnels_p); struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 9edfa50f12..49450e2deb 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1763,7 +1763,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms } } - itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, instance, msg_delete_tunnels_p); //S1AP_E_RAB_RELEASE_RESPONSE rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 8f1fa9f81f..e1c511c4f9 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -39,6 +39,7 @@ #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" #include "executables/softmodem-common.h" #include +#include extern boolean_t nr_rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, @@ -341,7 +342,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; } - itti_send_msg_to_task(TASK_GTPV1_U, rrc->module_id, msg_delete_tunnels_p); + itti_send_msg_to_task(TASK_VARIABLE, rrc->module_id, msg_delete_tunnels_p); /* remove context */ rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 5a5717c726..f9fc506860 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1,3 +1,9 @@ +#include +using namespace std; + +#ifdef __cplusplus +extern "C" { +#endif #include #include #include @@ -10,9 +16,8 @@ #include #include #include +#include //#include -#include -using namespace std; #pragma pack(1) @@ -25,13 +30,13 @@ typedef struct Gtpv1uMsgHeader { uint8_t version:3; uint8_t msgType; uint16_t msgLength; - uint32_t teid; + teid_t teid; } __attribute__((packed)) Gtpv1uMsgHeaderT; #pragma pack() - // TS 29.060, table 7.1 defines the possible message types - // here are all the possible messages (3GPP R16) +// TS 29.060, table 7.1 defines the possible message types +// here are all the possible messages (3GPP R16) #define GTP_ECHO_REQ (1) #define GTP_ECHO_RSP (2) #define GTP_ERROR_INDICATION (26) @@ -57,11 +62,14 @@ typedef struct { typedef struct { rnti_t rnti; + gtpCallback callBack; } rntiData_t; class gtpEndPoint { public: openAddr_t addr; + uint8_t foundAddr[20]; + int foundAddrLen; map ue2te_mapping; map te2ue_mapping; }; @@ -75,10 +83,6 @@ class gtpEndPoints { gtpEndPoints globGtp; -#ifdef __cplusplus -extern "C" { -#endif - static uint32_t gtpv1uNewTeid(void) { #ifdef GTPV1U_LINEAR_TEID_ALLOCATION g_gtpv1u_teid = g_gtpv1u_teid + 1; @@ -90,7 +94,7 @@ static uint32_t gtpv1uNewTeid(void) { #define GTPV1U_HEADER_SIZE (8) -static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, uint32_t teid, uint8_t *Msg,int msgLen, +static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen, bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { AssertFatal(extHdrFlag==false,"Not developped"); int headerAdditional=0; @@ -203,6 +207,11 @@ static int udpServerSocket(openAddr_s addr) { close(sockfd); LOG_W(GTPU,"bind: %s\n", strerror(errno)); continue; + } else { + // We create the gtp instance on the socket + globGtp.instances[sockfd].addr=addr; + memcpy(globGtp.instances[sockfd].foundAddr, p->ai_addr, p->ai_addrlen); + globGtp.instances[sockfd].foundAddrLen=p->ai_addrlen; } break; // if we get here, we must have connected successfully @@ -215,6 +224,28 @@ static int udpServerSocket(openAddr_s addr) { } freeaddrinfo(servinfo); // all done with this structure + + if (strlen(addr.destinationHost)>1) { + struct addrinfo hints; + memset(&hints,0,sizeof(hints)); + hints.ai_family=AF_UNSPEC; + hints.ai_socktype=SOCK_DGRAM; + hints.ai_protocol=0; + hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG; + struct addrinfo *res=0; + int err=getaddrinfo(addr.destinationHost,addr.destinationService,&hints,&res); + + if (err==0) { + for(p = res; p != NULL; p = p->ai_next) { + if ((err=connect(sockfd, p->ai_addr, p->ai_addrlen))==0) + break; + } + } + + if (err) + LOG_E(GTPU,"Can't filter remote host: %s, %s\n", addr.destinationHost,addr.destinationService); + } + int sendbuff = 1000*1000*10; AssertFatal(0==setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)),""); LOG_D(GTPU,"Created listener for paquets to: %s:%s, send buffer size: %d\n", addr.originHost, addr.originService,sendbuff); @@ -226,16 +257,66 @@ instance_t ocp_gtpv1Init(openAddr_t context) { int id=udpServerSocket(context); if (id>=0) { - globGtp.instances[id].addr=context; itti_subscribe_event_fd(OCP_GTPV1_U, id); } else LOG_E(GTPU,"can't create GTP-U instance\n"); pthread_mutex_unlock(&globGtp.gtp_lock); - return id; } +teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[instance]; + auto it=inst->ue2te_mapping.find(rnti); + + if ( it != inst->ue2te_mapping.end() ) { + LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", rnti); + inst->ue2te_mapping.erase(it); + } + + uint32_t s1u_teid=gtpv1uNewTeid(); + + while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { + LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid); + s1u_teid=gtpv1uNewTeid(); + }; + + inst->te2ue_mapping[s1u_teid].rnti=rnti; + + inst->te2ue_mapping[s1u_teid].callBack=callBack; + + auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id]; + + int addrs_length_in_bytes = remoteAddr.length / 8; + + switch (addrs_length_in_bytes) { + case 4: + memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4); + break; + + case 16: + memcpy(tmp->outgoing_ip6_addr.s6_addr,remoteAddr.buffer, + 16); + break; + + case 20: + memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4); + memcpy(&tmp->outgoing_ip6_addr.s6_addr, + remoteAddr.buffer+4, + 16); + + default: + AssertFatal(false, "SGW Address size impossible"); + } + + tmp->teid_incoming = s1u_teid; + tmp->outgoing_port=port; + tmp->teid_outgoing= teid; + pthread_mutex_unlock(&globGtp.gtp_lock); + return s1u_teid; +} + int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) { @@ -243,96 +324,23 @@ int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, create_tunnel_req->rnti, create_tunnel_req->num_tunnels, create_tunnel_req->sgw_S1u_teid[0]); - pthread_mutex_lock(&globGtp.gtp_lock); - auto inst=&globGtp.instances[instance]; - auto it=inst->ue2te_mapping.find(create_tunnel_req->rnti); - - if ( it != inst->ue2te_mapping.end() ) { - LOG_W(GTPU,"Create a config for a already existing GTP tunnel (rnti %x)\n", create_tunnel_req->rnti); - inst->ue2te_mapping.erase(it); - } - - rntiData_t rntiData= {create_tunnel_req->rnti}; for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { - ocp_gtpv1u_bearer_t gtpv1u_ue_data; - uint32_t s1u_teid=gtpv1uNewTeid(); - - while ( inst->te2ue_mapping.find(s1u_teid) != inst->te2ue_mapping.end() ) { - LOG_W(GTPU, "generated a random Teid that exists, re-generating (%u)\n",s1u_teid); - s1u_teid=gtpv1uNewTeid(); - }; - - inst->te2ue_mapping[s1u_teid]=rntiData; - - int addrs_length_in_bytes = create_tunnel_req->sgw_addr[i].length / 8; - - switch (addrs_length_in_bytes) { - case 4: - memcpy(>pv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4); - break; - - case 16: - memcpy(>pv1u_ue_data.outgoing_ip6_addr.s6_addr, - create_tunnel_req->sgw_addr[i].buffer, - 16); - break; - - case 20: - memcpy(>pv1u_ue_data.outgoing_ip_addr,create_tunnel_req->sgw_addr[i].buffer,4); - memcpy(>pv1u_ue_data.outgoing_ip6_addr.s6_addr, - create_tunnel_req->sgw_addr[i].buffer+4, - 16); - - default: - AssertFatal(false, "SGW Address size impossible"); - } - - gtpv1u_ue_data.teid_incoming = s1u_teid; - gtpv1u_ue_data.outgoing_port=2152; - gtpv1u_ue_data.teid_outgoing= create_tunnel_req->sgw_S1u_teid[i]; - inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]]=gtpv1u_ue_data; - LOG_D(GTPU, "Created tunnel %x for RNTI %x, SGW: " IPV4_ADDR ":%d\n", - s1u_teid, create_tunnel_req->rnti, - IPV4_ADDR_FORMAT(inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_ip_addr), - inst->ue2te_mapping[create_tunnel_req->rnti].bearers[create_tunnel_req->eps_bearer_id[i]].outgoing_port ); + teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti, + create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->sgw_addr[i], 2152, + pdcp_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; - create_tunnel_resp->enb_S1u_teid[i]=gtpv1u_ue_data.teid_incoming; + create_tunnel_resp->enb_S1u_teid[i]=teid; create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i]; - //TBD: fix me this is quite bad, for IPv4 only and - // Overcomplex stuff to fill InitialContextSetupResponse in S1AP - int status; - struct addrinfo hints= {0}, *servinfo, *p; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_PASSIVE; - openAddr_t *addr=&globGtp.instances[instance].addr; - - if ((status = getaddrinfo(addr->originHost, addr->originService, &hints, &servinfo)) != 0) { - LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); - pthread_mutex_unlock(&globGtp.gtp_lock); - return -1; - } - - // TBD: we take the first IPv4 addr, but it should be coded in the right way - for(p = servinfo; p != NULL; p = p->ai_next) - if (p->ai_family == AF_INET) { - struct sockaddr_in *ipv4P=(struct sockaddr_in *)p->ai_addr; - memcpy(create_tunnel_resp->enb_addr.buffer, - &ipv4P->sin_addr.s_addr, sizeof(ipv4P->sin_addr.s_addr)); - create_tunnel_resp->enb_addr.length = sizeof(ipv4P->sin_addr.s_addr); - break; - } - - if ( p == NULL ) - LOG_E(GTPU,"can't translate IP address string: %s\n",addr->originHost); - - freeaddrinfo(servinfo); // all done with this structure + memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[instance].foundAddr, + globGtp.instances[instance].foundAddrLen); + create_tunnel_resp->enb_addr.length= globGtp.instances[instance].foundAddrLen; } - pthread_mutex_unlock(&globGtp.gtp_lock); return !GTPNOK; } @@ -358,9 +366,9 @@ int ocp_gtpv1u_update_s1u_tunnel( if ( it != inst->ue2te_mapping.end() ) { LOG_W(GTPU,"Update a not existing tunnel, start create the new one (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); gtpv1u_enb_create_tunnel_resp_t tmp; (void)ocp_gtpv1u_create_s1u_tunnel(instance, create_tunnel_req, &tmp); - pthread_mutex_unlock(&globGtp.gtp_lock); return 0; } @@ -369,16 +377,16 @@ int ocp_gtpv1u_update_s1u_tunnel( pthread_mutex_unlock(&globGtp.gtp_lock); return 0; } - + int ocp_gtpv1u_create_x2u_tunnel( const instance_t instanceP, - const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP){ + const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP) { AssertFatal( false, "to be developped\n"); } - + int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, - const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { + const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { LOG_D(GTPU, "Start delete tunnels for RNTI %x, num_erab %d, eps_bearer_id %d \n", req_pP->rnti, req_pP->num_erab, @@ -422,22 +430,22 @@ static int Gtpv1uHandleError(int h, int rc = GTPNOK; return rc; } - + static int Gtpv1uHandleSupportedExt(int h, - uint8_t *msgBuf, - uint32_t msgBufLen, - uint16_t peerPort, - uint32_t peerIp) { + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { LOG_E(GTPU,"to be dev\n"); int rc = GTPNOK; return rc; } - - static int Gtpv1uHandleEndMarker(int h, - uint8_t *msgBuf, - uint32_t msgBufLen, - uint16_t peerPort, - uint32_t peerIp) { + +static int Gtpv1uHandleEndMarker(int h, + uint8_t *msgBuf, + uint32_t msgBufLen, + uint16_t peerPort, + uint32_t peerIp) { LOG_E(GTPU,"to be dev\n"); int rc = GTPNOK; return rc; @@ -460,52 +468,52 @@ static int Gtpv1uHandleGpdu(int h, auto tunnel=inst->te2ue_mapping.find(ntohl(msgHdr->teid)); if ( tunnel == inst->te2ue_mapping.end() ) { - LOG_E(GTPU,"Received a incoming packet on non open teid (%d)\n", msgHdr->teid); + LOG_E(GTPU,"Received a incoming packet on unknown teid (%d) Dropping!\n", msgHdr->teid); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; } int offset=8; + if( msgHdr->E || msgHdr->S ||msgHdr->PN) offset+=4; - /* - gtpv1u_enb_tunnel_data_ind_t tmp; + + // This context is not good for gtp + // frame, ... has no meaning + // manyother attributes may come from create tunnel protocol_ctxt_t ctxt; - ctxt.module_id = 0; - ctxt.enb_flag = 1; - ctxt.instance = 0; - ctxt.frame = 0; - ctxt.subframe = 0; - ctxt.eNB_index = 0; - ctxt.configured = 1; - ctxt.brOption = 0; - result = pdcp_data_req(&ctxt, - SRB_FLAG_YES, - RRC_DCCH_DATA_REQ(msg_p).rb_id, - RRC_DCCH_DATA_REQ(msg_p).muip, - RRC_DCCH_DATA_REQ(msg_p).confirmp, - RRC_DCCH_DATA_REQ(msg_p).sdu_size, - RRC_DCCH_DATA_REQ(msg_p).sdu_p, - RRC_DCCH_DATA_REQ(msg_p).mode, - NULL, NULL); - - - ctxt.rnti = rnti; - pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, - PDCP_TRANSMISSION_MODE_DATA, NULL, NULL); - - MessageDef *msg_p=itti_alloc_new_message_sized(OCP_GTPV1_U,GTPV1U_ENB_TUNNEL_DATA_IND, - sizeof(MessageDef) + msgBufLen); - GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer=(uint8_t *)(msg_p+1); - memcpy(GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).buffer,msgBuf,msgBufLen); - GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).length=msgBufLen; - GTPV1U_ENB_TUNNEL_DATA_IND(msg_p).offset=offset; + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = inst->addr.originInstance; + ctxt.rnti = tunnel->second.rnti; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 1; + ctxt.brOption = 0; + const srb_flag_t srb_flag=SRB_FLAG_NO; + const rb_id_t rb_id=0; + const mui_t mui=RLC_MUI_UNDEFINED; + const confirm_t confirm=RLC_SDU_CONFIRM_NO; + const sdu_size_t sdu_buffer_size=msgBufLen-offset; + unsigned char *const sdu_buffer=msgBuf+offset; + const pdcp_transmission_mode_t mode=PDCP_TRANSMISSION_MODE_DATA; + const uint32_t sourceL2Id=0; + const uint32_t destinationL2Id=0; pthread_mutex_unlock(&globGtp.gtp_lock); - inst->addr.dlCallBack(msg_p); - */ - // could be a full itti msg, make it in the call back if you need - //itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(0), msg_p); + + if ( !tunnel->second.callBack(&ctxt, + srb_flag, + rb_id, + mui, + confirm, + sdu_buffer_size, + sdu_buffer, + mode, + &sourceL2Id, + &destinationL2Id) ) + LOG_E(GTPU,"down layer refused incoming packet\n"); + LOG_D(GTPU,"Received a %d bytes packet for: teid:%x\n", msgBufLen-offset, ntohl(msgHdr->teid)); @@ -541,26 +549,28 @@ void gtpv1uReceiver(int h) { case GTP_ERROR_INDICATION: Gtpv1uHandleError( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); break; - - case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION: + + case GTP_SUPPORTED_EXTENSION_HEADER_INDICATION: Gtpv1uHandleSupportedExt( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); - break; - - case GTP_END_MARKER: - Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); - break; - - case GTP_GPDU: - Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); - break; - - default: - LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType); - break; + break; + + case GTP_END_MARKER: + Gtpv1uHandleEndMarker( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + case GTP_GPDU: + Gtpv1uHandleGpdu( h, udpData, udpDataLen, htons(addr.sin_port), addr.sin_addr.s_addr); + break; + + default: + LOG_E(GTPU, "Received a GTP packet of unknown type: %d\n",msgType); + break; } } } +#include + void *ocp_gtpv1uTask(void *args) { while(1) { /* Trying to fetch a message from the message queue. @@ -571,6 +581,8 @@ void *ocp_gtpv1uTask(void *args) { itti_receive_msg(OCP_GTPV1_U, &message_p); if (message_p != NULL ) { + openAddr_t addr= {0}; + switch (ITTI_MSG_ID(message_p)) { // DATA TO BE SENT TO UDP case GTPV1U_ENB_TUNNEL_DATA_REQ: { @@ -587,19 +599,24 @@ void *ocp_gtpv1uTask(void *args) { LOG_E(GTPU, "Received unexpected timer expired (no need of timers in this version) %s\n", ITTI_MSG_NAME(message_p)); break; - - case GTPV1U_ENB_DATA_FORWARDING_REQ: - case GTPV1U_ENB_DATA_FORWARDING_IND: - case GTPV1U_ENB_END_MARKER_REQ: - case GTPV1U_ENB_END_MARKER_IND: - case GTPV1U_ENB_S1_REQ: - LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); - abort(); - break; - - default: - LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - abort(); + case GTPV1U_ENB_DATA_FORWARDING_REQ: + case GTPV1U_ENB_DATA_FORWARDING_IND: + case GTPV1U_ENB_END_MARKER_REQ: + case GTPV1U_ENB_END_MARKER_IND: + LOG_E(GTPU, "to be developped %s\n", ITTI_MSG_NAME(message_p)); + abort(); + break; + + case GTPV1U_ENB_S1_REQ: + // to be dev: should be removed, to use API + strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); + strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr); + AssertFatal(ocp_gtpv1Init(addr),"Only one instance 0 supprted\n"); + break; + + default: + LOG_E(GTPU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + abort(); break; } diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index e09f2194eb..24b1adaa6f 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -1,5 +1,5 @@ -#ifndef __UDP_ITF_H__ -#define __UDP_ITF_H__ +#ifndef __GTPUNEW_ITF_H__ +#define __GTPUNEW_ITF_H__ #define GTPNOK -1 # define GTPU_HEADER_OVERHEAD_MAX 64 @@ -9,11 +9,27 @@ extern "C" { #include #if defined(NEW_GTPU) - #define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel - #define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel - #define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel - #define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel - #endif +#define gtpv1u_create_s1u_tunnel ocp_gtpv1u_create_s1u_tunnel +#define gtpv1u_update_s1u_tunnel ocp_gtpv1u_update_s1u_tunnel +#define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel +#define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel +#define gtpv1u_eNB_task ocp_gtpv1uTask +#define TASK_VARIABLE OCP_GTPV1_U +#else +#define TASK_VARIABLE TASK_GTPV1_U +#endif + +typedef boolean_t (*gtpCallback)( + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id); typedef struct openAddr_s { char originHost[HOST_NAME_MAX]; @@ -25,7 +41,6 @@ typedef struct openAddr_s { // the init function create a gtp instance and return the gtp instance id // the parameter originInstance will be sent back in each message from gtp to the creator -instance_t ocp_gtpv1Init(openAddr_t context); void ocp_gtpv1uReceiver(int h); void ocp_gtpv1uProcessTimeout(int handle,void *arg); int ocp_gtpv1u_create_s1u_tunnel(const instance_t instance, const gtpv1u_enb_create_tunnel_req_t *create_tunnel_req, @@ -36,13 +51,19 @@ int ocp_gtpv1u_update_s1u_tunnel(const instance_t instanceP, ); int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); int gtpv1u_delete_s1u_tunnel( const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP); - - int ocp_gtpv1u_create_x2u_tunnel( + +int ocp_gtpv1u_create_x2u_tunnel( const instance_t instanceP, - const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP); - void *ocp_gtpv1uTask(void *args); - + const gtpv1u_enb_create_x2u_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t *const create_tunnel_resp_pP); + + +// New API +teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid_t teid, + transport_layer_addr_t remoteAddr, int port, gtpCallback callBack); +instance_t ocp_gtpv1Init(openAddr_t context); +void *ocp_gtpv1uTask(void *args); + #ifdef __cplusplus } #endif From 4b345f1589bdeaf8cae9cd5bd022aa19ababceb2 Mon Sep 17 00:00:00 2001 From: laurent Date: Wed, 27 Jan 2021 15:09:00 +0100 Subject: [PATCH 3/5] tested with one UE, better intergration with legacy gtpu --- common/utils/ocp_itti/intertask_interface.h | 3 + openair2/LAYER2/MAC/eNB_scheduler_mch.c | 2 +- openair2/LAYER2/MAC/mac_extern.h | 1 + openair2/LAYER2/MAC/pre_processor.c | 3 +- openair2/LAYER2/MAC/ue_procedures.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 3 - openair3/ocp-gtpu/gtp_itf.cpp | 74 +++++++++++++-------- 7 files changed, 56 insertions(+), 32 deletions(-) diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 140340bacd..7df88c20a6 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -472,6 +472,9 @@ void itti_subscribe_event_fd(task_id_t task_id, int fd); void itti_unsubscribe_event_fd(task_id_t task_id, int fd); /** \brief Return the list of events excluding the fd associated with itti + \the fd associated with itti can return, but it is marked events[i].events &= ~EPOLLIN + \as it is not EPOLLIN, the reader should ignore this fd + \or it can manage the list of fd's in his interest, so ignore the other ones \param task_id Task ID of the task \param events events list @returns number of events to handle diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index f3a77ed703..1272b16ec0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -84,7 +84,7 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, static uint32_t bytes_in_buffer=0; static uint32_t msi_pmch_stop=0; -uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; +rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static uint32_t msi_sfs=0; diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index cee6066a9e..bc11c5aad6 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -77,4 +77,5 @@ extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern mac_rlc_am_muilist_t rlc_am_mui; extern SCHEDULER_MODES global_scheduler_mode; +extern rb_id_t mbms_rab_id; #endif //DEF_H diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e720c1dfec..206f9f2255 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -734,7 +734,8 @@ void calculate_max_mcs_min_rb(module_id_t mod_id, /* find maximum MCS */ while ((phr - *tx_power < 0 || tbs > bytes) && *mcs > 3) { - mcs--; + *mcs=*mcs-1; + AssertFatal(*rb_index < 34, ""); tbs = get_TBS_UL(*mcs, rb_table[*rb_index]); *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0); } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 8c4ee72380..6d5c2fc395 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -72,7 +72,7 @@ extern UL_IND_t *UL_INFO; extern int next_ra_frame; extern module_id_t next_Mod_id; -int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; +rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047}; static int mbms_mch_i=0; //static int num_msi_per_CSA[28]; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 04b9e188e6..0153d80401 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -78,9 +78,6 @@ extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; extern int nas_sock_mbms_fd; -extern int mbms_rab_id; - - extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index f9fc506860..0776a3863e 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -62,6 +62,7 @@ typedef struct { typedef struct { rnti_t rnti; + ebi_t rb_id; gtpCallback callBack; } rntiData_t; @@ -92,6 +93,8 @@ static uint32_t gtpv1uNewTeid(void) { #endif } +int legacyInstanceMapping=0; +#define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a) #define GTPV1U_HEADER_SIZE (8) static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen, @@ -147,11 +150,11 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b uint64_t rnti=req->rnti; int rab_id=req->rab_id; pthread_mutex_lock(&globGtp.gtp_lock); - auto inst=&globGtp.instances[instance]; + auto inst=&globGtp.instances[compatInst(instance)]; auto ptrRnti=inst->ue2te_mapping.find(rnti); if ( ptrRnti==inst->ue2te_mapping.end() ) { - LOG_E(GTPU, "Gtpv1uProcessUlpReq failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); + LOG_E(GTPU, "gtpv1uSend failed: while getting ue rnti %lx in hashtable ue_mapping\n", rnti); pthread_mutex_unlock(&globGtp.gtp_lock); return; } @@ -173,7 +176,7 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b ptr[rab_id].npduNum++; pthread_mutex_unlock(&globGtp.gtp_lock); - gtpv1uCreateAndSendMsg(instance, + gtpv1uCreateAndSendMsg(compatInst(instance), ptr[rab_id].outgoing_ip_addr, ptr[rab_id].outgoing_port, ptr[rab_id].teid_outgoing, @@ -210,8 +213,21 @@ static int udpServerSocket(openAddr_s addr) { } else { // We create the gtp instance on the socket globGtp.instances[sockfd].addr=addr; - memcpy(globGtp.instances[sockfd].foundAddr, p->ai_addr, p->ai_addrlen); - globGtp.instances[sockfd].foundAddrLen=p->ai_addrlen; + + if (p->ai_family == AF_INET) { + struct sockaddr_in *ipv4=(struct sockaddr_in *)p->ai_addr; + memcpy(globGtp.instances[sockfd].foundAddr, + &ipv4->sin_addr.s_addr, sizeof(ipv4->sin_addr.s_addr)); + globGtp.instances[sockfd].foundAddrLen=sizeof(ipv4->sin_addr.s_addr); + break; + } else if (p->ai_family == AF_INET6) { + LOG_W(GTPU,"Local address is IP v6\n"); + struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)p->ai_addr; + memcpy(globGtp.instances[sockfd].foundAddr, + &ipv6->sin6_addr.s6_addr, sizeof(ipv6->sin6_addr.s6_addr)); + globGtp.instances[sockfd].foundAddrLen=sizeof(ipv6->sin6_addr.s6_addr); + } else + AssertFatal(false,"Local address is not IPv4 or IPv6"); } break; // if we get here, we must have connected successfully @@ -284,6 +300,8 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int bearer_id, teid inst->te2ue_mapping[s1u_teid].rnti=rnti; + inst->te2ue_mapping[s1u_teid].rb_id= teid; + inst->te2ue_mapping[s1u_teid].callBack=callBack; auto tmp=&inst->ue2te_mapping[rnti].bearers[bearer_id]; @@ -326,9 +344,9 @@ int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, create_tunnel_req->sgw_S1u_teid[0]); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { - teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti, - create_tunnel_req->eps_bearer_id[i], + teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->sgw_S1u_teid[i], create_tunnel_req->sgw_addr[i], 2152, pdcp_data_req); create_tunnel_resp->status=0; @@ -336,9 +354,9 @@ int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; create_tunnel_resp->enb_S1u_teid[i]=teid; create_tunnel_resp->eps_bearer_id[i] = create_tunnel_req->eps_bearer_id[i]; - memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[instance].foundAddr, - globGtp.instances[instance].foundAddrLen); - create_tunnel_resp->enb_addr.length= globGtp.instances[instance].foundAddrLen; + memcpy(create_tunnel_resp->enb_addr.buffer,globGtp.instances[compatInst(instance)].foundAddr, + globGtp.instances[compatInst(instance)].foundAddrLen); + create_tunnel_resp->enb_addr.length= globGtp.instances[compatInst(instance)].foundAddrLen; } return !GTPNOK; @@ -356,7 +374,7 @@ int ocp_gtpv1u_update_s1u_tunnel( create_tunnel_req->sgw_S1u_teid[0], create_tunnel_req->eps_bearer_id[0]); pthread_mutex_lock(&globGtp.gtp_lock); - auto inst=&globGtp.instances[instance]; + auto inst=&globGtp.instances[compatInst(instance)]; if ( inst->ue2te_mapping.find(create_tunnel_req->rnti) != inst->ue2te_mapping.end() ) { LOG_E(GTPU,"Update a existing GTP tunnel to a already existing tunnel (new rnti %x, old rnti %x)\n", create_tunnel_req->rnti, prior_rnti); @@ -385,15 +403,12 @@ int ocp_gtpv1u_create_x2u_tunnel( AssertFatal( false, "to be developped\n"); } -int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, - const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { - LOG_D(GTPU, "Start delete tunnels for RNTI %x, num_erab %d, eps_bearer_id %d \n", - req_pP->rnti, - req_pP->num_erab, - req_pP->eps_bearer_id[0]); +int newGtpuDeleteTunnel(instance_t instance, rnti_t rnti) { + LOG_D(GTPU, "Start delete tunnels for RNTI %x\n", + rnti); pthread_mutex_lock(&globGtp.gtp_lock); - auto inst=&globGtp.instances[instance]; - auto it=inst->ue2te_mapping.find(req_pP->rnti); + auto inst=&globGtp.instances[compatInst(instance)]; + auto it=inst->ue2te_mapping.find(rnti); if ( it == inst->ue2te_mapping.end() ) { LOG_W(GTPU,"Delete a non existing GTP tunnel\n"); @@ -411,6 +426,13 @@ int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, return !GTPNOK; } +// Legacy delete tunnel finish by deleting all the rnti +// so the list of bearer provided is only a design bug +int ocp_gtpv1u_delete_s1u_tunnel( const instance_t instance, + const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { + return newGtpuDeleteTunnel(instance, req_pP->rnti); +} + static int Gtpv1uHandleEchoReq(int h, uint8_t *msgBuf, uint32_t msgBufLen, @@ -489,10 +511,10 @@ static int Gtpv1uHandleGpdu(int h, ctxt.frame = 0; ctxt.subframe = 0; ctxt.eNB_index = 0; - ctxt.configured = 1; + ctxt.configured = 0; ctxt.brOption = 0; const srb_flag_t srb_flag=SRB_FLAG_NO; - const rb_id_t rb_id=0; + const rb_id_t rb_id=tunnel->second.rb_id; const mui_t mui=RLC_MUI_UNDEFINED; const confirm_t confirm=RLC_SDU_CONFIRM_NO; const sdu_size_t sdu_buffer_size=msgBufLen-offset; @@ -529,7 +551,7 @@ void gtpv1uReceiver(int h) { if ((udpDataLen = recvfrom(h, udpData, sizeof(udpData), 0, (struct sockaddr *)&addr, &from_len)) < 0) { - LOG_E(GTPU, "Recvfrom failed %s\n", strerror(errno)); + LOG_E(GTPU, "Recvfrom failed on %d (%s)\n", h, strerror(errno)); return; } else if (udpDataLen == 0) { LOG_W(GTPU, "Recvfrom returned 0\n"); @@ -586,7 +608,7 @@ void *ocp_gtpv1uTask(void *args) { switch (ITTI_MSG_ID(message_p)) { // DATA TO BE SENT TO UDP case GTPV1U_ENB_TUNNEL_DATA_REQ: { - gtpv1uSend(ITTI_MESSAGE_GET_INSTANCE(message_p), + gtpv1uSend(compatInst(ITTI_MESSAGE_GET_INSTANCE(message_p)), >PV1U_ENB_TUNNEL_DATA_REQ(message_p), false, false); itti_free(OCP_GTPV1_U, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer); } @@ -611,7 +633,7 @@ void *ocp_gtpv1uTask(void *args) { // to be dev: should be removed, to use API strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr); - AssertFatal(ocp_gtpv1Init(addr),"Only one instance 0 supprted\n"); + AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n"); break; default: @@ -627,8 +649,8 @@ void *ocp_gtpv1uTask(void *args) { int nb_events = itti_get_events(OCP_GTPV1_U, &events); - if (nb_events > 0 && events!= NULL ) - for (int i = 0; i < nb_events; i++) + for (int i = 0; i < nb_events; i++) + if ((events[i].events&EPOLLIN)) gtpv1uReceiver(events[i].data.fd); } From 7eda2b7409c1e176c6f07ea600b34388a97b5387 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Mon, 1 Feb 2021 15:35:17 +0100 Subject: [PATCH 4/5] remainign bug after merge develop --- cmake_targets/CMakeLists.txt | 15 ++------------- executables/nr-softmodem.c | 1 + openair3/ocp-gtpu/gtp_itf.h | 1 + 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a210524220..51287a8ba4 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -405,7 +405,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(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") -add_boolean_option(NEW_GTPU True "NEW_GTP") +add_boolean_option(NEW_GTPU False "NEW_GTP") set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI @@ -2207,16 +2207,6 @@ add_library(CN_UTILS ) set(GTPV1U_DIR ${OPENAIR3_DIR}/GTPV1-U) -set (GTPV1U_SRC - ${RRC_DIR}/rrc_eNB_GTPV1U.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c - ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c - ${GTPV1U_DIR}/gtpv1u_teid_pool.c -) -add_library(GTPV1U ${GTPV1U_SRC}) -add_dependencies(GTPV1U rrc_flag) add_library (GTPV1U_OCP ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c @@ -2231,6 +2221,7 @@ set (NR_GTPV1U_SRC ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c ${RRC_DIR}/rrc_eNB_GTPV1U.c ${GTPV1U_DIR}/gtpv1u_eNB.c + ${GTPV1U_DIR}/gtpv1u_gNB.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c @@ -3022,7 +3013,6 @@ add_executable(nr-softmodem ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c @@ -3539,7 +3529,6 @@ add_executable(nr-ittisim ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 82dcec1220..7884ca9e81 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -85,6 +85,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "x2ap_eNB.h" #include "ngap_gNB.h" #include "gnb_paramdef.h" +#include pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 24b1adaa6f..507aa1338e 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -14,6 +14,7 @@ extern "C" { #define gtpv1u_delete_s1u_tunnel ocp_gtpv1u_delete_s1u_tunnel #define gtpv1u_create_x2u_tunnel ocp_gtpv1u_create_x2u_tunnel #define gtpv1u_eNB_task ocp_gtpv1uTask +#define gtpv1u_gNB_task ocp_gtpv1uTask #define TASK_VARIABLE OCP_GTPV1_U #else #define TASK_VARIABLE TASK_GTPV1_U From 657b525efc0ca13cde204b464633af4d8c254de3 Mon Sep 17 00:00:00 2001 From: Laurent Thomas Date: Fri, 9 Apr 2021 14:31:02 +0200 Subject: [PATCH 5/5] merge develop --- executables/nr-uesoftmodem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 20e1e296e1..4fa014972a 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -146,7 +146,6 @@ int card_offset = 0; uint64_t num_missed_slots = 0; // counter for the number of missed slots int transmission_mode = 1; int numerology = 0; -int usrp_tx_thread = 0; int oaisim_flag = 0; int emulate_rf = 0;