Merge branch 'integration_2020_wk39' into 'develop', comprising :
MR 896 : Nsa remove band hardcodings Removes hardcodings of EUTRA and NR bands in UE_Capability_Enquiry and NR_UE Capability_Enquiry messages, providing them from the eNB config file and gNB over X2 respectively. Moreover, the SSB Absolute frequency of the gNB is now provided by the eNB configuration file (instead of being hardcoded at rrc_eNB.c) MR903 : pusch ta update Update of PUSCH Timing advance MR 900 : improve x2/rrc for ENDC This MR introduces several enhancements in X2AP and RRC to deal with ENDC. The main goal is to deal with UE's on/off and with various errors. Includes : - DC prep and DC overall X2 timers - X2 messages for UE release and DC timers' timeout
This commit is contained in:
@@ -184,6 +184,8 @@ eNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -367,6 +367,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -188,6 +188,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -189,6 +189,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
///M2
|
||||
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -145,6 +145,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -184,6 +184,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "CI_RCC_IP_ADDR";
|
||||
ipv6 = "192:168:30::17";
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -192,6 +192,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -144,6 +144,8 @@ eNBs =
|
||||
discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
|
||||
discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
|
||||
|
||||
//SSB central frequency of NR secondary cell group (for ENDC NSA)
|
||||
nr_scg_ssb_freq = 641272;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -190,6 +192,8 @@ eNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -183,6 +183,8 @@ eNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "CI_RCC_IP_ADDR";
|
||||
ipv6 = "192:168:30::17";
|
||||
|
||||
@@ -210,6 +210,8 @@ gNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "CI_FR1_CTL_ENB_IP_ADDR";
|
||||
ipv6 = "192:168:30::17";
|
||||
|
||||
@@ -184,6 +184,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -185,6 +185,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
////////// MCE parameters:
|
||||
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
|
||||
|
||||
@@ -185,6 +185,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
////////// MCE parameters:
|
||||
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -150,6 +150,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -150,6 +150,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -150,6 +150,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -155,6 +155,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
|
||||
////////// MCE parameters:
|
||||
|
||||
@@ -155,6 +155,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
|
||||
////////// MCE parameters:
|
||||
|
||||
@@ -185,6 +185,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -2772,7 +2772,7 @@ if (NOT ${NOS1})
|
||||
endif()
|
||||
target_link_libraries (lte-uesoftmodem
|
||||
-Wl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
|
||||
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
|
||||
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}
|
||||
@@ -3023,12 +3023,15 @@ add_executable(nr_dlsim
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(nr_dlsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
)
|
||||
target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
@@ -3039,11 +3042,14 @@ add_executable(nr_prachsim
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES})
|
||||
target_link_libraries(nr_prachsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
|
||||
|
||||
add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||
@@ -3065,12 +3071,15 @@ add_executable(nr_ulsim
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(nr_ulsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
)
|
||||
target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -147,6 +147,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -149,6 +149,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -149,6 +149,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -149,6 +149,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -212,6 +212,8 @@ gNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "192.168.18.199";
|
||||
ipv6 = "192:168:30::17";
|
||||
|
||||
+53
-1
@@ -139,7 +139,6 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
|
||||
//#define TICK_TO_US(ts) (ts.diff)
|
||||
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
|
||||
|
||||
|
||||
static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
|
||||
|
||||
sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
|
||||
@@ -178,6 +177,59 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
|
||||
|
||||
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
|
||||
|
||||
/* hack to remove UEs */
|
||||
extern int rnti_to_remove[10];
|
||||
extern volatile int rnti_to_remove_count;
|
||||
extern pthread_mutex_t rnti_to_remove_mutex;
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
|
||||
int up_removed = 0;
|
||||
int down_removed = 0;
|
||||
int pucch_removed = 0;
|
||||
for (int i = 0; i < rnti_to_remove_count; i++) {
|
||||
LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]);
|
||||
void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
|
||||
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
|
||||
int j;
|
||||
for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++)
|
||||
if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) {
|
||||
gNB->ulsch[j][0]->rnti = 0;
|
||||
gNB->ulsch[j][0]->harq_mask = 0;
|
||||
//clean_gNB_ulsch(gNB->ulsch[j][0]);
|
||||
int h;
|
||||
for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) {
|
||||
gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE;
|
||||
gNB->ulsch[j][0]->harq_processes[h]->round = 0;
|
||||
gNB->ulsch[j][0]->harq_processes[h]->handled = 0;
|
||||
}
|
||||
up_removed++;
|
||||
}
|
||||
for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++)
|
||||
if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) {
|
||||
gNB->dlsch[j][0]->rnti = 0;
|
||||
gNB->dlsch[j][0]->harq_mask = 0;
|
||||
//clean_gNB_dlsch(gNB->dlsch[j][0]);
|
||||
down_removed++;
|
||||
}
|
||||
for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
|
||||
if (gNB->pucch[j]->active > 0 &&
|
||||
gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
|
||||
gNB->pucch[j]->active = 0;
|
||||
gNB->pucch[j]->pucch_pdu.rnti = 0;
|
||||
pucch_removed++;
|
||||
}
|
||||
#if 0
|
||||
for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
|
||||
gNB->pdcch_pdu[j].frame = -1;
|
||||
for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
|
||||
gNB->ul_pdcch_pdu[j].frame = -1;
|
||||
for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++)
|
||||
gNB->prach_vars.list[j].frame = -1;
|
||||
#endif
|
||||
}
|
||||
if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
|
||||
rnti_to_remove_count = 0;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
|
||||
|
||||
/*
|
||||
// if this is IF5 or 3GPP_gNB
|
||||
if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
|
||||
|
||||
@@ -1147,9 +1147,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
//--------------------- RBs extraction ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if (nb_re_pusch > 0) {
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
|
||||
if (nb_re_pusch > 0) {
|
||||
|
||||
start_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
@@ -84,8 +87,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
// dummy functions
|
||||
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_index,
|
||||
@@ -96,19 +97,33 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pdcp_layer_init(void) {}
|
||||
boolean_t
|
||||
pdcp_data_ind(
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
) { return(false);}
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
int rrc_init_nr_global_param(void){return(0);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int pdsch_AntennaPorts,
|
||||
@@ -124,7 +139,6 @@ int generate_dlsch_header(unsigned char *mac_header,
|
||||
unsigned char *ue_cont_res_id,
|
||||
unsigned char short_padding,
|
||||
unsigned short post_padding){return 0;}
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
|
||||
// needed for some functions
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#define NR_PRACH_DEBUG 1
|
||||
#define PRACH_WRITE_OUTPUT_DEBUG 1
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
@@ -66,17 +70,34 @@ int sl_ahead = 0;
|
||||
uint64_t get_softmodem_optmask(void) {return 0;}
|
||||
softmodem_params_t *get_softmodem_params(void) {return 0;}
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP) {return(false);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
void pdcp_layer_init(void) {}
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
|
||||
//#define DEBUG_ULSIM
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
@@ -84,20 +88,34 @@ int generate_dlsch_header(unsigned char *mac_header,
|
||||
unsigned char *ue_cont_res_id,
|
||||
unsigned char short_padding,
|
||||
unsigned short post_padding){return 0;}
|
||||
void pdcp_layer_init (void) {}
|
||||
boolean_t pdcp_data_ind(
|
||||
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
) { return(false);}
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
int rrc_init_nr_global_param(void){return(0);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// needed for some functions
|
||||
uint16_t n_rnti = 0x1234;
|
||||
|
||||
@@ -98,6 +98,7 @@ typedef struct gtpv1u_enb_delete_tunnel_req_s {
|
||||
uint8_t num_erab;
|
||||
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
|
||||
//teid_t enb_S1u_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
||||
int from_gnb; ///< Indicates if the message comes from gNB or eNB (1 = comes from gNB, 0 from eNB)
|
||||
} gtpv1u_enb_delete_tunnel_req_t;
|
||||
|
||||
typedef struct gtpv1u_enb_delete_tunnel_resp_s {
|
||||
@@ -170,4 +171,5 @@ typedef struct {
|
||||
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
|
||||
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
||||
} Gtpv1uS1Req;
|
||||
|
||||
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -323,6 +323,8 @@ typedef struct RrcConfigurationReq_s {
|
||||
char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs];
|
||||
long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs];
|
||||
long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs];
|
||||
//Nr secondary cell group SSB central frequency (for ENDC NSA)
|
||||
int nr_scg_ssb_freq;
|
||||
} RrcConfigurationReq;
|
||||
|
||||
#define MAX_NUM_NBIOT_CELEVELS 3
|
||||
|
||||
@@ -48,10 +48,19 @@ MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_han
|
||||
/* handover messages X2AP <-> S1AP */
|
||||
MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release)
|
||||
|
||||
/*Senb bearer addition messages X2AP <-> RRC */
|
||||
/* Senb bearer addition messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t , x2ap_senb_addition_req)
|
||||
|
||||
/*SGnb bearer addition messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t , x2ap_ENDC_sgnb_addition_req_ACK)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete)
|
||||
/* SGnb bearer addition messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_ENDC_SETUP_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_setup_req_t , x2ap_ENDC_setup_req)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t, x2ap_ENDC_sgnb_addition_req_ACK)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete)
|
||||
|
||||
/* SGnb UE releases ('request' is for enb starting the process, 'required' for gnb) */
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_RELEASE_REQUEST , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_release_request_t , x2ap_ENDC_sgnb_release_request)
|
||||
MESSAGE_DEF(X2AP_ENDC_SGNB_RELEASE_REQUIRED , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_release_required_t, x2ap_ENDC_sgnb_release_required)
|
||||
|
||||
/* ENDC timers' timeout X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_ENDC_DC_PREP_TIMEOUT , MESSAGE_PRIORITY_MED, x2ap_ENDC_dc_prep_timeout_t , x2ap_ENDC_dc_prep_timeout)
|
||||
MESSAGE_DEF(X2AP_ENDC_DC_OVERALL_TIMEOUT , MESSAGE_PRIORITY_MED, x2ap_ENDC_dc_overall_timeout_t , x2ap_ENDC_dc_overall_timeout)
|
||||
|
||||
@@ -25,22 +25,34 @@
|
||||
#include "s1ap_messages_types.h"
|
||||
#include "LTE_PhysCellId.h"
|
||||
|
||||
typedef enum {
|
||||
X2AP_CAUSE_T_DC_PREP_TIMEOUT,
|
||||
X2AP_CAUSE_T_DC_OVERALL_TIMEOUT,
|
||||
X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST,
|
||||
} x2ap_cause_t;
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
|
||||
#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
|
||||
#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel
|
||||
#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK
|
||||
#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete
|
||||
|
||||
#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req
|
||||
#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req
|
||||
#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp
|
||||
#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
|
||||
#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
|
||||
#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel
|
||||
#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req
|
||||
#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK
|
||||
#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete
|
||||
#define X2AP_ENDC_SGNB_RELEASE_REQUEST(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_release_request
|
||||
#define X2AP_ENDC_SGNB_RELEASE_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_release_required
|
||||
#define X2AP_ENDC_DC_PREP_TIMEOUT(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_dc_prep_timeout
|
||||
#define X2AP_ENDC_DC_OVERALL_TIMEOUT(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_dc_overall_timeout
|
||||
#define X2AP_ENDC_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_setup_req
|
||||
|
||||
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
|
||||
|
||||
@@ -144,6 +156,8 @@ typedef struct x2ap_register_enb_req_s {
|
||||
/* timers (unit: millisecond) */
|
||||
int t_reloc_prep;
|
||||
int tx2_reloc_overall;
|
||||
int t_dc_prep;
|
||||
int t_dc_overall;
|
||||
} x2ap_register_enb_req_t;
|
||||
|
||||
typedef struct x2ap_subframe_process_s {
|
||||
@@ -288,10 +302,6 @@ typedef struct x2ap_senb_addition_req_s {
|
||||
|
||||
}x2ap_senb_addition_req_t;
|
||||
|
||||
|
||||
|
||||
|
||||
//Panos: Have to see what should be the additional/different elements comparing to handover req ack
|
||||
typedef struct x2ap_senb_addition_req_ack_s {
|
||||
|
||||
int MeNB_UE_X2_id;
|
||||
@@ -313,6 +323,13 @@ typedef struct x2ap_senb_addition_req_ack_s {
|
||||
|
||||
} x2ap_senb_addition_req_ack_t;
|
||||
|
||||
|
||||
typedef struct x2ap_ENDC_setup_req_s {
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
uint32_t servedNrCell_band[MAX_NUM_CCs];
|
||||
} x2ap_ENDC_setup_req_t;
|
||||
|
||||
typedef struct x2ap_ENDC_sgnb_addition_req_s {
|
||||
int ue_x2_id;
|
||||
LTE_PhysCellId_t target_physCellId;
|
||||
@@ -357,6 +374,8 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
|
||||
|
||||
int SgNB_ue_x2_id;
|
||||
|
||||
int gnb_x2_assoc_id; // to be stored in the rrc's ue context, used when sending 'sgnb reconfiguration complete'
|
||||
|
||||
/* used for X2AP->RRC in source eNB */
|
||||
int rnti;
|
||||
|
||||
@@ -384,16 +403,26 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
|
||||
|
||||
typedef struct x2ap_ENDC_reconf_complete_s {
|
||||
int MeNB_ue_x2_id;
|
||||
|
||||
int SgNB_ue_x2_id;
|
||||
LTE_PhysCellId_t target_physCellId;
|
||||
|
||||
x2ap_sgNB_reconf_response_information_t reconf_response;
|
||||
|
||||
uint8_t rrc_buffer[4096 /* arbitrary, big enough */];
|
||||
int rrc_buffer_size;
|
||||
|
||||
int gnb_x2_assoc_id;
|
||||
} x2ap_ENDC_reconf_complete_t;
|
||||
|
||||
typedef struct x2ap_ENDC_sgnb_release_request_s {
|
||||
int rnti;
|
||||
x2ap_cause_t cause;
|
||||
int assoc_id;
|
||||
} x2ap_ENDC_sgnb_release_request_t;
|
||||
|
||||
typedef struct x2ap_ENDC_sgnb_release_required_s {
|
||||
int gnb_rnti;
|
||||
} x2ap_ENDC_sgnb_release_required_t;
|
||||
|
||||
typedef struct x2ap_ENDC_dc_prep_timeout_s {
|
||||
int rnti;
|
||||
} x2ap_ENDC_dc_prep_timeout_t;
|
||||
|
||||
typedef struct x2ap_ENDC_dc_overall_timeout_s {
|
||||
int rnti;
|
||||
} x2ap_ENDC_dc_overall_timeout_t;
|
||||
|
||||
#endif /* X2AP_MESSAGES_TYPES_H_ */
|
||||
|
||||
@@ -1576,6 +1576,8 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
|
||||
} // !NODE_IS_DU(node_type)
|
||||
}
|
||||
|
||||
RRC_CONFIGURATION_REQ (msg_p).nr_scg_ssb_freq = ccparams_lte.nr_scg_ssb_freq;
|
||||
|
||||
if (!NODE_IS_DU(rrc->node_type)) {
|
||||
char srb1path[MAX_OPTNAME_SIZE*2 + 8];
|
||||
sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1);
|
||||
@@ -2731,20 +2733,28 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
|
||||
{
|
||||
int t_reloc_prep = 0;
|
||||
int tx2_reloc_overall = 0;
|
||||
int t_dc_prep = 0;
|
||||
int t_dc_overall = 0;
|
||||
paramdef_t p[] = {
|
||||
{ "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 },
|
||||
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }
|
||||
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 },
|
||||
{ "t_dc_prep", "t_dc_prep", 0, iptr:&t_dc_prep, defintval:0, TYPE_INT, 0 },
|
||||
{ "t_dc_overall", "t_dc_overall", 0, iptr:&t_dc_overall, defintval:0, TYPE_INT, 0 }
|
||||
};
|
||||
config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
|
||||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) {
|
||||
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n");
|
||||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000 ||
|
||||
t_dc_prep <= 0 || t_dc_prep > 10000 ||
|
||||
t_dc_overall <= 0 || t_dc_overall > 20000) {
|
||||
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000] and [0 < t_dc_prep <= 10000] and [0 < t_dc_overall <= 20000]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_prep = t_dc_prep;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_overall = t_dc_overall;
|
||||
}
|
||||
// SCTP SETTING
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
|
||||
@@ -429,6 +429,9 @@ typedef enum {
|
||||
//SIB1-MBMS
|
||||
#define ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL "mbms_dedicated_serving_cell"
|
||||
|
||||
//NSA NR Cell SSB Absolute Frequency
|
||||
#define ENB_CONFIG_STRING_NR_SCG_SSB_FREQ "nr_scg_ssb_freq"
|
||||
|
||||
|
||||
|
||||
#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13"
|
||||
@@ -577,6 +580,7 @@ typedef struct ccparams_lte_s {
|
||||
int32_t srb1_poll_pdu;
|
||||
int32_t srb1_poll_byte;
|
||||
int32_t srb1_max_retx_threshold;
|
||||
int32_t nr_scg_ssb_freq;
|
||||
} ccparams_lte_t;
|
||||
|
||||
#define CCPARAMS_CHECK { \
|
||||
@@ -780,7 +784,8 @@ typedef struct ccparams_lte_s {
|
||||
{ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0} \
|
||||
{ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_NR_SCG_SSB_FREQ, NULL, 0, iptr:&ccparams.nr_scg_ssb_freq, defintval:641272, TYPE_INT, 0} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1123,20 +1123,28 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
{
|
||||
int t_reloc_prep = 0;
|
||||
int tx2_reloc_overall = 0;
|
||||
int t_dc_prep = 0;
|
||||
int t_dc_overall = 0;
|
||||
paramdef_t p[] = {
|
||||
{ "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 },
|
||||
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }
|
||||
{ "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 },
|
||||
{ "t_dc_prep", "t_dc_prep", 0, iptr:&t_dc_prep, defintval:0, TYPE_INT, 0 },
|
||||
{ "t_dc_overall", "t_dc_overall", 0, iptr:&t_dc_overall, defintval:0, TYPE_INT, 0 }
|
||||
};
|
||||
config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix);
|
||||
|
||||
if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
|
||||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) {
|
||||
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n");
|
||||
tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000 ||
|
||||
t_dc_prep <= 0 || t_dc_prep > 10000 ||
|
||||
t_dc_overall <= 0 || t_dc_overall > 20000) {
|
||||
LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000] and [0 < t_dc_prep <= 10000] and [0 < t_dc_overall <= 20000]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_prep = t_dc_prep;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).t_dc_overall = t_dc_overall;
|
||||
}
|
||||
// SCTP SETTING
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
|
||||
@@ -1603,11 +1603,9 @@ uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{
|
||||
uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340},
|
||||
{4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}};
|
||||
|
||||
//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK
|
||||
uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
|
||||
{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
|
||||
|
||||
//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK
|
||||
uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},
|
||||
{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}};
|
||||
|
||||
@@ -2471,6 +2469,40 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
|
||||
return(-1);
|
||||
}
|
||||
|
||||
uint8_t get_pusch_mcs_table(long *mcs_Table,
|
||||
int is_tp,
|
||||
int dci_format,
|
||||
int rnti_type,
|
||||
int target_ss,
|
||||
bool config_grant) {
|
||||
|
||||
// implementing 6.1.4.1 in 38.214
|
||||
if (mcs_Table != NULL) {
|
||||
if (config_grant || (rnti_type == NR_RNTI_CS)) {
|
||||
if (*mcs_Table == NR_PUSCH_Config__mcs_Table_qam256)
|
||||
return 1;
|
||||
else
|
||||
return (2+(is_tp<<1));
|
||||
}
|
||||
else {
|
||||
if ((*mcs_Table == NR_PUSCH_Config__mcs_Table_qam256) &&
|
||||
(dci_format == NR_UL_DCI_FORMAT_0_1) &&
|
||||
((rnti_type == NR_RNTI_C ) || (rnti_type == NR_RNTI_SP_CSI)))
|
||||
return 1;
|
||||
// TODO take into account UE configuration
|
||||
if ((*mcs_Table == NR_PUSCH_Config__mcs_Table_qam64LowSE) &&
|
||||
(target_ss == NR_SearchSpace__searchSpaceType_PR_ue_Specific) &&
|
||||
((rnti_type == NR_RNTI_C ) || (rnti_type == NR_RNTI_SP_CSI)))
|
||||
return (2+(is_tp<<1));
|
||||
if (rnti_type == NR_RNTI_MCS_C)
|
||||
return (2+(is_tp<<1));
|
||||
AssertFatal(1==0,"Invalid configuration to set MCS table");
|
||||
}
|
||||
}
|
||||
else
|
||||
return (0+(is_tp*3));
|
||||
}
|
||||
|
||||
|
||||
int binomial(int n, int k) {
|
||||
int c = 1, i;
|
||||
|
||||
@@ -60,7 +60,8 @@ typedef enum {
|
||||
NR_RNTI_INT,
|
||||
NR_RNTI_TPC_PUSCH,
|
||||
NR_RNTI_TPC_PUCCH,
|
||||
NR_RNTI_TPC_SRS
|
||||
NR_RNTI_TPC_SRS,
|
||||
NR_RNTI_MCS_C,
|
||||
} nr_rnti_type_t;
|
||||
|
||||
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
|
||||
@@ -100,6 +101,13 @@ int get_nr_prach_info_from_index(uint8_t index,
|
||||
uint8_t *N_t_slot,
|
||||
uint8_t *N_dur);
|
||||
|
||||
uint8_t get_pusch_mcs_table(long *mcs_Table,
|
||||
int is_tp,
|
||||
int dci_format,
|
||||
int rnti_type,
|
||||
int target_ss,
|
||||
bool config_grant);
|
||||
|
||||
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
||||
uint8_t nb_preambles,
|
||||
uint8_t unpaired);
|
||||
|
||||
@@ -441,11 +441,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
|
||||
|
||||
pdcp_run(&ctxt);
|
||||
//rrc_rx_tx(&ctxt, CC_id);
|
||||
/* send tick to RLC every ms */
|
||||
/* send tick to RLC and RRC every ms */
|
||||
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
|
||||
void nr_rlc_tick(int frame, int subframe);
|
||||
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||
}
|
||||
|
||||
dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
|
||||
@@ -514,20 +514,15 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
} else
|
||||
UE_list->fiveG_connected[UE_id] = true;
|
||||
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
|
||||
if (UE_list->fiveG_connected[UE_id]) {
|
||||
// TbD once RACH is available, start ta_timer when UE is connected
|
||||
if (ue_sched_ctl->ta_timer)
|
||||
ue_sched_ctl->ta_timer--;
|
||||
if (ue_sched_ctl->ta_timer == 0) {
|
||||
gNB->ta_command = ue_sched_ctl->ta_update;
|
||||
ue_sched_ctl->ta_apply = true;
|
||||
/* if time is up, then set the timer to not send it for 5 frames
|
||||
// regardless of the TA value */
|
||||
ue_sched_ctl->ta_timer = 100;
|
||||
/* reset ta_update */
|
||||
ue_sched_ctl->ta_update = 31;
|
||||
/* MAC CE flag indicating TA length */
|
||||
gNB->ta_len = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,8 +537,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
|
||||
nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
|
||||
nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
|
||||
// resetting ta flag
|
||||
gNB->ta_len = 0;
|
||||
ue_sched_ctl->ta_apply = false;
|
||||
}
|
||||
|
||||
if (UE_list->fiveG_connected[UE_id])
|
||||
|
||||
@@ -94,13 +94,13 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
|
||||
// now TA is always send when ta_timer resets regardless of its value
|
||||
// this is done to avoid issues with the timeAlignmentTimer which is
|
||||
// supposed to monitor if the UE received TA or not */
|
||||
if (gNB->ta_len) {
|
||||
if (ue_sched_ctl->ta_apply) {
|
||||
mac_pdu_ptr->R = 0;
|
||||
mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND;
|
||||
//last_size = 1;
|
||||
mac_pdu_ptr++;
|
||||
// TA MAC CE (1 octet)
|
||||
timing_advance_cmd = gNB->ta_command;
|
||||
timing_advance_cmd = ue_sched_ctl->ta_update;
|
||||
AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n", timing_advance_cmd);
|
||||
((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f;
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP);
|
||||
|
||||
int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
|
||||
int post_padding = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0;
|
||||
int lcid, offset, i, header_length_last, TBS_bytes = 0;
|
||||
int UE_id = 0, CC_id = 0;
|
||||
|
||||
@@ -615,12 +615,13 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
unsigned char sdu_lcids[NB_RB_MAX] = {0};
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
uint16_t rnti = UE_list->rnti[UE_id];
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
|
||||
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
|
||||
|
||||
LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n");
|
||||
|
||||
ta_len = gNB_mac->ta_len;
|
||||
int ta_len = (ue_sched_ctl->ta_apply)?2:0;
|
||||
|
||||
TBS_bytes = configure_fapi_dl_pdu(module_idP,
|
||||
dl_req,
|
||||
@@ -862,6 +863,36 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
LOG_D(MAC, "Scheduling UE specific PUSCH\n");
|
||||
//UL_tti_req = &nr_mac->UL_tti_req[CC_id];
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
NR_SearchSpace_t *ss;
|
||||
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
int found=0;
|
||||
|
||||
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
|
||||
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
|
||||
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
|
||||
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
|
||||
if (ss->searchSpaceType->present == target_ss) {
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
|
||||
|
||||
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
|
||||
else
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
rnti_types[0] = NR_RNTI_C;
|
||||
|
||||
//Resource Allocation in time domain
|
||||
int startSymbolAndLength=0;
|
||||
int StartSymbolIndex,NrOfSymbols,mapping_type;
|
||||
@@ -881,12 +912,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
pusch_pdu->cyclic_prefix = 0;
|
||||
//pusch information always include
|
||||
//this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined.
|
||||
pusch_pdu->mcs_index = 9;
|
||||
pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY
|
||||
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
|
||||
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
|
||||
|
||||
if (pusch_Config->transformPrecoder == NULL) {
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
|
||||
pusch_pdu->transform_precoding = 1;
|
||||
@@ -900,6 +926,23 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
else
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
|
||||
pusch_pdu->mcs_index = 9;
|
||||
if (pusch_pdu->transform_precoding)
|
||||
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0,
|
||||
dci_formats[0], rnti_types[0], target_ss, false);
|
||||
else
|
||||
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1,
|
||||
dci_formats[0], rnti_types[0], target_ss, false);
|
||||
|
||||
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
|
||||
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
|
||||
if (pusch_Config->tp_pi2BPSK!=NULL) {
|
||||
if(((pusch_pdu->mcs_table==3)&&(pusch_pdu->mcs_index<2)) ||
|
||||
((pusch_pdu->mcs_table==4)&&(pusch_pdu->mcs_index<6))) {
|
||||
pusch_pdu->target_code_rate = pusch_pdu->target_code_rate>>1;
|
||||
pusch_pdu->qam_mod_order = pusch_pdu->qam_mod_order<<1;
|
||||
}
|
||||
}
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
|
||||
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
|
||||
@@ -1053,35 +1096,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
UL_dci_req->numPdus+=1;
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
NR_SearchSpace_t *ss;
|
||||
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
int found=0;
|
||||
|
||||
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
|
||||
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
|
||||
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
|
||||
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
|
||||
if (ss->searchSpaceType->present == target_ss) {
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
|
||||
|
||||
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
|
||||
else
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
rnti_types[0] = NR_RNTI_C;
|
||||
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
|
||||
|
||||
int ret = nr_configure_pdcch(nr_mac,
|
||||
|
||||
@@ -1454,7 +1454,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
UE_list->num_UEs);
|
||||
dump_nr_ue_list(UE_list, 0);
|
||||
|
||||
for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i] == TRUE)
|
||||
continue;
|
||||
|
||||
@@ -1465,6 +1465,8 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
UE_list->UE_sched_ctrl[UE_id].ta_timer = 100;
|
||||
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0;
|
||||
UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
|
||||
UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
|
||||
@@ -1492,6 +1494,48 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* hack data to remove UE in the phy */
|
||||
int rnti_to_remove[10];
|
||||
volatile int rnti_to_remove_count;
|
||||
pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int UE_id;
|
||||
int i;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[mod_id]->UE_list;
|
||||
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i] != TRUE)
|
||||
continue;
|
||||
if (UE_list->rnti[i] != rnti)
|
||||
continue;
|
||||
|
||||
/* UE found, remove it */
|
||||
UE_id = i;
|
||||
UE_list->num_UEs--;
|
||||
UE_list->fiveG_connected[UE_id] = FALSE;
|
||||
UE_list->active[UE_id] = FALSE;
|
||||
UE_list->rnti[UE_id] = 0;
|
||||
free(UE_list->UE_sched_ctrl[UE_id].sched_pucch);
|
||||
free(UE_list->UE_sched_ctrl[UE_id].sched_pusch);
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n",
|
||||
mod_id,
|
||||
UE_id,
|
||||
rnti);
|
||||
|
||||
/* hack to remove UE in the phy */
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
|
||||
if (rnti_to_remove_count == 10) exit(1);
|
||||
rnti_to_remove[rnti_to_remove_count] = rnti;
|
||||
LOG_W(MAC, "to remove in mac rnti_to_remove[%d]=%d\n", rnti_to_remove_count, rnti);
|
||||
rnti_to_remove_count++;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
|
||||
// al values passed to this function are x10
|
||||
|
||||
@@ -339,7 +339,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
// if not missed detection (10dB threshold for now)
|
||||
if (UE_scheduling_control->ul_rssi < (100+rssi)) {
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
if (timing_advance != 0xffff)
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->ul_rssi = rssi;
|
||||
LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
}
|
||||
|
||||
@@ -265,6 +265,8 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
|
||||
|
||||
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
|
||||
|
||||
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
|
||||
|
||||
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
int bwp_id,
|
||||
int coreset_id,
|
||||
|
||||
@@ -289,6 +289,7 @@ typedef struct {
|
||||
NR_sched_pusch *sched_pusch;
|
||||
uint16_t ta_timer;
|
||||
int16_t ta_update;
|
||||
bool ta_apply;
|
||||
uint8_t tpc0;
|
||||
uint8_t tpc1;
|
||||
uint16_t ul_rssi;
|
||||
@@ -353,10 +354,6 @@ typedef struct gNB_MAC_INST_s {
|
||||
int pusch_target_snrx10;
|
||||
/// Pucch target SNR
|
||||
int pucch_target_snrx10;
|
||||
/// TA command
|
||||
int ta_command;
|
||||
/// MAC CE flag indicating TA length
|
||||
int ta_len;
|
||||
/// Common cell resources
|
||||
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
|
||||
/// current PDU index (BCH,DLSCH)
|
||||
|
||||
@@ -854,7 +854,12 @@ uint64_t get_pdcp_optmask(void)
|
||||
boolean_t pdcp_remove_UE(
|
||||
const protocol_ctxt_t *const ctxt_pP)
|
||||
{
|
||||
TODO;
|
||||
int rnti = ctxt_pP->rnti;
|
||||
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager, rnti);
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -897,9 +902,9 @@ printf("pdcp_data_req called size %d\n", sdu_buffer_size);
|
||||
rb = ue->drb[rb_id - 1];
|
||||
|
||||
if (rb == NULL) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal: no DRB found (rnti %d, rb_id %ld)\n",
|
||||
LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, rnti, rb_id);
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP);
|
||||
|
||||
@@ -117,7 +117,7 @@ void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti)
|
||||
break;
|
||||
|
||||
if (i == m->ue_count) {
|
||||
LOG_D(RLC, "%s:%d:%s: warning: ue %d not found\n",
|
||||
LOG_W(RLC, "%s:%d:%s: warning: ue %d not found\n",
|
||||
__FILE__, __LINE__, __FUNCTION__,
|
||||
rnti);
|
||||
return;
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "NR_FreqBandList.h"
|
||||
|
||||
|
||||
#include "common/ran_context.h"
|
||||
@@ -3199,9 +3200,13 @@ uint8_t do_SecurityModeCommand(
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id)
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_FreqBandList_t *nsa_band_list;
|
||||
NR_FreqBandInformation_t *nsa_band;
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
LTE_RAT_Type_t rat=LTE_RAT_Type_eutra;
|
||||
asn_enc_rval_t enc_rval;
|
||||
@@ -3238,8 +3243,36 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
/* TODO: no hardcoded values here */
|
||||
|
||||
nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
|
||||
nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
|
||||
nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
|
||||
nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
|
||||
if(nr_band > 0)
|
||||
nsa_band->choice.bandInformationNR->bandNR = nr_band;
|
||||
else
|
||||
nsa_band->choice.bandInformationNR->bandNR = 78;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
OCTET_STRING_t req_freq;
|
||||
unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
unsigned char req_freq_buf[1024];
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
|
||||
NULL,
|
||||
(void *)nsa_band_list,
|
||||
req_freq_buf,
|
||||
1024);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list);
|
||||
|
||||
|
||||
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260
|
||||
|
||||
//unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 };
|
||||
@@ -3248,7 +3281,7 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
// };
|
||||
|
||||
req_freq.buf = req_freq_buf;
|
||||
req_freq.size = 5;
|
||||
req_freq.size = (enc_rval.encoded+7)/8;
|
||||
// req_freq.size = 21;
|
||||
|
||||
r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
|
||||
@@ -3287,9 +3320,13 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id)
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
NR_FreqBandList_t *nsa_band_list;
|
||||
NR_FreqBandInformation_t *nsa_band;
|
||||
LTE_DL_DCCH_Message_t dl_dcch_msg;
|
||||
LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr;
|
||||
LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr;
|
||||
@@ -3329,8 +3366,32 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
/* TODO: no hardcoded values here */
|
||||
|
||||
nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA;
|
||||
nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t));
|
||||
nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t));
|
||||
nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR;
|
||||
nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t));
|
||||
if(nr_band > 0)
|
||||
nsa_band->choice.bandInformationNR->bandNR = nr_band;
|
||||
else
|
||||
nsa_band->choice.bandInformationNR->bandNR = 78;
|
||||
ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band);
|
||||
|
||||
OCTET_STRING_t req_freq;
|
||||
unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78
|
||||
unsigned char req_freq_buf[100];
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList,
|
||||
NULL,
|
||||
(void *)nsa_band_list,
|
||||
req_freq_buf,
|
||||
1024);
|
||||
|
||||
//unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260
|
||||
|
||||
//unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 };
|
||||
@@ -3339,7 +3400,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
|
||||
// };
|
||||
|
||||
req_freq.buf = req_freq_buf;
|
||||
req_freq.size = 5;
|
||||
req_freq.size = (enc_rval.encoded+7)/8;
|
||||
// req_freq.size = 21;
|
||||
|
||||
r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq;
|
||||
|
||||
@@ -359,15 +359,17 @@ uint8_t
|
||||
do_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id
|
||||
);
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band);
|
||||
|
||||
uint8_t
|
||||
do_NR_UECapabilityEnquiry(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
uint8_t *const buffer,
|
||||
const uint8_t Transaction_id
|
||||
);
|
||||
const uint8_t Transaction_id,
|
||||
int16_t eutra_band,
|
||||
uint32_t nr_band);
|
||||
|
||||
uint8_t do_SecurityModeCommand(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
@@ -271,7 +271,8 @@ typedef enum UE_STATE_e {
|
||||
RRC_RECONFIGURED,
|
||||
RRC_HO_EXECUTION,
|
||||
RRC_NR_NSA,
|
||||
RRC_NR_NSA_RECONFIGURED
|
||||
RRC_NR_NSA_RECONFIGURED,
|
||||
RRC_NR_NSA_DELETED
|
||||
} UE_STATE_t;
|
||||
|
||||
typedef enum HO_STATE_e {
|
||||
@@ -591,6 +592,8 @@ typedef struct eNB_RRC_UE_s {
|
||||
|
||||
uint8_t Status; // RRC status, type enum UE_STATE_t
|
||||
rnti_t rnti;
|
||||
int gnb_rnti; //RNTI of the UE at the gNB if in ENDC connection
|
||||
int gnb_x2_assoc_id;
|
||||
uint64_t random_ue_identity;
|
||||
|
||||
|
||||
@@ -791,6 +794,10 @@ typedef struct eNB_RRC_INST_s {
|
||||
int num_neigh_cells_cc[MAX_NUM_CCs];
|
||||
uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
|
||||
|
||||
// Nr scc freq band and SSB absolute frequency
|
||||
uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs];
|
||||
int nr_scg_ssb_freq;
|
||||
|
||||
// other RAN parameters
|
||||
int srb1_timer_poll_retransmit;
|
||||
int srb1_poll_pdu;
|
||||
|
||||
+156
-4
@@ -1282,10 +1282,14 @@ rrc_eNB_generate_UECapabilityEnquiry(
|
||||
uint8_t size;
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
|
||||
size = do_UECapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
buffer,
|
||||
rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
|
||||
rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
|
||||
eutra_band,
|
||||
nr_band);
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
@@ -1328,10 +1332,14 @@ rrc_eNB_generate_NR_UECapabilityEnquiry(
|
||||
uint8_t size;
|
||||
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
|
||||
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
|
||||
int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0];
|
||||
uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0];
|
||||
size = do_NR_UECapabilityEnquiry(
|
||||
ctxt_pP,
|
||||
buffer,
|
||||
rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
|
||||
rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
|
||||
eutra_band,
|
||||
nr_band);
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
|
||||
@@ -3283,8 +3291,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t
|
||||
|
||||
MeasObj2->measObjectId = 2;
|
||||
MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = 641272;
|
||||
//634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016)
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = rrc_inst->nr_scg_ssb_freq; //641272; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016)
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0;
|
||||
MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4;
|
||||
@@ -4648,6 +4655,8 @@ rrc_eNB_process_MeasurementReport(
|
||||
if ((ue_context_pP->ue_context.Status != RRC_NR_NSA) && (ue_context_pP->ue_context.Status != RRC_NR_NSA_RECONFIGURED)) {
|
||||
MessageDef *msg;
|
||||
ue_context_pP->ue_context.Status = RRC_NR_NSA;
|
||||
ue_context_pP->ue_context.gnb_rnti = -1; // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
|
||||
ue_context_pP->ue_context.gnb_x2_assoc_id = -1; // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK
|
||||
|
||||
if(is_en_dc_supported(ue_context_pP->ue_context.UE_Capability)) {
|
||||
/** to add gNB as Secondary node CG-ConfigInfo to be added as per 36.423 r15 **/
|
||||
@@ -5006,6 +5015,7 @@ void rrc_eNB_handover_ue_context_release(
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0;
|
||||
|
||||
for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
@@ -6948,6 +6958,32 @@ rrc_eNB_generate_RRCConnectionSetup(
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void rrc_eNB_process_reconfiguration_complete_endc(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_p)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
MessageDef *msg_p;
|
||||
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_ENDC_SGNB_RECONF_COMPLETE);
|
||||
|
||||
/* MeNB_ue_x2_id is unknown, set to 0.
|
||||
* This is not correct but X2 id in the eNB is only 12 bits,
|
||||
* so unfortunately we can't use rnti.
|
||||
* To be corrected if needed.
|
||||
* As of today, when stopping t_dc_prep we remove the UE
|
||||
* from X2. To keep the id until the 'reconfiguration complete' message is received
|
||||
* needs a rethink/rewrite of this logic. For simplicity, let's
|
||||
* keep it as is. The only problem we can get is if/when we
|
||||
* interoperate with a non-OAI gNB. The OAI gNB does not
|
||||
* care about MeNB_ue_x2_id.
|
||||
*/
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).MeNB_ue_x2_id = 0;
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).SgNB_ue_x2_id = ue_context_p->ue_context.gnb_rnti;
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).gnb_x2_assoc_id = ue_context_p->ue_context.gnb_x2_assoc_id;
|
||||
itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p);
|
||||
}
|
||||
|
||||
void setup_ngran_CU(eNB_RRC_INST *rrc) {
|
||||
}
|
||||
|
||||
@@ -7029,6 +7065,8 @@ char openair_rrc_eNB_configuration(
|
||||
openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0);
|
||||
}
|
||||
|
||||
RC.rrc[ctxt.module_id]->nr_scg_ssb_freq = configuration->nr_scg_ssb_freq;
|
||||
|
||||
openair_rrc_on(&ctxt);
|
||||
|
||||
/*
|
||||
@@ -7849,6 +7887,8 @@ rrc_eNB_decode_dcch(
|
||||
ue_context_p->ue_context.Status = RRC_NR_NSA_RECONFIGURED;
|
||||
/*Trigger E-RAB Modification Indication */
|
||||
rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
|
||||
/* send reconfiguration complete to gNB */
|
||||
rrc_eNB_process_reconfiguration_complete_endc(ctxt_pP, ue_context_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7909,6 +7949,7 @@ rrc_eNB_decode_dcch(
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0;
|
||||
|
||||
for(i = 0; i < NB_RB_MAX; i++) {
|
||||
if(xid == ue_context_p->ue_context.e_rab[i].xid) {
|
||||
@@ -8439,6 +8480,17 @@ rrc_eNB_decode_dcch(
|
||||
ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions.
|
||||
choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15);
|
||||
xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg);
|
||||
|
||||
/* TODO: scg failure indication, what to do? Let's remove the UE for now.
|
||||
* We could re-establish DRB?
|
||||
* Also, the way to remove is to start ue_release_timer_rrc and
|
||||
* send RRCConnectionRelease to the UE, maybe it's not good/correct.
|
||||
*/
|
||||
if (ue_context_p != NULL) {
|
||||
ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 1;
|
||||
rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8989,6 +9041,19 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
ue_to_be_removed[cur_ue]->ue_context.ue_reestablishment_timer = 0;
|
||||
}
|
||||
|
||||
/* remove UE from gNB if UE is in NSA mode */
|
||||
if (ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA ||
|
||||
ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA_RECONFIGURED) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_RELEASE_REQUEST);
|
||||
X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).rnti = ue_to_be_removed[cur_ue]->ue_context.gnb_rnti;
|
||||
X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).assoc_id = ue_to_be_removed[cur_ue]->ue_context.gnb_x2_assoc_id;
|
||||
X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).cause = X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST;
|
||||
itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, message_p);
|
||||
/* set state to RRC_NR_NSA_DELETED to avoid sending X2AP_ENDC_SGNB_RELEASE_REQUEST again later */
|
||||
ue_to_be_removed[cur_ue]->ue_context.Status = RRC_NR_NSA_DELETED;
|
||||
}
|
||||
|
||||
rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed[cur_ue]);
|
||||
|
||||
if (ue_to_be_removed[cur_ue]->ue_context.ul_failure_timer >= 20000) {
|
||||
@@ -9032,6 +9097,27 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
|
||||
}
|
||||
|
||||
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) {
|
||||
if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) {
|
||||
LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->num_cc > MAX_NUM_CCs) {
|
||||
LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n");
|
||||
return;
|
||||
}
|
||||
|
||||
RC.rrc[mod_id]->num_neigh_cells++;
|
||||
RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc;
|
||||
|
||||
for (int i=0; i<m->num_cc; i++) {
|
||||
RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i];
|
||||
RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, x2ap_ENDC_sgnb_addition_req_ACK_t *m) {
|
||||
NR_CG_Config_t *CG_Config = NULL;
|
||||
{
|
||||
@@ -9106,6 +9192,10 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
|
||||
|
||||
if (ue_context) {
|
||||
ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
|
||||
|
||||
ue_context->ue_context.gnb_rnti = m->SgNB_ue_x2_id;
|
||||
ue_context->ue_context.gnb_x2_assoc_id = m->gnb_x2_assoc_id;
|
||||
|
||||
int j=0;
|
||||
|
||||
while(j < m->nb_e_rabs_admitted_tobeadded) {
|
||||
@@ -9143,6 +9233,54 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
void rrc_eNB_process_ENDC_DC_prep_timeout(module_id_t module_id, x2ap_ENDC_dc_prep_timeout_t *m)
|
||||
{
|
||||
rrc_eNB_ue_context_t *ue_context;
|
||||
|
||||
ue_context = rrc_eNB_get_ue_context(RC.rrc[module_id], m->rnti);
|
||||
if (ue_context == NULL) {
|
||||
LOG_E(RRC, "receiving DC prep timeout for unknown UE rnti %d\n", m->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ue_context->ue_context.Status != RRC_NR_NSA) {
|
||||
LOG_E(RRC, "receiving DC prep timeout for UE rnti %d not in state RRC_NR_NSA\n", m->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I(RRC, "DC prep timeout for UE rnti %d, put back to RRC_RECONFIGURED mode\n", m->rnti);
|
||||
ue_context->ue_context.Status = RRC_RECONFIGURED;
|
||||
}
|
||||
|
||||
void rrc_eNB_process_ENDC_sgNB_release_required(module_id_t module_id, x2ap_ENDC_sgnb_release_required_t *m)
|
||||
{
|
||||
rrc_eNB_ue_context_t *ue_context;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
ue_context = rrc_eNB_find_ue_context_from_gnb_rnti(RC.rrc[module_id], m->gnb_rnti);
|
||||
if (ue_context == NULL) {
|
||||
LOG_E(RRC, "receiving ENDC SgNB Release Required for unknown UE (with gNB's rnti %d)\n", m->gnb_rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: what to do? release the UE? if yes, how? Or re-establish bearers in LTE?
|
||||
* Or something else?
|
||||
* The following removes the UE, maybe it's not correct at all.
|
||||
*/
|
||||
ue_context->ue_context.ue_release_timer_thres_rrc = 100;
|
||||
ue_context->ue_context.ue_release_timer_rrc = 1;
|
||||
|
||||
ue_context->ue_context.Status = RRC_NR_NSA_DELETED;
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
|
||||
module_id, /* TODO: should be 'instance' */
|
||||
ENB_FLAG_YES,
|
||||
ue_context->ue_context.rnti,
|
||||
0, 0);
|
||||
|
||||
rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
MessageDef *msg_p;
|
||||
@@ -9421,11 +9559,25 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
break;
|
||||
}
|
||||
|
||||
case X2AP_ENDC_SETUP_REQ:
|
||||
rrc_eNB_process_ENDC_x2_setup_request(instance, &X2AP_ENDC_SETUP_REQ(msg_p));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: {
|
||||
rrc_eNB_process_AdditionResponseInformation(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
case X2AP_ENDC_DC_PREP_TIMEOUT: {
|
||||
rrc_eNB_process_ENDC_DC_prep_timeout(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_PREP_TIMEOUT(msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
case X2AP_ENDC_SGNB_RELEASE_REQUIRED: {
|
||||
rrc_eNB_process_ENDC_sgNB_release_required(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Messages from eNB app */
|
||||
case RRC_CONFIGURATION_REQ:
|
||||
LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
|
||||
|
||||
@@ -189,6 +189,7 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
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;
|
||||
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];
|
||||
|
||||
@@ -1751,6 +1751,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0;
|
||||
|
||||
for(i = 0; i < NB_RB_MAX; i++) {
|
||||
if(xid == ue_context_p->ue_context.e_rab[i].xid) {
|
||||
|
||||
@@ -173,6 +173,23 @@ rrc_eNB_get_ue_context(
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
struct rrc_eNB_ue_context_s *
|
||||
rrc_eNB_find_ue_context_from_gnb_rnti(
|
||||
eNB_RRC_INST *rrc_instance_pP,
|
||||
int gnb_rnti)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
|
||||
if (ue_context_p->ue_context.gnb_rnti == gnb_rnti) {
|
||||
return ue_context_p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void rrc_eNB_remove_ue_context(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
|
||||
@@ -73,6 +73,11 @@ rrc_eNB_get_ue_context(
|
||||
rnti_t rntiP
|
||||
);
|
||||
|
||||
struct rrc_eNB_ue_context_s *
|
||||
rrc_eNB_find_ue_context_from_gnb_rnti(
|
||||
eNB_RRC_INST *rrc_instance_pP,
|
||||
int gnb_rnti);
|
||||
|
||||
void rrc_eNB_remove_ue_context(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
eNB_RRC_INST* rrc_instance_pP,
|
||||
|
||||
@@ -360,6 +360,8 @@ void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m);
|
||||
|
||||
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m);
|
||||
|
||||
void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m);
|
||||
|
||||
/**\brief Generate/decode the handover RRCConnectionReconfiguration at eNB
|
||||
\param module_idP Instance ID for eNB/CH
|
||||
\param frame Frame index
|
||||
|
||||
@@ -69,6 +69,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerL
|
||||
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
|
||||
|
||||
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti);
|
||||
|
||||
void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
int scg_id,
|
||||
@@ -97,3 +99,5 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2
|
||||
\param void *args_p Pointer on arguments to start the task. */
|
||||
void *rrc_gnb_task(void *args_p);
|
||||
|
||||
/* Trigger RRC periodic processing. To be called once per ms. */
|
||||
void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe);
|
||||
|
||||
@@ -301,6 +301,26 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
|
||||
parse_CG_ConfigInfo(rrc,cg_configinfo,m);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP];
|
||||
rrc_remove_nsa_user(rrc, m->rnti);
|
||||
}
|
||||
|
||||
void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC_dc_overall_timeout_t *m)
|
||||
{
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP];
|
||||
rrc_remove_nsa_user(rrc, m->rnti);
|
||||
}
|
||||
|
||||
void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
MessageDef *msg;
|
||||
|
||||
/* send a tick to x2ap */
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS);
|
||||
itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg);
|
||||
}
|
||||
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
///---------------------------------------------------------------------------------------------------------------///
|
||||
void *rrc_gnb_task(void *args_p) {
|
||||
@@ -319,7 +339,10 @@ void *rrc_gnb_task(void *args_p) {
|
||||
itti_receive_msg(TASK_RRC_GNB, &msg_p);
|
||||
msg_name_p = ITTI_MSG_NAME(msg_p);
|
||||
instance = ITTI_MSG_INSTANCE(msg_p);
|
||||
LOG_I(NR_RRC,"Received message %s\n",msg_name_p);
|
||||
|
||||
/* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */
|
||||
if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS)
|
||||
LOG_I(NR_RRC,"Received message %s\n",msg_name_p);
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
@@ -333,6 +356,10 @@ void *rrc_gnb_task(void *args_p) {
|
||||
|
||||
/* Messages from MAC */
|
||||
|
||||
case RRC_SUBFRAME_PROCESS:
|
||||
nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id);
|
||||
break;
|
||||
|
||||
/* Messages from PDCP */
|
||||
|
||||
/*
|
||||
@@ -406,6 +433,20 @@ void *rrc_gnb_task(void *args_p) {
|
||||
LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n");
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_RELEASE_REQUEST:
|
||||
LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n");
|
||||
rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_DC_OVERALL_TIMEOUT:
|
||||
rrc_gNB_process_dc_overall_timeout(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p));
|
||||
break;
|
||||
|
||||
/* Messages from GTP */
|
||||
case GTPV1U_ENB_DELETE_TUNNEL_RESP:
|
||||
/* nothing to do? */
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p);
|
||||
break;
|
||||
@@ -417,3 +458,11 @@ void *rrc_gnb_task(void *args_p) {
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_RRC_GNB, RRC_SUBFRAME_PROCESS);
|
||||
RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt;
|
||||
RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id;
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
* \company Eurecom
|
||||
* \email: raymond.knopp@eurecom.fr
|
||||
*/
|
||||
#ifndef RRC_GNB_NSA_C
|
||||
#define RRC_GNB_NSA_C
|
||||
|
||||
#include "nr_rrc_defs.h"
|
||||
#include "NR_RRCReconfiguration.h"
|
||||
@@ -247,15 +245,21 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n");
|
||||
}
|
||||
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
|
||||
// Send to X2 entity to transport to MeNB
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
|
||||
NULL,
|
||||
(void *)CG_Config,
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer,
|
||||
1024);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3;
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
|
||||
if (m != NULL) {
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id;
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
|
||||
|
||||
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
|
||||
// Send to X2 entity to transport to MeNB
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
|
||||
NULL,
|
||||
(void *)CG_Config,
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer,
|
||||
1024);
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3;
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding
|
||||
}
|
||||
|
||||
rrc->Nb_ue++;
|
||||
// configure MAC and RLC
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
@@ -290,5 +294,45 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
|
||||
}
|
||||
|
||||
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
|
||||
protocol_ctxt_t ctxt;
|
||||
rrc_gNB_ue_context_t *ue_context;
|
||||
MessageDef *msg_delete_tunnels_p;
|
||||
int e_rab;
|
||||
|
||||
#endif
|
||||
LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id);
|
||||
|
||||
ue_context = rrc_gNB_get_ue_context(rrc, rnti);
|
||||
if (ue_context == NULL) {
|
||||
LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
pdcp_remove_UE(&ctxt);
|
||||
|
||||
rrc_rlc_remove_ue(&ctxt);
|
||||
|
||||
mac_remove_nr_ue(rrc->module_id, rnti);
|
||||
|
||||
/* delete gtp tunnel */
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = rnti;
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 1;
|
||||
|
||||
LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d\n", ue_context->ue_context.nb_of_e_rabs);
|
||||
for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
ue_context->ue_context.gnb_gtp_ebi[e_rab];
|
||||
// erase data
|
||||
ue_context->ue_context.gnb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab]));
|
||||
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);
|
||||
|
||||
/* remove context */
|
||||
rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context);
|
||||
}
|
||||
|
||||
+64
-38
@@ -305,7 +305,9 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
|
||||
x2ap_id_manager_init(&new_instance->id_manager);
|
||||
x2ap_timers_init(&new_instance->timers,
|
||||
x2ap_register_eNB->t_reloc_prep,
|
||||
x2ap_register_eNB->tx2_reloc_overall);
|
||||
x2ap_register_eNB->tx2_reloc_overall,
|
||||
x2ap_register_eNB->t_dc_prep,
|
||||
x2ap_register_eNB->t_dc_overall);
|
||||
|
||||
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
|
||||
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
|
||||
@@ -476,7 +478,10 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
|
||||
}
|
||||
/* id_source is ue_id, id_target is unknown yet */
|
||||
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
|
||||
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
|
||||
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_ENB_PREPARE);
|
||||
x2ap_set_dc_prep_timer(id_manager, ue_id,
|
||||
x2ap_timer_get_tti(&instance_p->timers));
|
||||
x2ap_id_set_target(id_manager, ue_id, x2ap_eNB_data);
|
||||
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req,
|
||||
x2ap_eNB_data, ue_id);
|
||||
@@ -498,9 +503,6 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *target;
|
||||
int ue_id;
|
||||
/*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id;
|
||||
int id_source;
|
||||
int id_target;*/
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
@@ -514,22 +516,15 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
|
||||
X2AP_ERROR("could not allocate a new X2AP UE ID\n");
|
||||
exit(1);
|
||||
}
|
||||
/* id_source is ue_id, id_target is unknown yet */
|
||||
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req_ACK->rnti, ue_id,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id);
|
||||
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL);
|
||||
|
||||
|
||||
/*target = x2ap_get_eNB(NULL, source_assoc_id, 0);
|
||||
DevAssert(target != NULL);*/
|
||||
|
||||
// rnti is a new information, save it
|
||||
|
||||
/*ue_id = x2ap_handover_req_ack->x2_id_target;
|
||||
id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
id_target = ue_id;
|
||||
x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/
|
||||
|
||||
/* id_Source is MeNB_ue_x2_id, id_target is rnti (rnti is SgNB_ue_x2_id) */
|
||||
x2ap_set_ids(id_manager, ue_id,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id);
|
||||
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_GNB_OVERALL);
|
||||
x2ap_set_dc_overall_timer(id_manager, ue_id,
|
||||
x2ap_timer_get_tti(&instance_p->timers));
|
||||
x2ap_id_set_target(id_manager, ue_id, target);
|
||||
|
||||
x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target,
|
||||
x2ap_ENDC_sgnb_addition_req_ACK, ue_id);
|
||||
@@ -540,27 +535,24 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
|
||||
* @param : IN instance, IN x2ap_reconf_complete
|
||||
**/
|
||||
static
|
||||
void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance,
|
||||
x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete)
|
||||
void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance,
|
||||
x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete)
|
||||
{
|
||||
x2ap_eNB_instance_t *instance_p = NULL;
|
||||
x2ap_eNB_data_t *target = NULL;
|
||||
int id_source = -1;
|
||||
int id_target = -1;
|
||||
LTE_PhysCellId_t target_pci;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *target;
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_reconf_complete != NULL);
|
||||
|
||||
target_pci = x2ap_reconf_complete->target_physCellId;
|
||||
target = x2ap_is_eNB_pci_in_list(target_pci);
|
||||
|
||||
target = x2ap_get_eNB(NULL,x2ap_reconf_complete->gnb_x2_assoc_id, 0);
|
||||
DevAssert(target != NULL);
|
||||
|
||||
|
||||
id_source = x2ap_reconf_complete->MeNB_ue_x2_id;
|
||||
id_target = x2ap_reconf_complete->SgNB_ue_x2_id;
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(instance_p, target, id_source, id_target);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -589,6 +581,34 @@ void x2ap_eNB_ue_context_release(instance_t instance,
|
||||
x2ap_release_id(&instance_p->id_manager, ue_id);
|
||||
}
|
||||
|
||||
static
|
||||
void x2ap_eNB_handle_sgNB_release_request(instance_t instance,
|
||||
x2ap_ENDC_sgnb_release_request_t *x2ap_release_req)
|
||||
{
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *target;
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_release_req != NULL);
|
||||
|
||||
if (x2ap_release_req->rnti == -1 ||
|
||||
x2ap_release_req->assoc_id == -1) {
|
||||
X2AP_WARN("x2ap_eNB_handle_sgNB_release_request: bad rnti or assoc_id, do not send release request to gNB\n");
|
||||
return;
|
||||
}
|
||||
|
||||
target = x2ap_get_eNB(NULL, x2ap_release_req->assoc_id, 0);
|
||||
DevAssert(target != NULL);
|
||||
|
||||
/* id_source is not used by oai's gNB so it's not big deal. For
|
||||
* interoperability with other gNBs things may need to be refined.
|
||||
*/
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_release_request(instance_p, target,
|
||||
0, x2ap_release_req->rnti,
|
||||
x2ap_release_req->cause);
|
||||
}
|
||||
|
||||
void *x2ap_task(void *arg) {
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
@@ -640,10 +660,16 @@ void *x2ap_task(void *arg) {
|
||||
LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n");
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
|
||||
x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg));
|
||||
break;
|
||||
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
|
||||
x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg));
|
||||
break;
|
||||
|
||||
case X2AP_ENDC_SGNB_RELEASE_REQUEST:
|
||||
x2ap_eNB_handle_sgNB_release_request(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_ENDC_SGNB_RELEASE_REQUEST(received_msg));
|
||||
break;
|
||||
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
|
||||
@@ -69,6 +69,14 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n");
|
||||
break;
|
||||
|
||||
case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease:
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease message!\n");
|
||||
break;
|
||||
|
||||
case X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease:
|
||||
X2AP_INFO("X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease message!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)pdu->choice.initiatingMessage.procedureCode);
|
||||
@@ -103,6 +111,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu)
|
||||
X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n");
|
||||
break;
|
||||
|
||||
case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease:
|
||||
X2AP_INFO("meNBinitiatedSgNBRelease successful outcome!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)pdu->choice.successfulOutcome.procedureCode);
|
||||
|
||||
@@ -119,6 +119,8 @@ typedef struct x2ap_eNB_data_s {
|
||||
/* Nid cells */
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
/*Frequency band of NR neighbor cell supporting ENDC NSA */
|
||||
uint32_t servedNrCell_band[MAX_NUM_CCs];
|
||||
|
||||
/* Only meaningfull in virtual mode */
|
||||
struct x2ap_eNB_instance_s *x2ap_eNB_instance;
|
||||
|
||||
@@ -1317,7 +1317,7 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
|
||||
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
|
||||
if (freq_band == NULL)
|
||||
exit(1);
|
||||
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
|
||||
freq_band->freqBandIndicatorNr = instance_p->eutra_band[0];
|
||||
|
||||
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
|
||||
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
|
||||
@@ -1668,8 +1668,6 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
int MeNB_UE_X2AP_id = x2ap_sgnb_addition_req_ACK->MeNB_ue_x2_id;
|
||||
int SgNB_UE_X2AP_id = ue_id;
|
||||
int e_rabs_admitted_tobeadded = x2ap_sgnb_addition_req_ACK->nb_e_rabs_admitted_tobeadded;
|
||||
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
|
||||
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
|
||||
@@ -1694,7 +1692,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
// SgNB_UE_X2AP_id
|
||||
@@ -1702,7 +1700,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_target(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
|
||||
@@ -1792,7 +1790,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
|
||||
@@ -1821,3 +1819,226 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBReleaseRequest_t *out;
|
||||
X2AP_SgNBReleaseRequest_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
|
||||
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
|
||||
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequest;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequest;
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = x2_id_source;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2_id_target != -1) {
|
||||
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
}
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_Cause;
|
||||
switch (cause) {
|
||||
case X2AP_CAUSE_T_DC_PREP_TIMEOUT:
|
||||
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCprep_expiry;
|
||||
break;
|
||||
case X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST:
|
||||
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_radio_connection_with_UE_lost;
|
||||
break;
|
||||
default:
|
||||
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
|
||||
exit(1);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBReleaseRequestAcknowledge_t *out;
|
||||
X2AP_SgNBReleaseRequestAcknowledge_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING;
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_ignore;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseRequestAcknowledge;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseRequestAcknowledge;
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_release_required(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBReleaseRequired_t *out;
|
||||
X2AP_SgNBReleaseRequired_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
/* Prepare the X2AP message to encode */
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
|
||||
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequired;
|
||||
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequired;
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = x2_id_source;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_reject;
|
||||
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_Cause;
|
||||
switch (cause) {
|
||||
case X2AP_CAUSE_T_DC_OVERALL_TIMEOUT:
|
||||
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
||||
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCoverall_expiry;
|
||||
break;
|
||||
default:
|
||||
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
|
||||
exit(1);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
|
||||
{
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
X2AP_SgNBReleaseConfirm_t *out;
|
||||
X2AP_SgNBReleaseConfirm_IEs_t *ie;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
int ret = 0;
|
||||
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(x2ap_eNB_data_p != NULL);
|
||||
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
|
||||
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
||||
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseConfirm;
|
||||
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseConfirm;
|
||||
|
||||
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_UE_X2AP_ID;
|
||||
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
|
||||
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
||||
ie->criticality= X2AP_Criticality_ignore;
|
||||
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_SgNB_UE_X2AP_ID;
|
||||
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -77,4 +77,16 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
|
||||
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id);
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int x2_id_source, int x2_id_target, x2ap_cause_t cause);
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id);
|
||||
|
||||
int x2ap_eNB_generate_ENDC_x2_SgNB_release_required(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int x2_id_source, int x2_id_target, x2ap_cause_t cause);
|
||||
|
||||
int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id);
|
||||
|
||||
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
|
||||
|
||||
+381
-135
@@ -44,6 +44,7 @@
|
||||
#include "msc.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "X2AP_FreqBandNrItem.h"
|
||||
|
||||
static
|
||||
int x2ap_eNB_handle_x2_setup_request (instance_t instance,
|
||||
@@ -132,6 +133,29 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_request(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_required(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_confirm(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */
|
||||
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
@@ -166,8 +190,9 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBReconfigurationCompletion*/
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ x2ap_gNB_handle_ENDC_sGNB_release_request, x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge, 0 }, /* meNBinitiatedSgNBRelease */
|
||||
{ x2ap_gNB_handle_ENDC_sGNB_release_required, x2ap_gNB_handle_ENDC_sGNB_release_confirm, 0 }, /* sgNBinitiatedSgNBRelease */
|
||||
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
@@ -1354,13 +1379,13 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
MessageDef *msg;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
uint32_t gNB_id = 0;
|
||||
|
||||
x2ap_eNB_data = NULL;
|
||||
DevAssert (pdu != NULL);
|
||||
x2_ENDC_SetupRequest = &pdu->choice.initiatingMessage.value.choice.ENDCX2SetupRequest;
|
||||
|
||||
/*
|
||||
* We received a new valid X2 Setup Request on a stream != 0.
|
||||
* * * * This should not happen -> reject eNB x2 setup request.
|
||||
@@ -1385,103 +1410,110 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup, true);
|
||||
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SETUP_REQ);
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
} else {
|
||||
if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count > 0) {
|
||||
for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) {
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
|
||||
if (ie_GNB_ENDC == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) {
|
||||
else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) {
|
||||
if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) {
|
||||
//TODO: handle case were size != 28 -> notify ? reject ?
|
||||
}
|
||||
OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id);
|
||||
X2AP_DEBUG("gNB id: %07x\n", gNB_id);
|
||||
|
||||
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
|
||||
if (ie_GNB_ENDC == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
X2AP_DEBUG("Adding gNB to the list of associated gNBs\n");
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) {
|
||||
/*
|
||||
* eNB has not been found in list of associated eNB,
|
||||
* * * * Add it to the tail of list and initialize data
|
||||
*/
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
|
||||
/*
|
||||
* ??
|
||||
*/
|
||||
return -1;
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
x2ap_eNB_data->eNB_id = gNB_id;
|
||||
}
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
/*
|
||||
* eNB has been found in list, consider the x2 setup request as a reset connection,
|
||||
* * * * reseting any previous UE state if sctp association is != than the previous one
|
||||
*/
|
||||
if (x2ap_eNB_data->assoc_id != assoc_id) {
|
||||
/*
|
||||
* ??: Send an overload cause...
|
||||
*/
|
||||
X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id);
|
||||
|
||||
else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) {
|
||||
if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) {
|
||||
//TODO: handle case were size != 28 -> notify ? reject ?
|
||||
}
|
||||
OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id);
|
||||
X2AP_DEBUG("gNB id: %07x\n", gNB_id);
|
||||
// Here we should be calling an ENDC specific setup_failure function instead
|
||||
x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* * TODO: call the reset procedure
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){
|
||||
if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;
|
||||
X2AP_ENDC_SETUP_REQ(msg).num_cc = x2ap_eNB_data->num_cc;
|
||||
for (int i=0; i<ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) {
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI;
|
||||
X2AP_ENDC_SETUP_REQ(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i];
|
||||
//servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0]
|
||||
if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) {
|
||||
X2AP_INFO("TAC: %02x%02x%02x\n",
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
} else {
|
||||
X2AP_INFO("TAC: (NULL)\n");
|
||||
}
|
||||
|
||||
X2AP_DEBUG("Adding gNB to the list of associated gNBs\n");
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) {
|
||||
/*
|
||||
* eNB has not been found in list of associated eNB,
|
||||
* * * * Add it to the tail of list and initialize data
|
||||
*/
|
||||
if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) {
|
||||
/*
|
||||
* ??
|
||||
*/
|
||||
return -1;
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
x2ap_eNB_data->eNB_id = gNB_id;
|
||||
}
|
||||
} else {
|
||||
x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING;
|
||||
|
||||
/*
|
||||
* eNB has been found in list, consider the x2 setup request as a reset connection,
|
||||
* * * * reseting any previous UE state if sctp association is != than the previous one
|
||||
*/
|
||||
if (x2ap_eNB_data->assoc_id != assoc_id) {
|
||||
/*
|
||||
* ??: Send an overload cause...
|
||||
*/
|
||||
X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id);
|
||||
|
||||
// Panos: Here we should be calling an ENDC specific setup_failure function instead
|
||||
x2ap_eNB_generate_x2_setup_failure (instance,
|
||||
assoc_id,
|
||||
X2AP_Cause_PR_protocol,
|
||||
X2AP_CauseProtocol_unspecified,
|
||||
-1);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* * TODO: call the reset procedure
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){
|
||||
if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) {
|
||||
x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;
|
||||
for (int i=0; i<ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) {
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i];
|
||||
x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI;
|
||||
//servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0]
|
||||
if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) {
|
||||
X2AP_INFO("TAC: %02x%02x%02x\n",
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
} else {
|
||||
X2AP_INFO("TAC: (NULL)\n");
|
||||
}
|
||||
|
||||
X2AP_INFO("PLMN: %02x%02x%02x\n",
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
X2AP_INFO("PLMN: %02x%02x%02x\n",
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]);
|
||||
if(servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr.list.count > 0){
|
||||
X2AP_FreqBandNrItem_t *FreqBandItem = servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr.list.array[0];
|
||||
x2ap_eNB_data->servedNrCell_band[i] = FreqBandItem->freqBandIndicatorNr;
|
||||
X2AP_ENDC_SETUP_REQ(msg).servedNrCell_band[i] = x2ap_eNB_data->servedNrCell_band[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
}
|
||||
|
||||
@@ -1641,8 +1673,6 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
|
||||
|
||||
X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest;
|
||||
X2AP_SgNBAdditionRequest_IEs_t *ie;
|
||||
|
||||
@@ -1823,6 +1853,8 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
|
||||
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
|
||||
|
||||
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).gnb_x2_assoc_id = assoc_id;
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
@@ -1923,6 +1955,9 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
/* remove UE from x2, DC preparation is over */
|
||||
x2ap_release_id(&instance_p->id_manager, ue_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1930,78 +1965,289 @@ static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu) {
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete;
|
||||
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
|
||||
|
||||
X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete;
|
||||
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
int id_target;
|
||||
int ue_id;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
|
||||
DevAssert (pdu != NULL);
|
||||
x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n");
|
||||
X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
//Allocate an ITTI X2AP_sGNB_reconfiguration_complete message
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
|
||||
//Allocate an ITTI X2AP_sGNB_reconfiguration_complete message
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
id_target = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = id_target;
|
||||
|
||||
ue_id = x2ap_find_id_from_id_target(&instance_p->id_manager, id_target);
|
||||
if (ue_id == -1) {
|
||||
X2AP_WARN("incorrect/unknown X2AP IDs for UE (SgNB_UE_X2AP_ID %d), ignoring sGNB reconfiguration complete\n",
|
||||
id_target);
|
||||
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
|
||||
X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ie->value.choice.ResponseInformationSgNBReconfComp.present == X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_SUCCESS;
|
||||
}
|
||||
else {
|
||||
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_REJECT;
|
||||
}
|
||||
if (ie->value.choice.ResponseInformationSgNBReconfComp.present != X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){
|
||||
X2AP_ERROR("%s %d: fatal: unsuccessfulSgNB Reconfiguration Complete\n",__FILE__,__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
x2ap_release_id(&instance_p->id_manager, ue_id);
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_request(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
/* the logic in this function is the following: when receiving a release
|
||||
* request, the UE may exist in X2. Or not. If it's not in X2, it can
|
||||
* nevertheless be in RRC.
|
||||
* The release request message may contain the gNB id. Or not. It's better
|
||||
* to look for the UE using the gNB rather than the eNB id. So if we have
|
||||
* the gNB id we use it. If not, we use the eNB id.
|
||||
*/
|
||||
X2AP_SgNBReleaseRequest_t *req;
|
||||
X2AP_SgNBReleaseRequest_IEs_t *ie;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
|
||||
int id_source;
|
||||
int id_target;
|
||||
int rnti;
|
||||
int ue_id;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
req = &pdu->choice.initiatingMessage.value.choice.SgNBReleaseRequest;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received X2 SgNB Release Request message\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequest_IEs_t, ie, req,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_source = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequest_IEs_t, ie, req,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, false);
|
||||
if (ie != NULL)
|
||||
id_target = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
else
|
||||
id_target = -1;
|
||||
|
||||
/* find ue_id, preferably from id_target if id_target is known */
|
||||
ue_id = -1;
|
||||
if (id_target != -1)
|
||||
ue_id = x2ap_find_id_from_id_target(&instance_p->id_manager, id_target);
|
||||
if (ue_id == -1)
|
||||
ue_id = x2ap_find_id_from_id_source(&instance_p->id_manager, id_source);
|
||||
|
||||
if (ue_id == -1) {
|
||||
X2AP_WARN("%s %d: no UE found for id_source %d id_target %d\n",
|
||||
__FILE__, __LINE__, id_source, id_target);
|
||||
}
|
||||
|
||||
/* the UE may not exist in X2 anymore but exist in RRC
|
||||
* in which case its rnti is simply the id_target
|
||||
*/
|
||||
if (ue_id != -1) {
|
||||
rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id);
|
||||
|
||||
/* remove ue_id */
|
||||
x2ap_release_id(&instance_p->id_manager, ue_id);
|
||||
} else {
|
||||
rnti = id_target;
|
||||
}
|
||||
|
||||
if (rnti != -1) {
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUEST);
|
||||
|
||||
X2AP_ENDC_SGNB_RELEASE_REQUEST(msg).rnti = rnti;
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
}
|
||||
|
||||
/* this call should maybe not be here, we should check that the
|
||||
* SgNB Release Request message has been executed properly
|
||||
*/
|
||||
x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(instance_p, x2ap_eNB_data,
|
||||
id_source,
|
||||
rnti != -1 ? rnti : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
/* nothing to do - may change at some point */
|
||||
X2AP_INFO("received release request acknowledge\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_required(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
/* the logic in this function is the following: when receiving a release
|
||||
* required we don't care about the UE in X2. We simply send a message
|
||||
* to RRC with the SgNB id (which is SgNB's RNTI). RRC will look for the
|
||||
* UE using this RNTI and deal with it. In the meanwhile the X2 layer
|
||||
* immediately replies with "release confirm" no matter what happens
|
||||
* in RRC.
|
||||
*/
|
||||
X2AP_SgNBReleaseRequired_t *req;
|
||||
X2AP_SgNBReleaseRequired_IEs_t *ie;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
|
||||
int id_source;
|
||||
int id_target;
|
||||
int gnb_rnti;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
req = &pdu->choice.initiatingMessage.value.choice.SgNBReleaseRequired;
|
||||
|
||||
/*if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
|
||||
// TODO: send a x2 failure response
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
X2AP_DEBUG ("Received X2 SgNB Release Required message\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequired_IEs_t, ie, req,
|
||||
X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_source = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequired_IEs_t, ie, req,
|
||||
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_target = ie->value.choice.SgNB_UE_X2AP_ID;
|
||||
|
||||
gnb_rnti = id_target;
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUIRED);
|
||||
X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg).gnb_rnti = gnb_rnti;
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
/* this call should maybe not be here, we should check that the
|
||||
* SgNB Release Required message has been executed properly
|
||||
*/
|
||||
x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(instance_p, x2ap_eNB_data,
|
||||
id_source, id_target);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int x2ap_gNB_handle_ENDC_sGNB_release_confirm(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
/* nothing to do - may change at some point */
|
||||
X2AP_INFO("received release confirm\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,16 @@ int x2ap_find_id_from_id_source(x2ap_id_manager *m, int id_source)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x2ap_find_id_from_id_target(x2ap_id_manager *m, int id_target)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < X2AP_MAX_IDS; i++)
|
||||
if (m->ids[i].rnti != -1 &&
|
||||
m->ids[i].id_target == id_target)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti)
|
||||
{
|
||||
int i;
|
||||
@@ -107,6 +117,16 @@ void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
|
||||
m->ids[ue_id].tx2_reloc_overall_start = time;
|
||||
}
|
||||
|
||||
void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].t_dc_prep_start = time;
|
||||
}
|
||||
|
||||
void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time)
|
||||
{
|
||||
m->ids[ue_id].t_dc_overall_start = time;
|
||||
}
|
||||
|
||||
int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id)
|
||||
{
|
||||
return m->ids[ue_id].id_source;
|
||||
|
||||
@@ -38,7 +38,8 @@ typedef enum {
|
||||
X2ID_STATE_SOURCE_PREPARE,
|
||||
X2ID_STATE_SOURCE_OVERALL,
|
||||
X2ID_STATE_TARGET,
|
||||
X2ID_STATE_NSA_PREPARE,
|
||||
X2ID_STATE_NSA_ENB_PREPARE,
|
||||
X2ID_STATE_NSA_GNB_OVERALL,
|
||||
} x2id_state_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -55,6 +56,8 @@ typedef struct {
|
||||
/* timers */
|
||||
uint64_t t_reloc_prep_start;
|
||||
uint64_t tx2_reloc_overall_start;
|
||||
uint64_t t_dc_prep_start;
|
||||
uint64_t t_dc_overall_start;
|
||||
} x2ap_id;
|
||||
|
||||
typedef struct {
|
||||
@@ -66,6 +69,7 @@ int x2ap_allocate_new_id(x2ap_id_manager *m);
|
||||
void x2ap_release_id(x2ap_id_manager *m, int id);
|
||||
int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target);
|
||||
int x2ap_find_id_from_id_source(x2ap_id_manager *, int id_source);
|
||||
int x2ap_find_id_from_id_target(x2ap_id_manager *, int id_source);
|
||||
int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti);
|
||||
void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
|
||||
void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state);
|
||||
@@ -73,6 +77,8 @@ void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state);
|
||||
void x2ap_id_set_target(x2ap_id_manager *m, int ue_id, void *target);
|
||||
void x2ap_set_reloc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
|
||||
void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
|
||||
void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
|
||||
void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time);
|
||||
int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id);
|
||||
int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id);
|
||||
int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id);
|
||||
|
||||
@@ -28,11 +28,17 @@
|
||||
#include "x2ap_eNB_management_procedures.h"
|
||||
#include "x2ap_eNB_generate_messages.h"
|
||||
|
||||
void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall)
|
||||
void x2ap_timers_init(x2ap_timers_t *t,
|
||||
int t_reloc_prep,
|
||||
int tx2_reloc_overall,
|
||||
int t_dc_prep,
|
||||
int t_dc_overall)
|
||||
{
|
||||
t->tti = 0;
|
||||
t->t_reloc_prep = t_reloc_prep;
|
||||
t->tx2_reloc_overall = tx2_reloc_overall;
|
||||
t->t_dc_prep = t_dc_prep;
|
||||
t->t_dc_overall = t_dc_overall;
|
||||
}
|
||||
|
||||
void x2ap_check_timers(instance_t instance)
|
||||
@@ -59,14 +65,17 @@ void x2ap_check_timers(instance_t instance)
|
||||
|
||||
for (i = 0; i < X2AP_MAX_IDS; i++) {
|
||||
if (m->ids[i].rnti == -1) continue;
|
||||
x2_ongoing++;
|
||||
|
||||
if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE ||
|
||||
m->ids[i].state == X2ID_STATE_SOURCE_OVERALL)
|
||||
x2_ongoing++;
|
||||
|
||||
if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE &&
|
||||
t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) {
|
||||
LOG_I(X2AP, "X2 timeout reloc prep\n");
|
||||
/* t_reloc_prep timed out */
|
||||
cause = X2AP_T_RELOC_PREP_TIMEOUT;
|
||||
goto timeout;
|
||||
goto lte_handover_timeout;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == X2ID_STATE_SOURCE_OVERALL &&
|
||||
@@ -74,13 +83,62 @@ void x2ap_check_timers(instance_t instance)
|
||||
LOG_I(X2AP, "X2 timeout reloc overall\n");
|
||||
/* tx2_reloc_overall timed out */
|
||||
cause = X2AP_TX2_RELOC_OVERALL_TIMEOUT;
|
||||
goto timeout;
|
||||
goto lte_handover_timeout;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == X2ID_STATE_NSA_ENB_PREPARE &&
|
||||
t->tti > m->ids[i].t_dc_prep_start + t->t_dc_prep) {
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
LOG_I(X2AP, "X2 timeout DC prep\n");
|
||||
/* t_dc_prep timed out */
|
||||
target = x2ap_id_get_target(m, i);
|
||||
id_source = x2ap_id_get_id_source(m, i);
|
||||
id_target = x2ap_id_get_id_target(m, i);
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_release_request(instance_p, target,
|
||||
id_source, id_target,
|
||||
X2AP_CAUSE_T_DC_PREP_TIMEOUT);
|
||||
|
||||
/* inform RRC of timeout */
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_PREP_TIMEOUT);
|
||||
X2AP_ENDC_DC_PREP_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i);
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
|
||||
|
||||
/* remove UE from X2AP */
|
||||
x2ap_release_id(m, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m->ids[i].state == X2ID_STATE_NSA_GNB_OVERALL &&
|
||||
t->tti > m->ids[i].t_dc_overall_start + t->t_dc_overall) {
|
||||
int id_source;
|
||||
int id_target;
|
||||
|
||||
LOG_I(X2AP, "X2 timeout DC overall\n");
|
||||
/* t_dc_overall timed out */
|
||||
target = x2ap_id_get_target(m, i);
|
||||
id_source = x2ap_id_get_id_source(m, i);
|
||||
id_target = x2ap_id_get_id_target(m, i);
|
||||
x2ap_eNB_generate_ENDC_x2_SgNB_release_required(instance_p, target,
|
||||
id_source, id_target, X2AP_CAUSE_T_DC_OVERALL_TIMEOUT);
|
||||
|
||||
/* inform RRC of timeout */
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_OVERALL_TIMEOUT);
|
||||
X2AP_ENDC_DC_OVERALL_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i);
|
||||
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
|
||||
|
||||
/* remove UE from X2AP */
|
||||
x2ap_release_id(m, i);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* no timeout -> check next UE */
|
||||
continue;
|
||||
|
||||
timeout:
|
||||
lte_handover_timeout:
|
||||
/* inform target about timeout */
|
||||
target = x2ap_id_get_target(m, i);
|
||||
x2ap_eNB_generate_x2_handover_cancel(instance_p, target, i, cause);
|
||||
|
||||
@@ -36,9 +36,15 @@ typedef struct {
|
||||
/* timer values (unit: TTI, ie. millisecond when in realtime) */
|
||||
int t_reloc_prep;
|
||||
int tx2_reloc_overall;
|
||||
int t_dc_prep;
|
||||
int t_dc_overall;
|
||||
} x2ap_timers_t;
|
||||
|
||||
void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall);
|
||||
void x2ap_timers_init(x2ap_timers_t *t,
|
||||
int t_reloc_prep,
|
||||
int tx2_reloc_overall,
|
||||
int t_dc_prep,
|
||||
int t_dc_overall);
|
||||
void x2ap_check_timers(instance_t instance);
|
||||
uint64_t x2ap_timer_get_tti(x2ap_timers_t *t);
|
||||
|
||||
|
||||
@@ -1184,7 +1184,10 @@ int gtpv1u_delete_s1u_tunnel(
|
||||
"0 GTPV1U_ENB_DELETE_TUNNEL_RESP rnti %x teid %x",
|
||||
GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti,
|
||||
teid_eNB);
|
||||
return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
|
||||
if (req_pP->from_gnb)
|
||||
return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p);
|
||||
else
|
||||
return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -55,6 +55,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -42,6 +42,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -187,6 +187,8 @@ eNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -214,6 +214,8 @@ gNBs =
|
||||
enable_x2 = "yes";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
target_enb_x2_ip_address = (
|
||||
{ ipv4 = "127.0.0.1";
|
||||
ipv6 = "192:168:30::17";
|
||||
|
||||
@@ -367,6 +367,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -148,6 +148,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -184,6 +184,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
@@ -148,6 +148,8 @@ eNBs =
|
||||
enable_x2 = "no";
|
||||
t_reloc_prep = 1000; /* unit: millisecond */
|
||||
tx2_reloc_overall = 2000; /* unit: millisecond */
|
||||
t_dc_prep = 1000; /* unit: millisecond */
|
||||
t_dc_overall = 2000; /* unit: millisecond */
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user