diff --git a/README.txt b/README.txt index 0a99216435635c0447563e915ff19667d0f7aba6..6280cd5ec6b5bbd4c894c0d31c1b4a960be5363f 100644 --- a/README.txt +++ b/README.txt @@ -43,17 +43,36 @@ openairinterface5g RELEASE NOTES: -v0.1 -> Last stable commit on develop branch before enhancement-10-harmony -v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU -v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License -v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0 -v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support -v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB -v0.5.2 -> Last version with old code for oaisim (abstraction mode works) -v0.6 -> RRH functionality, UE greatly improved, better TDD support, - a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not - work, you need to use v0.5.2 for that. -v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI. +v1.1.0 -> July 2019. This version adds the following implemented features: + * Experimental support of LTE-M + - Single LTE-M UE attachment, legacy-LTE UE attachment is disabled + * X2 interface and handover (also X2-U interface) + - In FDD and TDD + * CU/DU split (F1 interface) + - Tested only in FDD + * CDRX + - Tested only in FDD + * Experimental eMBMS support (only on UE side) + * Experimental multi-RRU support + - Tested only in TDD + This version has an improved code quality: + * Simplification of the Build System + - A single build includes all full-stack simulators, S1/noS1 modes and one HW platform (such as USRP, BladeRF, ...) + * TUN interface is now used as default for the data plane + - for UE, eNB-noS1 and UE-noS1 + * Code Cleanup + * Better Static Code Analysis: + - Limited number of errors in cppcheck + - Important Decrease on high Impact errors in CoverityScan + * Better Test Coverage in Continuous Integration: + - TM2, CDRX, IF4.5, F1 + - OAI UE is tested in S1 and noS1 modes with USRP board + - Multi-RRU TDD mode + - X2 Handover in FDD mode + +v1.0.3 -> June 2019: Bug fix for LimeSuite v19.04.0 API +v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD +v1.0.1 -> February 2019: Bug fix for the UE L1 simulator. v1.0.0 -> January 2019. This version first implements the architectural split described in doc/oai_lte_enb_func_split_arch.png picture. Only FAPI, nFAPI and IF4.5 interfaces are implemented. Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR. @@ -61,6 +80,15 @@ v1.0.0 -> January 2019. This version first implements the architectural split de S1-flex has been introduced. New tools: config library, telnet server, ... A lot of bugfixes and a proper automated Continuous Integration process validates contributions. -v1.0.1 -> February 2019: Bug fix for the UE L1 simulator. -v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD -v1.0.3 -> June 2019: Bug fix for LimeSuite v19.04.0 API + +v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI. +v0.6 -> RRH functionality, UE greatly improved, better TDD support, + a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not + work, you need to use v0.5.2 for that. +v0.5.2 -> Last version with old code for oaisim (abstraction mode works) +v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB +v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support +v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0 +v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License +v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU +v0.1 -> Last stable commit on develop branch before enhancement-10-harmony diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 3569a22715e6742cbd21412a06926b104c961721..6ffac9a806cc8d696300db58a082568eb08c5f61 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -44,7 +44,7 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build gNb-usrp", "Build nr-UE-usrp", "Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13"]) + gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-Mono-FDD-Band13-X2-HO"]) ansiColor('xterm') } @@ -232,7 +232,7 @@ pipeline { } stage ("Build 5G gNB-USRP") { steps { - gitlabCommitStatus(name: "Build gNb-usrp") { + gitlabCommitStatus(name: "Build gNB-USRP") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } @@ -241,16 +241,16 @@ pipeline { } stage ("Build 5G NR-UE-USRP") { steps { - gitlabCommitStatus(name: "Build nr-UE-usrp") { + gitlabCommitStatus(name: "Build nr-UE-USRP") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } } - stage ("Build eNb-USRP") { + stage ("Build eNB-USRP") { steps { - gitlabCommitStatus(name: "Build eNb-USRP") { + gitlabCommitStatus(name: "Build eNB-USRP") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } @@ -266,9 +266,9 @@ pipeline { } } } - stage ("Build eNb-ethernet") { + stage ("Build eNB-ethernet") { steps { - gitlabCommitStatus(name: "Build eNb-ethernet") { + gitlabCommitStatus(name: "Build eNB-ethernet") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } @@ -284,12 +284,12 @@ pipeline { } } } - stage ("Build eNb-USRP on Red Hat") { + stage ("Build eNB-USRP on Red Hat") { when { expression {doRedHatBuild} } steps { - gitlabCommitStatus(name: "Build eNb-USRP-RHE") { + gitlabCommitStatus(name: "Build eNB-USRP-RHE") { script { try { withCredentials([ @@ -538,6 +538,7 @@ pipeline { stage ("Test MONOLITHIC - FDD - Band 13 - B210") { steps { script { + sh "sleep 60" triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13') } } @@ -554,6 +555,26 @@ pipeline { } } } + stage ("Test X2 Handover - FDD - Band 13 - B210") { + steps { + script { + sh "sleep 60" + triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-X2HO-B210', 'Test-Mono-FDD-Band13-X2-HO') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-X2HO-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test OAI UE - FDD - Band 20 - B200") { steps { script { diff --git a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..2a7783da08bfbab86560711358f8b652c6253cba --- /dev/null +++ b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf @@ -0,0 +1,271 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe01; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + + nr_cellid = 98765L; + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 1; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 110; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "eth0"; + FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD";//PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..c76a664c15648bf2951fd04e5b359fd577a6ede6 --- /dev/null +++ b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf @@ -0,0 +1,276 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + + nr_cellid = 123456L; + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 110; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "CI_RCC_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "eth0"; + FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD";//PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index 81fc7eedce43275998cfca24428ee77563e79452..28bfd91560d9085aa446f3e1267b6cf7853ea665 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -218,7 +218,7 @@ MACRLCs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_SINGLE_THREAD"; + parallel_config = "PARALLEL_RU_L1_SPLIT"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 6079421190138e729276f3cbea58e07e1dae88b5..d465e7075cae04515e2cce3dfb6f9ec3b8d4b34d 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -63,6 +63,12 @@ UE_STATUS_DETACHING = 1 UE_STATUS_ATTACHING = 2 UE_STATUS_ATTACHED = 3 +X2_HO_REQ_STATE__IDLE = 0 +X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1 +X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2 +X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3 +X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10 + #----------------------------------------------------------- # Import #----------------------------------------------------------- @@ -145,6 +151,10 @@ class SSHConnection(): self.htmlUEFailureMsg = '' self.picocom_closure = False self.idle_sleep_time = 0 + self.x2_ho_options = 'network' + self.x2NbENBs = 0 + self.x2ENBBsIds = [] + self.x2ENBConnectedUEs = [] self.htmlTabRefs = [] self.htmlTabNames = [] self.htmlTabIcons = [] @@ -815,7 +825,10 @@ class SSHConnection(): # self.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) # a dedicated script has to be installed inside the UE # airplane mode on means call /data/local/tmp/off - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) #airplane mode off means call /data/local/tmp/on logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') self.close() @@ -1219,7 +1232,10 @@ class SSHConnection(): def AttachUE_common(self, device_id, statusQueue, lock): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) time.sleep(2) max_count = 45 count = max_count @@ -1246,9 +1262,15 @@ class SSHConnection(): count = count - 1 if count == 15 or count == 30: logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) time.sleep(0.5) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) time.sleep(0.5) logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') time.sleep(1) @@ -1325,7 +1347,10 @@ class SSHConnection(): def DetachUE_common(self, device_id): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + if device_id == '84B7N16418004022': + self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') self.close() except: @@ -2718,7 +2743,36 @@ class SSHConnection(): isRRU = False isSlave = False slaveReceivesFrameResyncCmd = False + X2HO_state = X2_HO_REQ_STATE__IDLE + X2HO_inNbProcedures = 0 + X2HO_outNbProcedures = 0 for line in enb_log_file.readlines(): + if X2HO_state == X2_HO_REQ_STATE__IDLE: + result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ + result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK + if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ: + result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE + if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE: + result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ + if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ: + result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__IDLE + X2HO_inNbProcedures += 1 + if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK: + result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line)) + if result is not None: + X2HO_state = X2_HO_REQ_STATE__IDLE + X2HO_outNbProcedures += 1 + if self.eNBOptions[int(self.eNB_instance)] != '': res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)]) res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line)) @@ -2854,6 +2908,14 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if X2HO_inNbProcedures > 0: + rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' + if X2HO_outNbProcedures > 0: + rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' if self.eNBOptions[int(self.eNB_instance)] != '': res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)]) if res1 is not None: @@ -3355,6 +3417,116 @@ class SSHConnection(): time.sleep(self.idle_sleep_time) self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) + def X2_Status(self, idx, fileName): + cmd = "curl --silent http://" + self.EPCIPAddress + ":9999/stats | jq '.' > " + fileName + message = cmd + '\n' + logging.debug(cmd) + subprocess.run(cmd, shell=True) + if idx == 0: + cmd = "jq '.mac_stats | length' " + fileName + strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2NbENBs = int(strNbEnbs.strip()) + cnt = 0 + while cnt < self.x2NbENBs: + cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName + bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2ENBBsIds[idx].append(bs_id.strip()) + cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName + stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) + nbUEs = int(stNbUEs.strip()) + ueIdx = 0 + self.x2ENBConnectedUEs[idx].append([]) + while ueIdx < nbUEs: + cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName + rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) + ueIdx += 1 + cnt += 1 + + msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" + logging.debug(msg) + message += msg + '\n' + cnt = 0 + while cnt < self.x2NbENBs: + msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)" + logging.debug(msg) + message += msg + '\n' + ueIdx = 0 + while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): + msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) + logging.debug(msg) + message += msg + '\n' + ueIdx += 1 + cnt += 1 + return message + + def Perform_X2_Handover(self): + html_queue = SimpleQueue() + fullMessage = '<pre style="background-color:white">' + msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options + logging.debug(msg) + fullMessage += msg + '\n' + if self.x2_ho_options == 'network': + if self.flexranCtrlInstalled and self.flexranCtrlStarted: + self.x2ENBBsIds = [] + self.x2ENBConnectedUEs = [] + self.x2ENBBsIds.append([]) + self.x2ENBBsIds.append([]) + self.x2ENBConnectedUEs.append([]) + self.x2ENBConnectedUEs.append([]) + fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') + + msg = "Activating the X2 Net control on each eNB" + logging.debug(msg) + fullMessage += msg + '\n' + eNB_cnt = self.x2NbENBs + cnt = 0 + while cnt < eNB_cnt: + cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" + logging.debug(cmd) + fullMessage += cmd + '\n' + subprocess.run(cmd, shell=True) + cnt += 1 + # Waiting for the activation to be active + time.sleep(10) + msg = "Switching UE(s) from eNB to eNB" + logging.debug(msg) + fullMessage += msg + '\n' + cnt = 0 + while cnt < eNB_cnt: + ueIdx = 0 + while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]): + cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) + logging.debug(cmd) + fullMessage += cmd + '\n' + subprocess.run(cmd, shell=True) + ueIdx += 1 + cnt += 1 + time.sleep(10) + # check + logging.debug("Checking the Status after X2 Handover") + fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') + cnt = 0 + x2Status = True + while cnt < eNB_cnt: + if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]): + x2Status = False + cnt += 1 + if x2Status: + msg = "X2 Handover was successful" + logging.debug(msg) + fullMessage += msg + '</pre>' + html_queue.put(fullMessage) + self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + else: + msg = "X2 Handover FAILED" + logging.error(msg) + fullMessage += msg + '</pre>' + html_queue.put(fullMessage) + self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + else: + self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK) + def LogCollectBuild(self): if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): IPAddress = self.eNBIPAddress @@ -3892,7 +4064,7 @@ def Usage(): print('------------------------------------------------------------') def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep': + if action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) return False return True @@ -4011,6 +4183,18 @@ def GetParametersFromXML(action): else: SSH.idle_sleep_time = int(string_field) + if action == 'Perform_X2_Handover': + string_field = test.findtext('x2_ho_options') + if (string_field is None): + SSH.x2_ho_options = 'network' + else: + if string_field != 'network': + logging.error('ERROR: test-case has wrong option ' + string_field) + SSH.x2_ho_options = 'network' + else: + SSH.x2_ho_options = string_field + + #check if given test is in list #it is in list if one of the strings in 'list' is at the beginning of 'test' def test_in_list(test, list): @@ -4421,6 +4605,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re SSH.TerminateFlexranCtrl() elif action == 'IdleSleep': SSH.IdleSleep() + elif action == 'Perform_X2_Handover': + SSH.Perform_X2_Handover() else: sys.exit('Invalid action') if SSH.prematureExit: diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 7a31e2bab2cdb459d17b85f4920663d275bd2c2c..e93f23120c268492aa1323efd7316ad7e6a1ea8e 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1843,7 +1843,7 @@ function run_test_on_vm { fi fi - if [ $S1_NOS1_CFG -eq 0 ] + if [ $S1_NOS1_CFG -eq 2 ] then get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR echo "############################################################" diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml index 29c9a29c2d2f9eeae14cc68dea9c59f5a52a8fd2..a2e74c6de9329c1f0a1215d62592388b9ef18afd 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -24,6 +24,7 @@ <htmlTabRef>test-05-tm1-nos1-tunnel</htmlTabRef> <htmlTabName>Test-05MHz-TM1-noS1-tunnel</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>2</repeatCount> <TestCaseRequestedList> 030201 090109 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml index 2e6b9a0dc6c25f7ef8d2ff45780b3074b6be6aa9..9f7546cab347cbfed1513460c2b0158402a55c0b 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml @@ -24,6 +24,7 @@ <htmlTabRef>test-05-tm1-tunnel</htmlTabRef> <htmlTabName>Test-05MHz-TM1-tunnel</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>2</repeatCount> <TestCaseRequestedList> 030201 090109 030102 000001 090102 000002 040503 000001 040603 040604 040643 040644 000001 090109 030201 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml index a3f88307ec0057a0ca0c2ee94b483266eb741038..9c98ba4a8eb33677e1c7bf6c7093e47136e0ed59 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml @@ -25,6 +25,7 @@ <htmlTabRef>test-05-tm2</htmlTabRef> <htmlTabName>Test-05MHz-TM2</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>2</repeatCount> <TestCaseRequestedList> 030201 040101 diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml index fc14f5f7ffc9679ee12cc800332e55cf4350c00f..c2a48037baf5c2e6b151059d3806d15e4d07e2f9 100644 --- a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml +++ b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml @@ -24,7 +24,7 @@ <htmlTabRef>test-f1-05</htmlTabRef> <htmlTabName>Test-F1-CU-DU-05MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> - <repeatCount>4</repeatCount> + <repeatCount>2</repeatCount> <TestCaseRequestedList> 030201 040101 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml index 17ede3f8305ec26db5e8204c3080717c48811f7c..15d641efeb431917f96d24568558447d68d64080 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml @@ -24,6 +24,7 @@ <htmlTabRef>test-20</htmlTabRef> <htmlTabName>Test-20MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>2</repeatCount> <TestCaseRequestedList> 030201 040101 diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml new file mode 100644 index 0000000000000000000000000000000000000000..0d2a122537d2caf3344e0dc43fc236bdaa7233d2 --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml @@ -0,0 +1,66 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>build-tab</htmlTabRef> + <htmlTabName>Build</htmlTabName> + <htmlTabIcon>wrench</htmlTabIcon> + <TestCaseRequestedList> + 010101 + 010102 + 050101 060101 070101 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="010101"> + <class>Build_eNB</class> + <desc>Build Master eNB (USRP)</desc> + <Build_eNB_args>-w USRP -c --eNB</Build_eNB_args> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="010102"> + <class>Build_eNB</class> + <desc>Build Slave eNB (USRP)</desc> + <Build_eNB_args>-w USRP -c --eNB</Build_eNB_args> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + </testCase> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml new file mode 100644 index 0000000000000000000000000000000000000000..07fb6951f8e99a35cabd2ee4e48232d2bd035f41 --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml @@ -0,0 +1,47 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>epc-closure</htmlTabRef> + <htmlTabName>EPC-Closure</htmlTabName> + <htmlTabIcon>log-out</htmlTabIcon> + <TestCaseRequestedList> + 050201 060201 070201 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml new file mode 100644 index 0000000000000000000000000000000000000000..91280462b70b1b31887ce17edf0bb9a92be9a932 --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml @@ -0,0 +1,46 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-x2-ho-full-end</htmlTabRef> + <htmlTabName>Test-X2-HO-Full-Terminate</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 030202 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate Master eNB</desc> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate Slave eNB</desc> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml new file mode 100644 index 0000000000000000000000000000000000000000..c43be75a8721feda87fbfeba9e29d932d96154ac --- /dev/null +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml @@ -0,0 +1,191 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + + 030101 000002 030102 040301 040501 040601 040641 050401 000002 040502 040602 040642 050402 000002 040503 040603 040643 040401 040201 030201 030202 +--> +<testCaseList> + <htmlTabRef>test-x2-ho-05-tm1</htmlTabRef> + <htmlTabName>Test-X2-HO-FDD-05MHz-TM1</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>2</repeatCount> + <TestCaseRequestedList> + 030201 030202 + 040101 + 050102 + 030101 000002 030102 040301 040501 050401 000002 040502 050402 000002 040503 040401 040201 030201 030202 + 050202 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Waiting for 60 seconds</desc> + <idle_sleep_time_in_sec>60</idle_sleep_time_in_sec> + </testCase> + + <testCase id="000002"> + <class>IdleSleep</class> + <desc>Waiting for 10 seconds</desc> + <idle_sleep_time_in_sec>10</idle_sleep_time_in_sec> + </testCase> + + <testCase id="050102"> + <class>Initialize_FlexranCtrl</class> + <desc>Starting Flexran Controller</desc> + </testCase> + + <testCase id="050202"> + <class>Terminate_FlexranCtrl</class> + <desc>Stopping Flexran Controller</desc> + </testCase> + + <testCase id="030101"> + <class>Initialize_eNB</class> + <desc>Initialize Master eNB (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="030102"> + <class>Initialize_eNB</class> + <desc>Initialize Slave eNB (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate Master eNB</desc> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate Slave eNB</desc> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040501"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040502"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040503"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040601"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/8Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 8M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040602"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/8Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 8M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040603"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/8Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 8M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040641"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/5Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 5M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040642"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/5Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 5M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040643"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/5Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 5M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="050401"> + <class>Perform_X2_Handover</class> + <desc>Doing a Flexran-Controlled X2 Handover</desc> + <x2_ho_options>network</x2_ho_options> + </testCase> + + <testCase id="050402"> + <class>Perform_X2_Handover</class> + <desc>Doing a Flexran-Controlled X2 Handover</desc> + <x2_ho_options>network</x2_ho_options> + </testCase> + +</testCaseList> diff --git a/cmake_targets/build_ue b/cmake_targets/build_ue deleted file mode 100755 index 9d9ca839d10c0164f038a8b6eb4a79f772e01d70..0000000000000000000000000000000000000000 --- a/cmake_targets/build_ue +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -#sudo ./build_oai -c -C -I --install-optional-packages --install-system-files --UE -w USRP -V -#sudo ./build_oai -c -C -I --install-optional-packages --UE -w USRP -V -#sudo ./build_oai -c -C --UE -w USRP -V -sudo ./build_oai -c -C --UE -w USRP -#sudo ./build_oai -c -C --UE -w USRP --build-eclipse diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index b4b9722ca41b55aadee6b282b4d3ef60e7be6127..186077035126d5e85d217c883a2fa00538a9678a 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -43,8 +43,22 @@ #include <string.h> #include <linux/prctl.h> #include "common/config/config_userapi.h" + // main log variables +log_mem_cnt_t log_mem_d[2]; +int log_mem_flag=0; +int log_mem_multi=1; +volatile int log_mem_side=0; +pthread_mutex_t log_mem_lock; +pthread_cond_t log_mem_notify; +pthread_t log_mem_thread; +int log_mem_file_cnt=0; +volatile int log_mem_write_flag=0; +volatile int log_mem_write_side=0; +char __log_mem_filename[1024]={0}; +char * log_mem_filename = &__log_mem_filename[0]; +char logmem_filename[1024] = {0}; mapping log_level_names[] = { {"error", OAILOG_ERR}, @@ -477,10 +491,14 @@ void logRecord_mt(const char *file, { char log_buffer[MAX_LOG_TOTAL]= {0}; va_list args; - va_start(args, format); - log_header(log_buffer,MAX_LOG_TOTAL,comp, level,format); - g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); + va_start(args,format); + if (log_mem_flag == 1) { + log_output_memory(file,func,line,comp,level,format,args); + } else { + log_header(log_buffer,MAX_LOG_TOTAL,comp,level,format); + g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer,args); fflush(g_log->log_component[comp].stream); + } va_end(args); } @@ -493,8 +511,12 @@ void vlogRecord_mt(const char *file, va_list args ) { char log_buffer[MAX_LOG_TOTAL]; + if (log_mem_flag == 1) { + log_output_memory(file,func,line,comp,level, format,args); + } else { log_header(log_buffer,MAX_LOG_TOTAL,comp, level,format); g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); + } } void log_dump(int component, @@ -696,6 +718,265 @@ void logClean (void) } } +extern int oai_exit; +void flush_mem_to_file(void) +{ + int fp; + char f_name[1024]; + struct timespec slp_tm; + slp_tm.tv_sec = 0; + slp_tm.tv_nsec = 10000; + + pthread_setname_np( pthread_self(), "flush_mem_to_file"); + + while (!oai_exit) { + pthread_mutex_lock(&log_mem_lock); + log_mem_write_flag=0; + pthread_cond_wait(&log_mem_notify, &log_mem_lock); + log_mem_write_flag=1; + pthread_mutex_unlock(&log_mem_lock); + // write! + if(log_mem_d[log_mem_write_side].enable_flag==0){ + if(log_mem_file_cnt>5){ + log_mem_file_cnt=5; + printf("log over write!!!\n"); + } + snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt); + fp=open(f_name, O_WRONLY | O_CREAT, 0666); + int ret = write(fp, log_mem_d[log_mem_write_side].buf_p, log_mem_d[log_mem_write_side].buf_index); + if ( ret < 0) { + fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name); + exit(EXIT_FAILURE); + } + close(fp); + log_mem_file_cnt++; + log_mem_d[log_mem_write_side].buf_index=0; + log_mem_d[log_mem_write_side].enable_flag=1; + }else{ + printf("If you'd like to write log, you should set enable flag to 0!!!\n"); + nanosleep(&slp_tm,NULL); + } + } +} + +char logmem_log_level[NUM_LOG_LEVEL]={'E','W','I','D','T'}; + +void log_output_memory(const char *file, const char *func, int line, int comp, int level, const char* format,va_list args) +{ + //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args) + int len = 0; + log_component_t *c; + char *log_start; + char *log_end; + /* The main difference with the version above is the use of this local log_buffer. + * The other difference is the return value of snprintf which was not used + * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is + * big enough so that the buffer is never full. + */ + char log_buffer[MAX_LOG_TOTAL]; + + /* for no gcc warnings */ + (void)log_start; + (void)log_end; + + + c = &g_log->log_component[comp]; + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN); + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if (level == OAILOG_TRACE) { + log_start = log_buffer; + len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + } else { + if ( (g_log->flag & 0x001) || (c->flag & 0x001) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_start[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + log_start = log_buffer + len; + +// if ( (g_log->flag & 0x004) || (c->flag & 0x004) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->log_component[comp].name); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; +// } + + if ( (level >= OAILOG_ERR) && (level <= OAILOG_TRACE) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%c]", + logmem_log_level[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { +# define THREAD_NAME_LEN 128 + char threadname[THREAD_NAME_LEN]; + if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) + { + perror("pthread_getname_np : "); + } else { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } +# undef THREAD_NAME_LEN + } + + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", + func); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", + file, line); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + +/* len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%08lx]", thread_id); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + + struct timeval gettime; + gettimeofday(&gettime,NULL); + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%ld.%06ld]", gettime.tv_sec, gettime.tv_usec); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; +*/ + if ( (g_log->flag & FLAG_NOCOLOR) || (c->flag & FLAG_NOCOLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_end[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + } + + //va_end(args); + + // OAI printf compatibility + if(log_mem_flag==1){ + if(log_mem_d[log_mem_side].enable_flag==1){ + int temp_index; + temp_index=log_mem_d[log_mem_side].buf_index; + if(temp_index+len+1 < LOG_MEM_SIZE){ + log_mem_d[log_mem_side].buf_index+=len; + memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len); + }else{ + log_mem_d[log_mem_side].enable_flag=0; + if(log_mem_d[1-log_mem_side].enable_flag==1){ + temp_index=log_mem_d[1-log_mem_side].buf_index; + if(temp_index+len+1 < LOG_MEM_SIZE){ + log_mem_d[1-log_mem_side].buf_index+=len; + log_mem_side=1-log_mem_side; + memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len); + /* write down !*/ + if (pthread_mutex_lock(&log_mem_lock) != 0) { + return; + } + if(log_mem_write_flag==0){ + log_mem_write_side=1-log_mem_side; + if(pthread_cond_signal(&log_mem_notify) != 0) { + } + } + if(pthread_mutex_unlock(&log_mem_lock) != 0) { + return; + } + }else{ + log_mem_d[1-log_mem_side].enable_flag=0; + } + } + } + } + }else{ + fwrite(log_buffer, len, 1, stdout); + } +} + +int logInit_log_mem (void) +{ + if(log_mem_flag==1){ + if(log_mem_multi==1){ + printf("log-mem multi!!!\n"); + log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE); + log_mem_d[0].buf_index=0; + log_mem_d[0].enable_flag=1; + log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE); + log_mem_d[1].buf_index=0; + log_mem_d[1].enable_flag=1; + log_mem_side=0; + if ((pthread_mutex_init (&log_mem_lock, NULL) != 0) + || (pthread_cond_init (&log_mem_notify, NULL) != 0)) { + log_mem_d[1].enable_flag=0; + return -1; + } + pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void*)NULL); + }else{ + printf("log-mem single!!!\n"); + log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE); + log_mem_d[0].buf_index=0; + log_mem_d[0].enable_flag=1; + log_mem_d[1].enable_flag=0; + log_mem_side=0; + } + }else{ + log_mem_d[0].buf_p=NULL; + log_mem_d[1].buf_p=NULL; + log_mem_d[0].enable_flag=0; + log_mem_d[1].enable_flag=0; + } + + printf("log init done\n"); + + return 0; +} + +void close_log_mem(void){ + int fp; + char f_name[1024]; + + if(log_mem_flag==1){ + log_mem_d[0].enable_flag=0; + log_mem_d[1].enable_flag=0; + usleep(10); // wait for log writing + while(log_mem_write_flag==1){ + usleep(100); + } + if(log_mem_multi==1){ + snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt); + fp=open(f_name, O_WRONLY | O_CREAT, 0666); + int ret = write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index); + if ( ret < 0) { + fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name); + exit(EXIT_FAILURE); + } + close(fp); + free(log_mem_d[0].buf_p); + + snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt); + fp=open(f_name, O_WRONLY | O_CREAT, 0666); + ret = write(fp, log_mem_d[1].buf_p, log_mem_d[1].buf_index); + if ( ret < 0) { + fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name); + exit(EXIT_FAILURE); + } + close(fp); + free(log_mem_d[1].buf_p); + }else{ + fp=open(log_mem_filename, O_WRONLY | O_CREAT, 0666); + int ret = write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index); + if ( ret < 0) { + fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,log_mem_filename); + exit(EXIT_FAILURE); + } + close(fp); + free(log_mem_d[0].buf_p); + } + } + } #ifdef LOG_TEST diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index ba27c87cc183d905e4de6bdf539cc99116d90ebf..cee14a27af92d98726d6a00d46565d35545f83cf 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -119,6 +119,8 @@ extern "C" { #define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */ #define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */ #define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */ +#define FLAG_FUNCT 0x0020 +#define FLAG_FILE_LINE 0x0040 #define FLAG_TIME 0x0100 #define FLAG_INITIALIZED 0x8000 @@ -314,6 +316,19 @@ int is_newline( char *str, int size); int register_log_component(char *name, char *fext, int compidx); +#define LOG_MEM_SIZE 100*1024*1024 +#define LOG_MEM_FILE "./logmem.log" +void flush_mem_to_file(void); +void log_output_memory(const char *file, const char *func, int line, int comp, int level, const char* format,va_list args); +int logInit_log_mem(void); +void close_log_mem(void); + +typedef struct { + char* buf_p; + int buf_index; + int enable_flag; +} log_mem_cnt_t; + /* @}*/ /*!\fn int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format); diff --git a/common/utils/LOG/log_extern.h b/common/utils/LOG/log_extern.h index 3c93d517ca76456f57927b34cfb915482b8b87c2..f6205889dc1477f2bc1bc86115ed89ff9ecaed72 100644 --- a/common/utils/LOG/log_extern.h +++ b/common/utils/LOG/log_extern.h @@ -27,4 +27,6 @@ extern log_t *g_log; extern mapping log_level_names[]; extern mapping log_options[]; extern mapping log_maskmap[]; - +extern int log_mem_flag; +extern char * log_mem_filename; +extern char logmem_filename[1024]; diff --git a/common/utils/itti_analyzer/filters.xml b/common/utils/itti_analyzer/filters.xml index e4a0e627d56f2297ec6b667bb115a2984704210f..7305a2294cd8e035f4ec4c8391e2cfb8af9e95a1 100644 --- a/common/utils/itti_analyzer/filters.xml +++ b/common/utils/itti_analyzer/filters.xml @@ -91,6 +91,8 @@ <TASK_MAC_ENB enabled="1"/> <TASK_RLC_ENB enabled="1"/> <TASK_PDCP_ENB enabled="1"/> + <TASK_DATA_FORWARDING enabled="1"/> + <TASK_END_MARKER enabled="1"/> <TASK_RRC_ENB enabled="1"/> <TASK_RAL_ENB enabled="1"/> <TASK_S1AP enabled="1"/> @@ -114,6 +116,8 @@ <TASK_MAC_ENB enabled="1"/> <TASK_RLC_ENB enabled="1"/> <TASK_PDCP_ENB enabled="1"/> + <TASK_DATA_FORWARDING enabled="1"/> + <TASK_END_MARKER enabled="1"/> <TASK_RRC_ENB enabled="1"/> <TASK_RAL_ENB enabled="1"/> <TASK_S1AP enabled="1"/> diff --git a/common/utils/itti_analyzer/filters_ue_enb.xml b/common/utils/itti_analyzer/filters_ue_enb.xml index 38ed00ceae6d1fd7ae200c0e1f51d180dff1a89e..77859d20b694414a9d03a7c98b1d5bbcf8f74f31 100644 --- a/common/utils/itti_analyzer/filters_ue_enb.xml +++ b/common/utils/itti_analyzer/filters_ue_enb.xml @@ -130,6 +130,8 @@ <TASK_MAC_ENB enabled="1"/> <TASK_RLC_ENB enabled="1"/> <TASK_PDCP_ENB enabled="1"/> + <TASK_DATA_FORWARDING enabled="1"/> + <TASK_END_MARKER enabled="1"/> <TASK_RRC_ENB enabled="1"/> <TASK_RAL_ENB enabled="1"/> <TASK_S1AP enabled="1"/> @@ -153,6 +155,8 @@ <TASK_MAC_ENB enabled="1"/> <TASK_RLC_ENB enabled="1"/> <TASK_PDCP_ENB enabled="1"/> + <TASK_DATA_FORWARDING enabled="1"/> + <TASK_END_MARKER enabled="1"/> <TASK_RRC_ENB enabled="1"/> <TASK_RAL_ENB enabled="1"/> <TASK_S1AP enabled="1"/> diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 99a2f2195f438b385f2729da5e32891c1191f8f0..868a9ba24555f314d7771f020f5ef3018b495fa4 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -283,6 +283,8 @@ typedef struct { TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\ TASK_DEF(TASK_RRC_GNB, TASK_PRIORITY_MED, 200, NULL,NULL)\ TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h index 2f479d8ee6f9e5f59b06720e751df617d871e3bb..160111f15e8bca2abd60af3f63ef4d487ed6a2a6 100644 --- a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h +++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h @@ -81,8 +81,8 @@ {"total_num_pdus", &(macuestatptr->total_num_pdus),TELNET_VARTYPE_INT32,0},\ {"overhead_bytes", &(macuestatptr->overhead_bytes),TELNET_VARTYPE_INT64,0},\ {"crnti", &(macuestatptr->crnti),TELNET_VARTYPE_INT16,0},\ - {"normalized_rx_power", &(macuestatptr->normalized_rx_power),TELNET_VARTYPE_INT32,0},\ - {"target_rx_power", &(macuestatptr->target_rx_power),TELNET_VARTYPE_INT32,0},\ + {"snr", &(macuestatptr->snr),TELNET_VARTYPE_INT32,0},\ + {"target_snr ", &(macuestatptr->target_snr),TELNET_VARTYPE_INT32,0},\ {"ulsch_mcs1", &(macuestatptr->ulsch_mcs1),TELNET_VARTYPE_INT8,0},\ {"ulsch_mcs2", &(macuestatptr->ulsch_mcs2),TELNET_VARTYPE_INT8,0},\ {"rbs_used_rx", &(macuestatptr->rbs_used_rx),TELNET_VARTYPE_INT32,0},\ diff --git a/doc/BASIC_SIM.md b/doc/BASIC_SIM.md new file mode 100644 index 0000000000000000000000000000000000000000..ab4c3489d9a3562cbb20acc59e0e101e84d922f6 --- /dev/null +++ b/doc/BASIC_SIM.md @@ -0,0 +1,191 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">Running OAI Basic Simulator</font></b> + </td> + </tr> +</table> + +This page is valid on the following branches: + +- `master` starting from tag `v1.1.0` +- `develop` starting from tag `2019.w11` + +# 1. Building the basic-simulator. + +After the build simplification, the basic simulator is available directly from the standard build. + +```bash +$ source oaienv +$ cd cmake_targets +$ ./build_oai --eNB --UE +``` + +Both eNB (lte-softmodem) and UE (lte-uesoftmodem) are present on `cmake_targets/lte_build_oai/build` folder. + +More details are available on the [build page](BUILD.md). + +# 2. Running the basic simulator. + +The basic simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE and the oai eNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. + +This is the ideal tool to check signal processing algorithms and protocols implementation and having debug sessions without any HW radio equipment. + +The main limitations are: + +- A single OAI UE will connect to the OAI eNB +- No channel noise + +## 2.1. Starting eNB + +The basic simulator is able to run with a connected EPC or without any (the so-called "noS1" mode). + +Example 1: running in FDD mode with EPC. + +```bash +$ source oaienv +$ cd cmake_targets/lte_build_oai/build +$ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-fdd-basic-sim.conf --basicsim +``` + +Edit previously the `ci-scripts/conf_files/lte-fdd-basic-sim.conf` file to modify: + +- `N_RB_DL` field to change the Bandwidth (25, 50, 100) +- `CI_MME_IP_ADDR` with the EPC IP address +- `CI_ENB_IP_ADDR` with the container (physical server, virtual machine, ...) on which you are executing the eNB soft-modem + +Example 2: running in TDD mode without any EPC. + +```bash +$ source oaienv +$ cd cmake_targets/lte_build_oai/build +$ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-tdd-basic-sim.conf --basicsim --noS1 +``` + +## 2.2. Starting UE + +Before starting the UE, you may need to edit the SIM parameters to adapt to your eNB configuration and HSS database. + +The <conf> file to use for conf2uedate is `openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf` + +You need to set the correct OPC, USIM_API_K, MSIN (this is the end par of the IMSI), HPLMN (the front part of IMSI) to match values from HSS. + +```bash +$ source oaienv +# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +$ cd cmake_targets/lte_build_oai/build +$ ../../nas_sim_tools/build/conf2uedata -c $OPENAIR_HOME/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . +$ sudo -E ./lte-uesoftmodem -C 2625000000 -r 25 --ue-rxgain 140 --basicsim [--noS1] +``` + +The `-r 25` is to use if in the conf file of the eNB you use N_RB_DL=25. Use 50 if you have N_RB_DL=50 and 100 if you have N_RB_DL=100. + +The `-C 2625000000` is the downlink frequency. Use the same value as `downlink_frequency` in the eNB configuration file. + +The `--noS1` is mandatory if you started the eNB in that mode. + +# 3. Testing the data plane + +# 3.1. In S1 mode + +First we need to retrieve the IP address allocated to the OAI UE. + +On the server that runs the UE: + +```bash +$ ifconfig oaitun_ue1 +oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 + inet addr:192.172.0.2 P-t-P:192.172.0.2 Mask:255.255.255.0 +... +``` + +`192.172.0.2` is the IP address that has been allocated by the SPGW in the EPC. + +On the server that runs the EPC: + +```bash +$ ping -c 20 192.172.0.2 + --- 192.172.0.2 ping statistics --- + 20 packets transmitted, 20 received, 0% packet loss, time 19020ms + rtt min/avg/max/mdev = 13.241/18.999/24.208/2.840 ms +``` + +You can ping the EPC from the UE: + +```bash +$ ping -I oaitun_ue1 -c 20 192.172.0.1 + --- 192.172.0.1 ping statistics --- +... + 20 packets transmitted, 20 received, 0% packet loss, time 19019ms + rtt min/avg/max/mdev = 13.015/18.674/23.738/2.917 ms +``` + +For DL iperf testing: + +On the server that runs the UE. + +```bash +$ iperf -B 192.172.0.2 -u -s -i 1 -fm -p 5001 +``` + +On the server that runs the EPC. + +```bash +$ iperf -c 192.172.0.2 -u -t 30 -b 10M -i 1 -fm -B 192.172.0.1 -p 5001 +``` + +For UL iperf testing: + +On the server that runs the EPC. + +```bash +$ iperf -B 192.172.0.1 -u -s -i 1 -fm -p 5001 +``` + +On the server that runs the UE. + +```bash +$ iperf -c 192.172.0.1 -u -t 30 -b 2M -i 1 -fm -B 192.172.0.2 -p 5001 +``` + +# 3.2. In noS1 mode + +The IP addresses are fixed. But we can still retrieve them programmatically. + +For the UE it is quite the same: + +```bash +$ ifconfig oaitun_ue1 +oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 + inet addr:10.0.1.2 P-t-P:10.0.1.2 Mask:255.255.255.0 +... +``` + +For the eNB: + +```bash +$ ifconfig oaitun_enb1 +oaitun_enb1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 + inet addr:10.0.1.1 P-t-P:10.0.1.1 Mask:255.255.255.0 +... +``` + +Pinging like this: + +```bash +$ ping -I oaitun_ue1 -c 20 10.0.1.1 +$ ping -I oaitun_enb1 -c 20 10.0.1.2 +``` + +And the same for iperf: + +```bash +$ iperf -B 10.0.1.2 -u -s -i 1 -fm +$ iperf -c 10.0.1.2 -u -b 1.00M -t 30 -i 1 -fm -B 10.0.1.1 +``` diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 4386382591201525dbaeaf55d1e38948ff24f1d9..e9355e51d2a88e479ebe991c85e45ec95bf8d9b2 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -41,10 +41,12 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid - Max number of antennas: 2 - CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1 - PRACH preamble format 0 -- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH -- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS +- Downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH, MPDCCH +- Uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS - HARQ support (UL and DL) - Highly optimized base band processing (including turbo decoder) +- Multi-RRU support: over the air synchro b/ multi RRU in TDD mode +- Support for CE-modeA for LTE-M. Limited support for repeatition, single-LTE-M connection, legacy-LTE UE attach is disabled. ### Performances ### @@ -144,6 +146,7 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following - UE Context Release - X2 timers (t_reloc_prep, tx2_reloc_overall) - Handover Cancel + - X2-U interface implemented ## eNB Advanced Features ## diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 1c3636a56fb4e6b6b473777d55e55cd9ea2076f5..71354e663ab738770fbe29ed5bf4bc393aa53a50 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -14,6 +14,10 @@ After you have [built the softmodem executables](BUILD.md) you can set your default directory to the build directory `cmake_targets/ran_build/build/` and start testing some use cases. Below, the description of the different oai functionalities should help you choose the oai configuration that suits your need. +# Basic Simulator + +See the [dedicated page](BASIC_SIM.md). + # RF Simulator The rf simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE and the oai eNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation. diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index c835f38e115a449b6ede31168954873b52219288..f07fb1ad23f13aadeeabfe0b2178655bb4c2722e 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -83,7 +83,7 @@ nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_n uint8_t tx_pdus[32][8][4096]; - +nfapi_ue_release_request_body_t release_rntis; uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; nfapi_pnf_param_response_t g_pnf_param_resp; @@ -197,19 +197,19 @@ static pthread_t pnf_start_pthread; int nfapitooai_level(int nfapi_level) { switch(nfapi_level) { case NFAPI_TRACE_ERROR: - return LOG_ERR; + return OAILOG_ERR; case NFAPI_TRACE_WARN: - return LOG_WARNING; + return OAILOG_WARNING; case NFAPI_TRACE_NOTE: - return LOG_INFO; + return OAILOG_INFO; case NFAPI_TRACE_INFO: - return LOG_DEBUG; + return OAILOG_DEBUG; } - return LOG_ERR; + return OAILOG_ERR; } void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) { @@ -540,7 +540,6 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap } if(req->nfapi_config.earfcn.tl.tag == NFAPI_NFAPI_EARFCN_TAG) { - fp->eutra_band = 0; fp->dl_CarrierFreq = from_earfcn(fp->eutra_band, req->nfapi_config.earfcn.value); fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(fp->eutra_band) * 1e5); num_tlv++; @@ -896,6 +895,15 @@ int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t *config, nfapi_lbt_dl_config return 0; } +int pnf_phy_ue_release_req(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req) { + if (req->ue_release_request_body.number_of_TLVs==0) + return -1; + + release_rntis.number_of_TLVs = req->ue_release_request_body.number_of_TLVs; + memcpy(&release_rntis.ue_release_request_TLVs_list, req->ue_release_request_body.ue_release_request_TLVs_list, sizeof(nfapi_ue_release_request_TLVs_t)*req->ue_release_request_body.number_of_TLVs); + return 0; +} + int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, nfapi_p7_message_header_t *msg) { if(msg->message_id == P7_VENDOR_EXT_REQ) { //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; @@ -1024,7 +1032,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; p7_config->tx_req = &pnf_phy_tx_req; p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - + p7_config->ue_release_req = &pnf_phy_ue_release_req; if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { p7_config->dl_config_req = &memcpy_dl_config_req; p7_config->ul_config_req = &memcpy_ul_config_req; @@ -1367,7 +1375,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { - nfapi_setmode(NFAPI_PNF); // PNF! + nfapi_setmode(NFAPI_MODE_PNF); // PNF! } nfapi_pnf_config_t *config = nfapi_pnf_config_create(); diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 64d454e6e7b39758604018e05a7b4392eb60eeb6..a0574221f5b8e1dafddd66bb3bd20064e3c83d72 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -42,6 +42,7 @@ #include "common/ran_context.h" extern RAN_CONTEXT_t RC; +extern UL_RCC_IND_t UL_RCC_INFO; typedef struct { uint8_t enabled; @@ -424,6 +425,40 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; printf("[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); pthread_mutex_lock(&eNB->UL_INFO_mutex); + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.rach_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_rach_indication : num of rach reach max \n"); + return 0; + } + UL_RCC_INFO.rach_ind[index] = *ind; + + if (ind->rach_indication_body.number_of_preambles > 0) + UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list = malloc(sizeof(nfapi_preamble_pdu_t)*ind->rach_indication_body.number_of_preambles ); + + for (int i=0; i<ind->rach_indication_body.number_of_preambles; i++) { + if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) { + + printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", + i, + ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, + ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, + ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance + ); + } + if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) { + printf("RACH PREAMBLE REL13 present\n"); + } + + UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list[i] = ind->rach_indication_body.preamble_list[i]; + } + }else{ eNB->UL_INFO.rach_ind = *ind; eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = eNB->preamble_list; @@ -443,7 +478,7 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio eNB->preamble_list[i] = ind->rach_indication_body.preamble_list[i]; } - + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rach_ind(p7_vnf->mac, ind); @@ -454,13 +489,33 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->harq_indication_body.number_of_harqs); pthread_mutex_lock(&eNB->UL_INFO_mutex); + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.harq_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_harq_indication : num of harq reach max \n"); + return 0; + } + UL_RCC_INFO.harq_ind[index] = *ind; + + if (ind->harq_indication_body.number_of_harqs > 0) + UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = malloc(sizeof(nfapi_harq_indication_pdu_t)*ind->harq_indication_body.number_of_harqs ); + for (int i=0; i<ind->harq_indication_body.number_of_harqs; i++) { + memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(nfapi_harq_indication_pdu_t)); + } + }else{ eNB->UL_INFO.harq_ind = *ind; eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; for (int i=0; i<ind->harq_indication_body.number_of_harqs; i++) { memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i])); } - + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_harq_ind(p7_vnf->mac, ind); @@ -470,6 +525,37 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; pthread_mutex_lock(&eNB->UL_INFO_mutex); + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.crc_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + } + if(UL_RCC_INFO.rx_ind[i].sfn_sf == ind->sfn_sf){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_crc_indication : num of crc reach max \n"); + return 0; + } + UL_RCC_INFO.crc_ind[index] = *ind; + + if (ind->crc_indication_body.number_of_crcs > 0) + UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list = malloc(sizeof(nfapi_crc_indication_pdu_t)*ind->crc_indication_body.number_of_crcs ); + + for (int i=0; i<ind->crc_indication_body.number_of_crcs; i++) { + memcpy(&UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0])); + + LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, UL_RCC_INFO.crc_ind[index].crc_indication_body.number_of_crcs, + i, + ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti, + UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); + } + }else{ eNB->UL_INFO.crc_ind = *ind; nfapi_crc_indication_t *dest_ind = &eNB->UL_INFO.crc_ind; nfapi_crc_indication_pdu_t *dest_pdu_list = eNB->crc_pdu_list; @@ -489,7 +575,7 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_ ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti, eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); } - + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_crc_ind(p7_vnf->mac, ind); @@ -504,6 +590,52 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t } pthread_mutex_lock(&eNB->UL_INFO_mutex); + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.rx_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + } + if(UL_RCC_INFO.crc_ind[i].sfn_sf == ind->sfn_sf){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_rx_indication : num of rx reach max \n"); + return 0; + } + UL_RCC_INFO.rx_ind[index] = *ind; + + if (ind->rx_indication_body.number_of_pdus > 0) + UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list = malloc(sizeof(nfapi_rx_indication_pdu_t)*ind->rx_indication_body.number_of_pdus ); + + for (int i=0; i<ind->rx_indication_body.number_of_pdus; i++) { + nfapi_rx_indication_pdu_t *dest_pdu = &UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list[i]; + nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i]; + + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + // DJP - TODO FIXME - intentional memory leak + if(dest_pdu->rx_indication_rel8.length > 0){ + dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length); + memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length); + }else{ + dest_pdu->data = NULL; + } + + LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, + dest_pdu->rx_ue_information.handle, + dest_pdu->rx_ue_information.rnti, + dest_pdu->rx_indication_rel8.length, + dest_pdu->rx_indication_rel8.offset, + dest_pdu->rx_indication_rel8.ul_cqi, + dest_pdu->rx_indication_rel8.timing_advance, + dest_pdu->data + ); + } + }else{ nfapi_rx_indication_t *dest_ind = &eNB->UL_INFO.rx_ind; nfapi_rx_indication_pdu_t *dest_pdu_list = eNB->rx_pdu_list; *dest_ind = *ind; @@ -528,7 +660,7 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t dest_pdu->data ); } - + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rx_ind(p7_vnf->mac, ind); @@ -544,6 +676,32 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs); pthread_mutex_lock(&eNB->UL_INFO_mutex); + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.sr_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_sr_indication : num of sr reach max \n"); + return 0; + } + UL_RCC_INFO.sr_ind[index] = *ind; + LOG_D(MAC,"%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, index, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); + if (ind->sr_indication_body.number_of_srs > 0) + UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t)*ind->sr_indication_body.number_of_srs ); + + for (int i=0; i<ind->sr_indication_body.number_of_srs; i++) { + nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list[i]; + nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; + + LOG_D(MAC, "SR_IND[PDU:%d %d][rnti:%x cqi:%d channel:%d]\n", index, i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); + + memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); + } + }else{ nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind; nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list; *dest_ind = *ind; @@ -556,7 +714,7 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); } - + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_sr_ind(p7_vnf->mac, ind); @@ -569,7 +727,48 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_ struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.cqi_ind = ind->cqi_indication_body; + if(NFAPI_MODE == NFAPI_MODE_VNF){ + int8_t index = -1; + for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ + if((UL_RCC_INFO.cqi_ind[i].header.message_id == 0) && (index == -1)){ + index = i; + break; + } + } + if(index == -1){ + LOG_E(MAC,"phy_cqi_indication : num of cqi reach max \n"); + return 0; + } + UL_RCC_INFO.cqi_ind[index] = *ind; + if (ind->cqi_indication_body.number_of_cqis > 0){ + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = malloc(sizeof(nfapi_cqi_indication_pdu_t)*ind->cqi_indication_body.number_of_cqis ); + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = malloc(sizeof(nfapi_cqi_indication_raw_pdu_t)*ind->cqi_indication_body.number_of_cqis ); + } + for (int i=0; i<ind->cqi_indication_body.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); + memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list[i], + src_pdu, sizeof(nfapi_cqi_indication_pdu_t)); + + memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list[i], + &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t)); + } + }else{ + nfapi_cqi_indication_t *dest_ind = &eNB->UL_INFO.cqi_ind; + *dest_ind = *ind; + dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list; + dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list; + for(int i=0; i<ind->cqi_indication_body.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); + memcpy(&dest_ind->cqi_indication_body.cqi_pdu_list[i], + src_pdu, sizeof(nfapi_cqi_indication_pdu_t)); + memcpy(&dest_ind->cqi_indication_body.cqi_raw_pdu_list[i], + &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t)); + } + } pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 1; } @@ -947,6 +1146,7 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext; config->codec_config.allocate = &vnf_allocate; config->codec_config.deallocate = &vnf_deallocate; + memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t)); NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_start_thread, config); NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); @@ -1040,3 +1240,21 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return retval; } + +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){ + if(release_req->ue_release_request_body.number_of_TLVs <= 0) + return 0; + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + release_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + release_req->header.message_id = NFAPI_UE_RELEASE_REQUEST; + release_req->ue_release_request_body.tl.tag = NFAPI_UE_RELEASE_BODY_TAG; + + int retval = nfapi_vnf_p7_ue_release_req(p7_config, release_req); + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + release_req->ue_release_request_body.number_of_TLVs = 0; + } + return retval; +} diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 901b4956c4ccdf78ed55b464197c68b508bc6a11..2c31af4bc1a3cae039498cd1ad4d17f177b2c54c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -150,6 +150,8 @@ typedef enum { NFAPI_LBT_DL_INDICATION, NFAPI_NB_HARQ_INDICATION, NFAPI_NRACH_INDICATION, + NFAPI_UE_RELEASE_REQUEST, + NFAPI_UE_RELEASE_RESPONSE, NFAPI_PNF_PARAM_REQUEST = 0x0100, NFAPI_PNF_PARAM_RESPONSE, @@ -2424,6 +2426,19 @@ typedef struct { } nfapi_tx_request_body_t; #define NFAPI_TX_REQUEST_BODY_TAG 0x2022 +#define NFAPI_RELEASE_MAX_RNTI 256 +typedef struct { + uint32_t handle; + uint16_t rnti; +} nfapi_ue_release_request_TLVs_t; + +typedef struct { + nfapi_tl_t tl; + uint16_t number_of_TLVs; + nfapi_ue_release_request_TLVs_t ue_release_request_TLVs_list[NFAPI_RELEASE_MAX_RNTI]; +} nfapi_ue_release_request_body_t; +#define NFAPI_UE_RELEASE_BODY_TAG 0x2068 + // P7 Message Structures typedef struct { nfapi_p7_message_header_t header; @@ -3450,6 +3465,19 @@ typedef struct { nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_error_indication_t; +typedef struct { + nfapi_p7_message_header_t header; + uint16_t sfn_sf; + nfapi_ue_release_request_body_t ue_release_request_body; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_ue_release_request_t; + +typedef struct { + nfapi_p7_message_header_t header; + uint32_t error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_ue_release_response_t; + // // P4 Messages // diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c old mode 100644 new mode 100755 index 2daf1450c852c9bbb7b5ff1003e308903b494ba4..be9205d035ea075803e8e548925f1c8f3a9f1e8c --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -81,13 +81,19 @@ void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config) if(size == 0) return 0; + void* buffer_p = NULL; if(config && config->allocate) { - return (config->allocate)(size); + buffer_p = (config->allocate)(size); + if(buffer_p != NULL){ + memset(buffer_p,0,size); + } + return buffer_p; } else { - return calloc(1, size); + buffer_p = calloc(1, size); + return buffer_p; } } @@ -1577,7 +1583,43 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e return x && y && z; } - + +static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv; + if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){ + return 0; + } + + uint8_t j; + uint16_t num = value->number_of_TLVs; + for(j = 0; j < num; ++j){ + if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){ + return 0; + } + } + return 1; +} + +static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; + int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + return x && y && z; +} + +static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + + nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; + + int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + return x && z; +} + static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; @@ -2665,7 +2707,15 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); break; - + + case NFAPI_UE_RELEASE_REQUEST: + result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_HARQ_INDICATION: result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); break; @@ -4479,7 +4529,55 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * return 1; } - + +static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + uint8_t proceed = 1; + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; + + if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0) + return 0; + + while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_UE_RELEASE_BODY_TAG: + { + pNfapiMsg->ue_release_request_body.tl = generic_tl; + if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0) + return 0; + + if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI); + return 0; + } else { + uint8_t j; + uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs; + for(j = 0; j < num; ++j){ + if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){ + return 0; + } + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag ); + } + break; + }; + } + + return 1; +} + static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv; @@ -5727,7 +5825,18 @@ static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPa pull8(ppReadPackedMsg, &value->nrach_ce_level, end)); } - +static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; + if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){ + return 0; + } + else{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code); + } + return 1; +} + static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) { nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; @@ -5940,7 +6049,17 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) retLen = sizeof(nfapi_timing_info_t); break; - + + case NFAPI_UE_RELEASE_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t)) + retLen = sizeof(nfapi_ue_release_request_t); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t)) + retLen = sizeof(nfapi_ue_release_response_t); + break; + default: NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); break; @@ -6060,7 +6179,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - + + case NFAPI_UE_RELEASE_REQUEST: + if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) + result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_HARQ_INDICATION: if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); @@ -6158,7 +6284,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - + + case NFAPI_UE_RELEASE_RESPONSE: + if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen)) + result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + default: if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index b25caf28760ff6e06ef4607b2d49f7e1a46e1de5..8d17416a418a98a822494726b1f1261aa1f66e54 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -546,7 +546,7 @@ typedef struct nfapi_hi_dci0_request_t* hi_dci0_req; nfapi_tx_request_t* tx_req; nfapi_lbt_dl_config_request_t* lbt_dl_config_req; - + nfapi_ue_release_request_t* ue_release_req; } nfapi_pnf_p7_subframe_buffer_t; typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t; @@ -652,6 +652,17 @@ typedef struct nfapi_pnf_p7_config * \return not currently used */ int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req); + + /*! A callback for the UE_RELEASE_REQ.request + * \param config A poiner to the PNF P7 config + * \param req A pointer to the release rnti request message structure + * \return not currently used + * + * The release request contains pointers to the release rnti to be sent. In the case that the FAPI interface + * will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0 + * and then use the p7 codec config free function to release the rnti when appropriate. + */ + int (*ue_release_req)(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req); /*! A callback for vendor extension messages * \param config A poiner to the PNF P7 config @@ -796,6 +807,7 @@ int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication */ int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg); +int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp); #if defined(__cplusplus) } #endif diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 81abed81a95b27935df7b19bb21ddb8b5c25f97d..944673037500c6f8478b3352f0998f28e840cc07 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -36,7 +36,7 @@ extern uint16_t sf_ahead; void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset) { - *frameP = *frameP + ((*subframeP + offset) / 10); + *frameP = (*frameP + ((*subframeP + offset) / 10))%1024; *subframeP = ((*subframeP + offset) % 10); } @@ -241,6 +241,16 @@ void deallocate_nfapi_lbt_dl_config_request(nfapi_lbt_dl_config_request_t* req, pnf_p7_free(pnf_p7, req); } +nfapi_ue_release_request_t* allocate_nfapi_ue_release_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_ue_release_request_t)); +} + +void deallocate_nfapi_ue_release_request(nfapi_ue_release_request_t* req, pnf_p7_t* pnf_p7) +{ + pnf_p7_free(pnf_p7, req); +} + pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len) { pnf_p7_rx_message_t* msg = 0; @@ -720,6 +730,21 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) } } + if(tx_subframe_buffer->ue_release_req != 0) + { + if(pnf_p7->_public.ue_release_req) + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), tx_subframe_buffer->ue_release_req); + } + else + { + //send dummy + if(pnf_p7->_public.ue_release_req && pnf_p7->_public.dummy_subframe.ue_release_req) + { + pnf_p7->_public.dummy_subframe.ue_release_req->sfn_sf = sfn_sf_tx; + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ue_release_req); + } + } + if(tx_subframe_buffer->dl_config_req != 0) { deallocate_nfapi_dl_config_request(tx_subframe_buffer->dl_config_req, pnf_p7); @@ -735,6 +760,10 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) deallocate_nfapi_hi_dci0_request(tx_subframe_buffer->hi_dci0_req, pnf_p7); tx_subframe_buffer->hi_dci0_req = 0; } + if(tx_subframe_buffer->ue_release_req != 0){ + deallocate_nfapi_ue_release_request(tx_subframe_buffer->ue_release_req, pnf_p7); + tx_subframe_buffer->ue_release_req = 0; + } } else { @@ -799,7 +828,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) } } // sfn_sf match - if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0) + if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0 && subframe_buffer->ue_release_req == 0) { memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t)); pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1; @@ -1310,6 +1339,80 @@ void pnf_handle_p7_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pn } +void pnf_handle_ue_release_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + nfapi_ue_release_request_t* req = allocate_nfapi_ue_release_request(pnf_p7); + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to alloced nfapi_ue_release_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ue_release_request_t), &pnf_p7->_public.codec_config); + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to lock mutex\n"); + return; + } + + if(is_p7_request_in_window(req->sfn_sf, "ue_release_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UE_RELEASE_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() UE_RELEASE_REQ.req sfn_sf:%d rntis:%d - UE_RELEASE_REQ is within window\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->ue_release_request_body.number_of_TLVs); + + if(pnf_p7->subframe_buffer[buffer_index].ue_release_req != 0) + { + deallocate_nfapi_ue_release_request(pnf_p7->subframe_buffer[buffer_index].ue_release_req, pnf_p7); + } + + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].ue_release_req = req; + + pnf_p7->stats.tx_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() UE_RELEASE_REQUEST Request is outside of window REQ:SFN_SF:%d CURR:SFN_SF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), NFAPI_SFNSF2DEC(pnf_p7->sfn_sf)); + + deallocate_nfapi_ue_release_request(req, pnf_p7); + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.tx_late++; + } + nfapi_ue_release_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_UE_RELEASE_RESPONSE; + resp.header.phy_id = req->header.phy_id; + resp.error_code = NFAPI_MSG_OK; + nfapi_pnf_ue_release_resp(&(pnf_p7->_public), &resp); + NFAPI_TRACE(NFAPI_TRACE_INFO, "do ue_release_response\n"); + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to unlock mutex\n"); + return; + } + } + else + { + deallocate_nfapi_ue_release_request(req, pnf_p7); + } +} uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr) { @@ -1445,7 +1548,11 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, case NFAPI_LBT_DL_CONFIG_REQUEST: pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); break; - + + case NFAPI_UE_RELEASE_REQUEST: + pnf_handle_ue_release_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + default: { if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && @@ -1536,7 +1643,7 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length); return; } - + memset(pnf_p7->reassemby_buffer, 0, length); pnf_p7->reassemby_buffer_size = length; } diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index 74de5e5d785e5d251dfcc65133fd2154219b7641..24e73ae9b3c6fb54efd362b6ed855a941b6cb932 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -223,3 +223,15 @@ int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_messag return pnf_p7_pack_and_send_p7_message(_this, msg, 0); } +int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t)); +} diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 525490629ac23f1d24baaa5842f3d5d29d653762..5d463afdaea976eef6800be0f5912e36ac462a56 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -990,6 +990,15 @@ int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_c */ int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* msg); +/*! Send the RELEASE_RNTI.request + * \param config A pointer to the vnf p7 configuration + * \param req A data structure for the decoded RELEASE_RNTI.request. + * \return A status value. 0 equal success, -1 indicates failure + * + * The caller is responsiable for memory management of any pointers set in the req, which + * may be released after this function call has returned or at a later pointer + */ +int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req); #if defined(__cplusplus) } #endif diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 4b7acabec3637af74e3d95f8d9d805ea3337b118..985a6f830a6835db67f38ff587c6e0d86f5a99b4 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -822,6 +822,28 @@ void vnf_handle_nrach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p } } +void vnf_handle_ue_release_resp(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + + // ensure it's valid + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_ue_release_response_t resp; + + if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &resp, sizeof(resp), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__); + } + + + vnf_p7_codec_free(vnf_p7, resp.vendor_extension); + } +} + void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7, uint16_t message_id) { if (pRecvMsg == NULL || vnf_p7 == NULL) @@ -1334,6 +1356,10 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7); break; + case NFAPI_UE_RELEASE_RESPONSE: + vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7); + break; + default: { if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && @@ -1430,7 +1456,7 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length); return; } - + memset(phy->reassembly_buffer, 0, length); phy->reassembly_buffer_size = length; } diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 2798e04ae6d50402eee4cbf51fea2b32cae0b964..8b601224835d732f45b9b9febe2acf7585a48325 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -534,6 +534,14 @@ int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_messag return vnf_p7_pack_and_send_p7_msg(vnf_p7, header); } +int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header) { diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 8a165ed78138b48cde44b8f994225b78e8792b8c..368910ee05b563b42e75040a3b5ac0ed4c84c84c 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -34,6 +34,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "assertions.h" #include <math.h> +#include "nfapi/oai_integration/vendor_ext.h" extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn); extern int32_t get_uldl_offset(int eutra_bandP); @@ -409,6 +410,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, + if (NFAPI_MODE!=NFAPI_MODE_VNF){ common_vars->rxdata = (int32_t **)NULL; common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*)); @@ -512,6 +514,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) eNB->UE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id]; + } eNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index c5654aa7428203ca04b4c709eaedae3612adf84d..cd76f209197f3854948cb14854fb7985a56fef9b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -38,7 +38,7 @@ #define CCEBITS 72 #define CCEPERSYMBOL 33 // This is for 1200 RE #define CCEPERSYMBOL0 22 // This is for 1200 RE -#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS) +#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS + 64) //#define Mquad (Msymb/4) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 21d7602a97fe463341c84821b198d583809033c5..80e7b6f8cdb9886c37ea41cb6eba5ed082c9eaff 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -379,9 +379,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, unsigned int G; unsigned int crc=1; unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe]; - - if(harq_pid >= dlsch->Mdlharq) { - LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d\n", harq_pid); + if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) { + LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); return(-1); } @@ -564,7 +563,12 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB, time_stats_t *i_stats) { int encoding_return = 0; unsigned int L,C,B; - B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B; + uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe]; + if(harq_pid >= dlsch->Mdlharq) { + LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid); + return(-1); + } + B = dlsch->harq_processes[harq_pid]->B; LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]); @@ -671,9 +675,8 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, unsigned int crc=1; LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe]; - - if(harq_pid >= dlsch->Mdlharq) { - LOG_E(PHY,"dlsch_encoding illegal harq_pid %d\n", harq_pid); + if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) { + LOG_E(PHY,"dlsch_encoding illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); return(-1); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index e8b56f3bdfe99292b3a5db85d91b5d99f1fba697..8a3649cf8727d5ad00ec73ae3a754593406afef2 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2257,8 +2257,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, if ((dlsch0 != NULL) && (dlsch1 != NULL)){ harq_pid = dlsch0->harq_ids[frame%2][subframe_offset]; - if(harq_pid >= dlsch0->Mdlharq) { - LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); return(-1); } dlsch0_harq = dlsch0->harq_processes[harq_pid]; @@ -2278,8 +2278,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){ harq_pid = dlsch0->harq_ids[frame%2][subframe_offset]; - if(harq_pid >= dlsch0->Mdlharq) { - LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); return(-1); } dlsch0_harq = dlsch0->harq_processes[harq_pid]; @@ -2299,8 +2299,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){ harq_pid = dlsch1->harq_ids[frame%2][subframe_offset]; - if(harq_pid >= dlsch1->Mdlharq) { - LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); + if((harq_pid < 0) || (harq_pid >= dlsch1->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); return(-1); } dlsch1_harq = dlsch1->harq_processes[harq_pid]; diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 676d753ab5d61bcf7c42f19200a5e9a57f728d05..72be96c95bfb4509bc821d8ad75346077798af02 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1063,7 +1063,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #endif } - for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) { + for (l2=0,l=(nsymb>>1); l < nsymb; l++,l2++) { stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb; stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb; off+=2; @@ -1092,7 +1092,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, // stat_max *= nsymb; // normalize to energy per symbol // stat_max /= (frame_parms->N_RB_UL*12); // - stat_max /= (nsymb*12); + stat_max /= 12; #ifdef DEBUG_PUCCH_RX printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max); @@ -1181,7 +1181,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, stat_ref_re=0; stat_ref_im=0; - for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) { + for (l2=0,l=(nsymb>>1); l< nsymb; l++,l2++) { if ((l2<2) || ((l2>(nsymb>>1) - 3)) ) { // data symbols stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index cedd7729c2bd5047475ac2b084dcc5907d379d32..735b8fd7ff2d2ce13eaba59387f136f2219d2fba 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -328,6 +328,8 @@ typedef struct { uint8_t subframe; /// corresponding UE RNTI uint16_t rnti; + /// UE ID from Layer2 + uint16_t ue_id; /// Type (SR, HARQ, CQI, HARQ_SR, HARQ_CQI, SR_CQI, HARQ_SR_CQI) UCI_type_t type; /// SRS active flag diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 88c652133b783bb627f708985c08c0d4004ca707..c301c8510f03f4ab7d22b50496cdf507435336de 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -41,7 +41,7 @@ int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_ uint16_t i; int16_t first_free_index=-1; AssertFatal(eNB!=NULL,"eNB is null\n"); - for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) { if ((eNB->uci_vars[i].active >0) && (eNB->uci_vars[i].rnti==rnti) && (eNB->uci_vars[i].frame==frame) && diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 7280ab69f1104dff3f189a719ff2d7f8f848b94d..314d6cc31bd6755ccc1fd5a666c7ef3c05f732f7 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -521,7 +521,7 @@ typedef struct PHY_VARS_eNB_s { LTE_eNB_PRACH prach_vars_br; #endif LTE_eNB_COMMON common_vars; - LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; + LTE_eNB_UCI uci_vars[NUMBER_OF_UCI_VARS_MAX]; LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PBCH pbch; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index 1ae23e28b1c9a030e57de4672cd46d36992aa22a..492abe7e8d3a600638b53e0d4882aaa1ea533640 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -42,9 +42,9 @@ int16_t *primary_synch2_time; #include "PHY/MODULATION/modulation_vars.h" - PHY_VARS_UE ***PHY_vars_UE_g; RAN_CONTEXT_t RC; +UL_RCC_IND_t UL_RCC_INFO; unsigned short rev[2048],rev_times4[8192],rev_half[1024]; unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index b311149532432a4e0f1d6e09923929eedc897a05..5f8b4ec3db810495192e35e18b601322fa92db17 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -42,7 +42,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); - +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req); void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, @@ -186,21 +186,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro #endif harq_pid = dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx]; - AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7 frame:%d subframe:%d subframe(TX):%d rnti:%x UE_id:%d dlsch0[harq_ids:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d]\n", - harq_pid, - frame,subframe, - proc->subframe_tx,rel8->rnti,UE_id, - dlsch0->harq_ids[proc->frame_tx%2][0], - dlsch0->harq_ids[proc->frame_tx%2][1], - dlsch0->harq_ids[proc->frame_tx%2][2], - dlsch0->harq_ids[proc->frame_tx%2][3], - dlsch0->harq_ids[proc->frame_tx%2][4], - dlsch0->harq_ids[proc->frame_tx%2][5], - dlsch0->harq_ids[proc->frame_tx%2][6], - dlsch0->harq_ids[proc->frame_tx%2][7], - dlsch0->harq_ids[proc->frame_tx%2][8], - dlsch0->harq_ids[proc->frame_tx%2][9] - ); + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); + return; + } + dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n"); @@ -588,6 +578,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB, uci->frame = frame; uci->subframe = subframe; uci->rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; + uci->ue_id = find_dlsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE); uci->type = SR; uci->pucch_fmt = pucch_format1; uci->num_antenna_ports = 1; @@ -615,6 +606,7 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_ uci->frame = frame; uci->subframe = subframe; uci->rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti; + uci->ue_id = find_dlsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE); uci->type = HARQ_SR; uci->num_antenna_ports = 1; uci->num_pucch_resources = 1; @@ -638,6 +630,7 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu uci->frame = frame; uci->subframe = subframe; uci->rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; + uci->ue_id = find_dlsch(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE); uci->type = HARQ; uci->srs_active = srs_active; uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports; @@ -809,7 +802,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); // clear DCI allocation maps for new subframe - + if (NFAPI_MODE!=NFAPI_MODE_VNF) for (i=0; i<NUMBER_OF_UE_MAX; i++) { if (eNB->ulsch[i]) { ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; @@ -825,7 +818,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { //LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); switch (dl_config_pdu->pdu_type) { case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); + if (NFAPI_MODE!=NFAPI_MODE_VNF) + handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++; //LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci); do_oai=1; @@ -840,7 +834,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { do_oai=1; //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); - handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, + if (NFAPI_MODE!=NFAPI_MODE_VNF) + handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); break; @@ -872,7 +867,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { dlsch_pdu_rel8->transport_blocks); if (1) { //sdu != NULL) - handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); + if (NFAPI_MODE!=NFAPI_MODE_VNF) + handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); } else { dont_send=1; LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, @@ -913,7 +909,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: - handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); + if (NFAPI_MODE!=NFAPI_MODE_VNF) + handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); eNB->mpdcch_vars[subframe&1].num_dci++; break; #endif @@ -921,16 +918,24 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { } if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) { - oai_nfapi_tx_req(Sched_INFO->TX_req); + if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0){ + Sched_INFO->TX_req->sfn_sf = frame << 4 | subframe; + oai_nfapi_tx_req(Sched_INFO->TX_req); + } + Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe; oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu + Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe; + oai_nfapi_ue_release_req(Sched_INFO->UE_release_req); } if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && number_hi_dci0_pdu!=0) { + HI_DCI0_req->sfn_sf = frame << 4 | subframe; oai_nfapi_hi_dci0_req(HI_DCI0_req); eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci=0; eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0; } +if (NFAPI_MODE!=NFAPI_MODE_VNF) for (i=0; i<number_hi_dci0_pdu; i++) { hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i]; LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type); @@ -955,6 +960,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { if (NFAPI_MODE!=NFAPI_MONOLITHIC) { if (number_ul_pdu>0) { //LOG_D(PHY, "UL_CONFIG to send to PNF\n"); + UL_req->sfn_sf = frame << 4 | subframe; oai_nfapi_ul_config_req(UL_req); UL_req->ul_config_request_body.number_of_pdus=0; number_ul_pdu=0; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 47b3f77d3e279bfdf6c1d37f5b4282cb8be01097..2d493f807289238eec1bba6cc180cf92270a4087 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -48,8 +48,7 @@ #include "intertask_interface.h" - - +nfapi_ue_release_request_body_t release_rntis; int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) { uint32_t Nre,sumKr,MPR_x100,Kr,r; @@ -460,6 +459,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,num_pdcch_symbols); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME (VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO, (frame * 10) + subframe); + if (num_pdcch_symbols == 0){ + LOG_E(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8") num_pdcch_symbols:%d\n",eNB->Mod_id,frame, subframe, num_dci, num_pdcch_symbols); + return; + } + if (num_dci > 0) LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8") num_pdcch_symbols:%d\n",eNB->Mod_id,frame, subframe, num_dci, num_pdcch_symbols); @@ -507,9 +511,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ) { // get harq_pid harq_pid = dlsch0->harq_ids[frame%2][subframe]; - AssertFatal(harq_pid>=0,"harq_pid is negative\n"); + //AssertFatal(harq_pid>=0,"harq_pid is negative\n"); - if (harq_pid>=8) { + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (dlsch0->ue_type==0) @@ -598,7 +602,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u // pdu->rx_ue_information.handle = handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; - int SNRtimes10 = dB_fixed_times10(stat) - 300;//(10*eNB->measurements.n0_power_dB[0]); + int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; @@ -631,7 +635,7 @@ uci_procedures(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci = NULL; LTE_DL_FRAME_PARMS *fp = &(eNB->frame_parms); - for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { + for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++) { uci = &(eNB->uci_vars[i]); if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { @@ -679,7 +683,7 @@ uci_procedures(PHY_VARS_eNB *eNB, int pucch1_thres = (uci->ue_type == 0) ? eNB->pucch1_DTX_threshold : eNB->pucch1_DTX_threshold_emtc[0]; metric_SR = rx_pucch(eNB, uci->pucch_fmt, - i, + uci->ue_id, uci->n_pucch_1_0_sr[0], 0, // n2_pucch uci->srs_active, // shortened format @@ -721,7 +725,7 @@ uci_procedures(PHY_VARS_eNB *eNB, SR_payload); metric[0] = rx_pucch(eNB, uci->pucch_fmt, - i, + uci->ue_id, uci->n_pucch_1[0][0], 0, //n2_pucch uci->srs_active, // shortened format @@ -745,7 +749,7 @@ uci_procedures(PHY_VARS_eNB *eNB, SR_payload = 1; metric[0]=rx_pucch(eNB, uci->pucch_fmt, - i, + uci->ue_id, uci->n_pucch_1_0_sr[0], 0, //n2_pucch uci->srs_active, // shortened format @@ -775,7 +779,7 @@ uci_procedures(PHY_VARS_eNB *eNB, #if 1 metric[0] = rx_pucch(eNB, uci->pucch_fmt, - i, + uci->ue_id, uci->n_pucch_1[0][0], 0, //n2_pucch uci->srs_active, // shortened format @@ -795,7 +799,7 @@ uci_procedures(PHY_VARS_eNB *eNB, SR_payload = 1; metric[0] = rx_pucch(eNB, pucch_format1b, - i, + uci->ue_id, uci->n_pucch_1_0_sr[0], 0, //n2_pucch uci->srs_active, // shortened format @@ -1133,11 +1137,11 @@ uci_procedures(PHY_VARS_eNB *eNB, if (SR_payload == 1) { LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n", eNB->Mod_id, uci->rnti, frame, subframe); - if (eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 - eNB->first_sr[i] = 0; - eNB->dlsch[i][0]->harq_processes[0]->round = 0; - eNB->dlsch[i][0]->harq_processes[0]->status = SCH_IDLE; - LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d First SR\n", eNB->Mod_id, eNB->ulsch[i]->rnti, frame, subframe); + if (eNB->first_sr[uci->ue_id] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 + eNB->first_sr[uci->ue_id] = 0; + eNB->dlsch[uci->ue_id][0]->harq_processes[0]->round = 0; + eNB->dlsch[uci->ue_id][0]->harq_processes[0]->status = SCH_IDLE; + LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d First SR\n", eNB->Mod_id, eNB->ulsch[uci->ue_id]->rnti, frame, subframe); } } } @@ -1466,7 +1470,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, pdu->rx_indication_rel8.timing_advance = timing_advance_update; // estimate UL_CQI for MAC (from antenna port 0 only) - int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*eNB->measurements.n0_power_dB[0]); + int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi = 0; @@ -1519,8 +1523,10 @@ static void do_release_harq(PHY_VARS_eNB *eNB, harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - AssertFatal((harq_pid >= 0) && (harq_pid < 8),"harq_pid %d not in 0...7\n", harq_pid); - + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); + return; + } dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; @@ -1569,37 +1575,39 @@ static void do_release_harq(PHY_VARS_eNB *eNB, if (((1 << m) & mask) > 0) { harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) { - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; + if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) { + LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__); + return; + } + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; - AssertFatal(dlsch0_harq != NULL, "Dlsch0_harq is null\n"); + AssertFatal(dlsch0_harq != NULL, "Dlsch0_harq is null\n"); #if T_TRACER - if (after_rounds != -1) { - T(T_ENB_PHY_DLSCH_UE_NACK, - T_INT(0), - T_INT(frame), - T_INT(subframe), - T_INT(dlsch0->rnti), - T_INT(harq_pid)); - } else { - T(T_ENB_PHY_DLSCH_UE_ACK, - T_INT(0), - T_INT(frame), - T_INT(subframe), - T_INT(dlsch0->rnti), - T_INT(harq_pid)); - } + if (after_rounds != -1) { + T(T_ENB_PHY_DLSCH_UE_NACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); + } else { + T(T_ENB_PHY_DLSCH_UE_ACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); + } #endif - if (dlsch0_harq->round >= after_rounds) { - dlsch0_harq->status = SCH_IDLE; + if (dlsch0_harq->round >= after_rounds) { + dlsch0_harq->status = SCH_IDLE; - if ((dlsch1_harq == NULL) || ((dlsch1_harq != NULL) && (dlsch1_harq->status == SCH_IDLE))) { - dlsch0->harq_mask &= ~(1 << harq_pid); - } + if ((dlsch1_harq == NULL) || ((dlsch1_harq != NULL) && (dlsch1_harq->status == SCH_IDLE))) { + dlsch0->harq_mask &= ~(1 << harq_pid); } - } // end if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) + } } // end if (((1 << m) & mask) > 0) } // end for (int m=0; m < M; m++) } // end if TDD @@ -1638,7 +1646,7 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - if (harq_pid>=0 && harq_pid<10) { + if (harq_pid>=0 && harq_pid<dlsch0->Mdlharq) { dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); @@ -1654,8 +1662,9 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subframe, LTE_UL_eNB_HARQ_t *ulsch_harq, uint16_t rnti) { pthread_mutex_lock (&eNB->UL_INFO_mutex); - nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; - nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; + nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis]; + nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis]; + pdu->instance_length = 0; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; @@ -1681,9 +1690,11 @@ void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subfr pdu->cqi_indication_rel9.number_of_cc_reported = 1; pdu->ul_cqi_information.channel = 1; // PUSCH + pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; memcpy ((void *) raw_pdu->pdu, ulsch_harq->o, pdu->cqi_indication_rel9.length); - eNB->UL_INFO.cqi_ind.number_of_cqis++; - LOG_D(PHY,"eNB->UL_INFO.cqi_ind.number_of_cqis:%d\n", eNB->UL_INFO.cqi_ind.number_of_cqis); + eNB->UL_INFO.cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; + eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis++; + LOG_D(PHY,"eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis:%d\n", eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis); pthread_mutex_unlock(&eNB->UL_INFO_mutex); } @@ -1772,7 +1783,7 @@ void fill_uci_harq_indication (PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, i pdu->rx_ue_information.rnti = uci->rnti; // estimate UL_CQI for MAC (from antenna port 0 only) pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - int SNRtimes10 = dB_fixed_times10(uci->stat) - 300;//(10*eNB->measurements.n0_power_dB[0]); + int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; if (SNRtimes10 < -100) LOG_I (PHY, "uci->stat %d \n", uci->stat); @@ -2000,3 +2011,44 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); } + +void release_rnti_of_phy(module_id_t mod_id){ + int i,j; + int CC_id; + rnti_t rnti; + PHY_VARS_eNB *eNB_PHY = NULL; + LTE_eNB_ULSCH_t *ulsch = NULL; + LTE_eNB_DLSCH_t *dlsch = NULL; + for(i = 0; i< release_rntis.number_of_TLVs;i++){ + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_PHY = RC.eNB[mod_id][CC_id]; + rnti = release_rntis.ue_release_request_TLVs_list[i].rnti; + for (j=0; j<NUMBER_OF_UE_MAX; j++) { + ulsch = eNB_PHY->ulsch[j]; + if((ulsch != NULL) && (ulsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti); + clean_eNb_ulsch(ulsch); + } + + dlsch = eNB_PHY->dlsch[j][0]; + if((dlsch != NULL) && (dlsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_dlsch dlsch[%d] UE %x \n", j, rnti); + clean_eNb_dlsch(dlsch); + } + } + ulsch = eNB_PHY->ulsch[j]; + if((ulsch != NULL) && (ulsch->rnti == rnti)){ + LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti); + clean_eNb_ulsch(ulsch); + } + for(j=0; j<NUMBER_OF_UCI_VARS_MAX; j++) { + if(eNB_PHY->uci_vars[j].rnti == rnti){ + LOG_I(PHY, "clean eNb uci_vars[%d] UE %x \n",j, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + + } + } + } + memset(&release_rntis, 0, sizeof(nfapi_ue_release_request_body_t)); +} diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index dccfbf7c388ac204771e391eaa1044cffea9e4cd..7fcabdc5ddf8163b063edc655cdca442a0f0617c 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -219,6 +219,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); +void release_rnti_of_phy(module_id_t mod_id); /*@}*/ diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c index 7d478f3f942a4d0ecafe9ebdf309755a08755296..5ec0f6e6967cc2ae27bfe8b9b3b5d3d199b9525c 100644 --- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -91,7 +91,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } - +int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){ return(0); } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8cd9b98bb701f3f3879bd5ce39aa98483f777084..be69e96897b633d93e512ba989e84b70d5161bb9 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -619,8 +619,8 @@ int main(int argc, char **argv) { eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; printf("lte_param_init done\n"); // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE PHY_vars_UE_g = (PHY_VARS_UE ** *)malloc(sizeof(PHY_VARS_UE **)); diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 27723eec15937c7ce204bc4f4e6e9190b7505bfb..1948f1596addcac0e9a3a865791b4f67362a60a1 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -25,4 +25,8 @@ MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_del MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_enb_delete_tunnel_resp_t, Gtpv1uDeleteTunnelResp) MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_ind_t, Gtpv1uTunnelDataInd) MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_req_t, Gtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_req_t,Gtpv1uDataForwardingReq) +MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_ind_t,Gtpv1uDataForwardingInd) +MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq) +MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd) MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index c398b55e3ef2fc40d2bb21946c0d9fb68ff2751b..4f81c22fb0bee322e307222890e6ff51c456ddb8 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -33,10 +33,33 @@ #define GTPV1U_ENB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDeleteTunnelResp #define GTPV1U_ENB_TUNNEL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataInd #define GTPV1U_ENB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataReq +#define GTPV1U_ENB_DATA_FORWARDING_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingReq +#define GTPV1U_ENB_DATA_FORWARDING_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingInd +#define GTPV1U_ENB_END_MARKER_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerReq +#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd + #define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF +typedef struct gtpv1u_enb_create_x2u_tunnel_req_s { + rnti_t rnti; + int num_tunnels; + teid_t tenb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE]; + transport_layer_addr_t enb_addr[GTPV1U_MAX_BEARERS_PER_UE]; +} gtpv1u_enb_create_x2u_tunnel_req_t; + +typedef struct gtpv1u_enb_create_x2u_tunnel_resp_s { + uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0) + rnti_t rnti; + int num_tunnels; + teid_t enb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE]; + transport_layer_addr_t enb_addr; +} gtpv1u_enb_create_x2u_tunnel_resp_t; + + typedef struct gtpv1u_enb_create_tunnel_req_s { rnti_t rnti; int num_tunnels; @@ -99,6 +122,50 @@ typedef struct gtpv1u_enb_tunnel_data_req_s { rb_id_t rab_id; } gtpv1u_enb_tunnel_data_req_t; +typedef struct gtpv1u_enb_data_forwarding_req_s { + uint8_t *buffer; + uint32_t length; + uint32_t offset; ///< start of message offset in buffer + rnti_t rnti; + rb_id_t rab_id; +} gtpv1u_enb_data_forwarding_req_t; + +typedef struct gtpv1u_enb_data_forwarding_ind_s { + uint32_t frame; + uint8_t enb_flag; + uint32_t rb_id; + uint32_t muip; + uint32_t confirmp; + uint32_t sdu_size; + uint8_t *sdu_p; + uint8_t mode; + uint16_t rnti; + uint8_t module_id; + uint8_t eNB_index; +} gtpv1u_enb_data_forwarding_ind_t; + +typedef struct gtpv1u_enb_end_marker_req_s { + uint8_t *buffer; + uint32_t length; + uint32_t offset; ///< start of message offset in buffer + rnti_t rnti; + rb_id_t rab_id; +} gtpv1u_enb_end_marker_req_t; + +typedef struct gtpv1u_enb_end_marker_ind_s { + uint32_t frame; + uint8_t enb_flag; + uint32_t rb_id; + uint32_t muip; + uint32_t confirmp; + uint32_t sdu_size; + uint8_t *sdu_p; + uint8_t mode; + uint16_t rnti; + uint8_t module_id; + uint8_t eNB_index; +} gtpv1u_enb_end_marker_ind_t; + typedef struct { in_addr_t enb_ip_address_for_S1u_S12_S4_up; tcp_udp_port_t enb_port_for_S1u_S12_S4_up; diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 5a35b85fdb4e413d9f71fd3d475e163cdad09f3d..5f2a95f576611df8596103ee9652e94127cb08a7 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -107,6 +107,8 @@ typedef struct x2ap_register_enb_req_s { lte_frame_type_t frame_type[MAX_NUM_CCs]; uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + uint32_t subframeAssignment[MAX_NUM_CCs]; + uint32_t specialSubframe[MAX_NUM_CCs]; int num_cc; /* To be considered for TDD */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index ea54e48e73c04eae958e24a8d57fd7527d7a1bd6..a0527d5d7b88d6122dfa17d81b49ff20acd45439 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -157,7 +157,7 @@ void RCconfig_L1(void) { LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_inst=1 this is because phy_init_RU() uses that to index and not RC.num_eNB - why the 2 similar variables?\n", __FUNCTION__); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst); - //mac_top_init_eNB(); + mac_top_init_eNB(); configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n .remote_portd); } else { // other midhaul @@ -2505,6 +2505,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = ccparams_lte.tdd_config; + X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s; } else { AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 8337b94ddb2c05026aab76a7fb4dacaf91366e9a..26cbf8688d1600bbb8e8cd14dd879459f90533dc 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1,4 +1,3 @@ - /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -27,7 +26,6 @@ * \version 0.1 * \email: navid.nikaein@eurecom.fr * @ingroup _mac - */ #include "COMMON/platform_types.h" @@ -81,56 +79,55 @@ typedef struct band_info_s { } band_info_t; - static const eutra_bandentry_t eutra_bandtable[] = { - {1, 19200, 19800, 21100, 21700, 0 }, - {2, 18500, 19100, 19300, 19900, 6000 }, - {3, 17100, 17850, 18050, 18800, 12000}, - {4, 17100, 17550, 21100, 21550, 19500}, - {5, 8240, 8490, 8690, 8940, 24000}, - {6, 8300, 8400, 8750, 8850, 26500}, - {7, 25000, 25700, 26200, 26900, 27500}, - {8, 8800, 9150, 9250, 9600, 34500}, - {9, 17499, 17849, 18449, 18799, 38000}, - {10, 17100, 17700, 21100, 21700, 41500}, - {11, 14279, 14529, 14759, 15009, 47500}, - {12, 6980, 7160, 7280, 7460, 50100}, - {13, 7770, 7870, 7460, 7560, 51800}, - {14, 7880, 7980, 7580, 7680, 52800}, - {17, 7040, 7160, 7340, 7460, 57300}, - {18, 8150, 9650, 8600, 10100, 58500}, - {19, 8300, 8450, 8750, 8900, 60000}, - {20, 8320, 8620, 7910, 8210, 61500}, - {21, 14479, 14629, 14959, 15109, 64500}, - {22, 34100, 34900, 35100, 35900, 66000}, - {23, 20000, 20200, 21800, 22000, 75000}, - {24, 16126, 16605, 15250, 15590, 77000}, - {25, 18500, 19150, 19300, 19950, 80400}, - {26, 8140, 8490, 8590, 8940, 86900}, - {27, 8070, 8240, 8520, 8690, 90400}, - {28, 7030, 7580, 7580, 8130, 92100}, - {29, 0, 0, 7170, 7280, 96600}, - {30, 23050, 23250, 23500, 23600, 97700}, - {31, 45250, 34900, 46250, 35900, 98700}, - {32, 0, 0, 14520, 14960, 99200}, - {33, 19000, 19200, 19000, 19200, 36000}, - {34, 20100, 20250, 20100, 20250, 36200}, - {35, 18500, 19100, 18500, 19100, 36350}, - {36, 19300, 19900, 19300, 19900, 36950}, - {37, 19100, 19300, 19100, 19300, 37550}, - {38, 25700, 26200, 25700, 26300, 37750}, - {39, 18800, 19200, 18800, 19200, 38250}, - {40, 23000, 24000, 23000, 24000, 38650}, - {41, 24960, 26900, 24960, 26900, 39650}, - {42, 34000, 36000, 34000, 36000, 41590}, - {43, 36000, 38000, 36000, 38000, 43590}, - {44, 7030, 8030, 7030, 8030, 45590}, - {45, 14470, 14670, 14470, 14670, 46590}, - {46, 51500, 59250, 51500, 59250, 46790}, - {65, 19200, 20100, 21100, 22000, 65536}, - {66, 17100, 18000, 21100, 22000, 66436}, - {67, 0, 0, 7380, 7580, 67336}, - {68, 6980, 7280, 7530, 7830, 67536} + {1, 19200, 19800, 21100, 21700, 0 }, + {2, 18500, 19100, 19300, 19900, 6000 }, + {3, 17100, 17850, 18050, 18800, 12000 }, + {4, 17100, 17550, 21100, 21550, 19500 }, + {5, 8240, 8490, 8690, 8940, 24000 }, + {6, 8300, 8400, 8750, 8850, 26500 }, + {7, 25000, 25700, 26200, 26900, 27500 }, + {8, 8800, 9150, 9250, 9600, 34500 }, + {9, 17499, 17849, 18449, 18799, 38000 }, + {10, 17100, 17700, 21100, 21700, 41500 }, + {11, 14279, 14529, 14759, 15009, 47500 }, + {12, 6980, 7160, 7280, 7460, 50100 }, + {13, 7770, 7870, 7460, 7560, 51800 }, + {14, 7880, 7980, 7580, 7680, 52800 }, + {17, 7040, 7160, 7340, 7460, 57300 }, + {18, 8150, 9650, 8600, 10100, 58500 }, + {19, 8300, 8450, 8750, 8900, 60000 }, + {20, 8320, 8620, 7910, 8210, 61500 }, + {21, 14479, 14629, 14959, 15109, 64500 }, + {22, 34100, 34900, 35100, 35900, 66000 }, + {23, 20000, 20200, 21800, 22000, 75000 }, + {24, 16126, 16605, 15250, 15590, 77000 }, + {25, 18500, 19150, 19300, 19950, 80400 }, + {26, 8140, 8490, 8590, 8940, 86900 }, + {27, 8070, 8240, 8520, 8690, 90400 }, + {28, 7030, 7580, 7580, 8130, 92100 }, + {29, 0, 0, 7170, 7280, 96600 }, + {30, 23050, 23250, 23500, 23600, 97700 }, + {31, 45250, 34900, 46250, 35900, 98700 }, + {32, 0, 0, 14520, 14960, 99200 }, + {33, 19000, 19200, 19000, 19200, 360000}, + {34, 20100, 20250, 20100, 20250, 362000}, + {35, 18500, 19100, 18500, 19100, 363500}, + {36, 19300, 19900, 19300, 19900, 369500}, + {37, 19100, 19300, 19100, 19300, 375500}, + {38, 25700, 26200, 25700, 26300, 377500}, + {39, 18800, 19200, 18800, 19200, 382500}, + {40, 23000, 24000, 23000, 24000, 386500}, + {41, 24960, 26900, 24960, 26900, 396500}, + {42, 34000, 36000, 34000, 36000, 415900}, + {43, 36000, 38000, 36000, 38000, 435900}, + {44, 7030, 8030, 7030, 8030, 455900}, + {45, 14470, 14670, 14470, 14670, 465900}, + {46, 51500, 59250, 51500, 59250, 467900}, + {65, 19200, 20100, 21100, 22000, 655360}, + {66, 17100, 18000, 21100, 22000, 664360}, + {67, 0, 0, 7380, 7580, 67336 }, + {68, 6980, 7280, 7530, 7830, 67536 } }; diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 4e781e5b3f33f6873ee159b163aa8dd62dc6844f..45b46aae549a2b737b1f83dba3009dd5e4006535 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -600,10 +600,10 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power - int32_t normalized_rx_power; - /// target rx power - int32_t target_rx_power; + /// snr + int32_t snr; + /// target snr + int32_t target_snr; /// num rx pdu uint32_t num_pdu_rx[NB_RB_MAX]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index d284660364e7f408c9ef1296dfc086b65c30610c..bb2cb0bc11acdd4c2d7a0656eb68c5a35751a62b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -128,9 +128,11 @@ void schedule_SRS(module_id_t module_idP, continue; } - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); + if(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) { + LOG_E(MAC,"physicalConfigDedicated is null for UE %d\n",UE_id); + printf("physicalConfigDedicated is null for UE %d\n",UE_id); + return; + } /* CDRX condition on Active Time and SRS type-0 report (36.321 5.7) */ UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); @@ -464,6 +466,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, DL_req[CC_id].dl_config_request_body.number_dci++; DL_req[CC_id].dl_config_request_body.number_pdu++; DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; LOG_D(MAC, "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", UE_id, rnti, @@ -508,6 +511,13 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; } } // ul_failure_timer>0 + + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++; + if((U_PLANE_INACTIVITY_VALUE != 0) && (UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE * 10))){ + LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); + mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti); + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + }// time > 60s } void diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index e7ee2c8a357a94164671bd515a56879328f71c7e..24b6e74bf0dd4de589f54e4039e23d8276f36fa6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -868,8 +868,10 @@ generate_Msg4(module_id_t module_idP, ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = ra->rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1]; @@ -957,9 +959,12 @@ generate_Msg4(module_id_t module_idP, 1, // tpc, none getRIV(N_RB_DL, first_rb, 4), // resource_block_coding ra->msg4_mcs, // mcs - 1, // ndi + 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], 0, // rv 0); // vrb_flag + + UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid]; + LOG_D(MAC, "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n", frameP, subframeP, dl_req_body->number_pdu, @@ -1049,7 +1054,7 @@ generate_Msg4(module_id_t module_idP, mac->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, (frameP * 10) + subframeP, - rrc_sdu_length, + rrc_sdu_length+offset, mac->pdu_index[CC_idP], mac->UE_list. DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); @@ -1194,7 +1199,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, 1, // tpc, none getRIV(N_RB_DL, first_rb, 4), // resource_block_coding ra->msg4_mcs, // mcs - 1, // ndi + UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid], round & 3, // rv 0); // vrb_flag diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index fb80c9e1d6058a9c50b33c869063c4cb6da40929..d523fb4e17b6f7aa031b6b7849a4a9b51430f756 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -1158,6 +1158,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP); dl_req->number_dci++; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); @@ -1188,6 +1189,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; // Rel10 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index e7857a33ccdc75bcd0b3d349bd4857db79d6dc53..051b1cd77311a722eb9871ee2483f08ae5bd0166 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -489,7 +489,7 @@ schedule_ue_spec(module_id_t module_idP, COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; + int32_t snr, target_snr; int tpc = 1; UE_sched_ctrl_t *ue_sched_ctrl; int mcs; @@ -718,9 +718,12 @@ schedule_ue_spec(module_id_t module_idP, eNB_UE_stats->harq_pid = harq_pid; eNB_UE_stats->harq_round = round_DL; + if (eNB_UE_stats->rrc_status < RRC_RECONFIGURED) { + ue_sched_ctrl->uplane_inactivity_timer = 0; + } + if (eNB_UE_stats->rrc_status < RRC_CONNECTED) { - LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", - UE_id); + LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id); continue; } @@ -734,7 +737,7 @@ schedule_ue_spec(module_id_t module_idP, eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ if (NFAPI_MODE != NFAPI_MONOLITHIC) { - eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]]; + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, eNB->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); @@ -1007,9 +1010,11 @@ schedule_ue_spec(module_id_t module_idP, , 0 #endif ); - pthread_mutex_lock(&rrc_release_freelist); if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { + while(pthread_mutex_trylock(&rrc_release_freelist)){ + /* spin... */ + } uint16_t release_total = 0; for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0]; @@ -1056,9 +1061,9 @@ schedule_ue_spec(module_id_t module_idP, if(release_total >= rrc_release_info.num_UEs) break; } + pthread_mutex_unlock(&rrc_release_freelist); } - pthread_mutex_unlock(&rrc_release_freelist); for (ra_ii = 0, ra = &eNB->common_channels[CC_id].ra[0]; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) { if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) { @@ -1478,11 +1483,11 @@ schedule_ue_spec(module_id_t module_idP, } // do PUCCH power control - // this is the normalized RX power + // this is the snr // unit is not dBm, it's special from nfapi - // converting to dBm: ToDo: Noise power hard coded to 30 - normalized_rx_power = (((5 * ue_sched_ctrl->pucch1_snr[CC_id]) - 640) / 10) + 30; - target_rx_power= (eNB->puCch10xSnr / 10) + 30; + // converting to dBm + snr = (5 * ue_sched_ctrl->pucch1_snr[CC_id] - 640) / 10; + target_snr = eNB->puCch10xSnr / 10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = ue_template->pucch_tpc_tx_frame * 10 + ue_template->pucch_tpc_tx_subframe; @@ -1494,22 +1499,22 @@ schedule_ue_spec(module_id_t module_idP, ue_template->pucch_tpc_tx_frame = frameP; ue_template->pucch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { + if (snr > target_snr + 4) { tpc = 0; //-1 - } else if (normalized_rx_power < (target_rx_power - 4)) { + } else if (snr < target_snr - 4) { tpc = 2; //+1 } else { tpc = 1; //0 } - LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d\n", module_idP, frameP, subframeP, harq_pid, tpc, - normalized_rx_power, - target_rx_power); + snr, + target_snr); } // Po_PUCCH has been updated else { tpc = 1; //0 @@ -1890,8 +1895,8 @@ schedule_ue_spec_br(module_id_t module_idP, int round_DL = 0; int ta_update = 0; int32_t tpc = 1; - int32_t normalized_rx_power = 0; - int32_t target_rx_power = 0; + int32_t snr = 0; + int32_t target_snr = 0; uint16_t TBS = 0; uint16_t j = 0; uint16_t sdu_lengths[NB_RB_MAX]; @@ -2369,10 +2374,10 @@ schedule_ue_spec_br(module_id_t module_idP, T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); /* Do PUCCH power control */ - /* This is the normalized RX power */ - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ - normalized_rx_power = (5 * ue_sched_ctl->pucch1_snr[CC_id]-640) / 10 + 30; - target_rx_power = mac->puCch10xSnr / 10 + 30; + /* This is the snr */ + /* unit is not dBm, it's special from nfapi, convert to dBm */ + snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10; + target_snr = mac->puCch10xSnr / 10; /* This assumes accumulated tpc */ /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; @@ -2385,22 +2390,22 @@ schedule_ue_spec_br(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { + if (snr > target_snr + 4) { tpc = 0; //-1 - } else if (normalized_rx_power<(target_rx_power - 4)) { + } else if (snr < target_snr - 4) { tpc = 2; //+1 } else { tpc = 1; //0 } - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d\n", module_idP, frameP, subframeP, harq_pid, tpc, - normalized_rx_power, - target_rx_power); + snr, + target_snr); } else { // Po_PUCCH has been updated tpc = 1; // 0 } @@ -3085,11 +3090,9 @@ schedule_PCH(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, - first_rb, - 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 697c738b807b2d37668ec79177b99b2c10246d18..c071c1f505d7aad17b990ff33b0b9a9b0e51e906 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -585,6 +585,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, // uint16_t r1=0; uint8_t CC_id; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + int N_RB_DL; UE_sched_ctrl_t *ue_sched_ctl; // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; @@ -600,6 +601,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, #endif memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char)); memset(min_rb_unit,0,sizeof(min_rb_unit)); + memset(MIMO_mode_indicator[0], 0, MAX_NUM_CCs*N_RBG_MAX*sizeof(unsigned char)); for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here @@ -640,7 +642,18 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, average_rbs_per_user[CC_id] = 0; cc = &RC.mac[Mod_id]->common_channels[CC_id]; // Get total available RBS count and total UE count - temp_total_rbs_count = RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs; + N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); + temp_total_rbs_count = 0; + for(uint8_t rbg_i = 0;rbg_i < N_RBG[CC_id];rbg_i++ ){ + if(rballoc_sub[CC_id][rbg_i] == 0){ + if((rbg_i == N_RBG[CC_id] -1) && + ((N_RB_DL == 25) || (N_RB_DL == 50))){ + temp_total_rbs_count += (min_rb_unit[CC_id] -1); + }else{ + temp_total_rbs_count += min_rb_unit[CC_id]; + } + } + } temp_total_ue_count = dlsch_ue_select[CC_id].ue_num; for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { @@ -825,7 +838,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; // int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; + int32_t snr, target_snr; int32_t tpc = 1; static int32_t tpc_accumulated = 0; UE_sched_ctrl_t *ue_sched_ctl; @@ -1001,6 +1014,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP, UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_RECONFIGURED) { + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; @@ -1013,7 +1030,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ if (NFAPI_MODE != NFAPI_MONOLITHIC) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } @@ -1287,9 +1304,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, ,0, 0 #endif ); - pthread_mutex_lock(&rrc_release_freelist); - if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { + if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ + while(pthread_mutex_trylock(&rrc_release_freelist)) { + /* spin... */ + } uint16_t release_total = 0; for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { @@ -1326,9 +1345,9 @@ schedule_ue_spec_fairRR(module_id_t module_idP, if(release_total >= rrc_release_info.num_UEs) break; } + pthread_mutex_unlock(&rrc_release_freelist); } - pthread_mutex_unlock(&rrc_release_freelist); RA_t *ra = &eNB->common_channels[CC_id].ra[0]; for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) { @@ -1720,11 +1739,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, } // do PUCCH power control - // this is the normalized RX power + // this is the snr eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; /* Unit is not dBm, it's special from nfapi */ - normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;//(+eNB->measurements.n0_power_dB[0]) - target_rx_power= eNB->puCch10xSnr/10 + 30;//(+eNB->measurements.n0_power_dB[0]) + snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10; + target_snr = eNB->puCch10xSnr / 10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; @@ -1736,19 +1755,19 @@ schedule_ue_spec_fairRR(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+4)) { + if (snr > target_snr + 4) { tpc = 0; //-1 tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-4)) { + } else if (snr < target_snr - 4) { tpc = 2; //+1 tpc_accumulated++; } else { tpc = 1; //0 } - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP,frameP, subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); + tpc_accumulated,snr,target_snr); } // Po_PUCCH has been updated else { tpc = 1; //0 @@ -1763,6 +1782,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power @@ -1972,7 +1992,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t cc_id_flag[MAX_NUM_CCs]; uint8_t harq_pid = 0,round = 0; UE_list_t *UE_list= &eNB->UE_list; - uint8_t aggregation = 2; + uint8_t aggregation; int format_flag; nfapi_hi_dci0_request_body_t *HI_DCI0_req; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; @@ -2031,7 +2051,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( if ( round > 0 ) { hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; - + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2110,7 +2130,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]); - + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0); if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; break; @@ -2182,7 +2202,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ) { hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; - + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2235,7 +2255,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]); - + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[ul_inactivity_id[CC_id][temp]].dl_cqi[CC_id],format0); if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; continue; @@ -2402,8 +2422,8 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; - tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3; - tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); + tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); } if ( rb_table[rb_table_index]<3 ) { @@ -2434,12 +2454,20 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } } else { - // assigne RBS( 3 RBs) - first_rb[CC_id] = first_rb[CC_id] + 3; - UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; - UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; - UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; - } + if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED){ + // assigne RBS( 6 RBs) + first_rb[CC_id] = first_rb[CC_id] + 6; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 6; + UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 5; + UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; + }else{ + // assigne RBS( 3 RBs) + first_rb[CC_id] = first_rb[CC_id] + 3; + UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; + UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; + UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; + } + } } else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; @@ -2609,7 +2637,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, unsigned char sched_subframeP, ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) { int16_t UE_id; - uint8_t aggregation = 2; + uint8_t aggregation; uint16_t first_rb[MAX_NUM_CCs]; uint8_t ULSCH_first_end; rnti_t rnti = -1; @@ -2618,8 +2646,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, uint8_t status = 0; uint8_t rb_table_index = -1; uint32_t cqi_req,cshift,ndi,tpc; - int32_t normalized_rx_power; - int32_t target_rx_power=-90; + int32_t snr; + int32_t target_snr=0; static int32_t tpc_accumulated=0; int CC_id,ulsch_ue_num; int N_RB_UL; @@ -2738,6 +2766,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; harq_pid = subframe2harqpid(cc,sched_frame,sched_subframeP); rnti = UE_RNTI(CC_id,UE_id); + aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; @@ -2757,12 +2786,12 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, if (cc->tdd_Config) { switch (cc->tdd_Config->subframeAssignment) { case 1: - if( subframeP == 1 || subframeP == 6 ) cqi_req=0; + if( sched_subframeP == 1 || sched_subframeP == 6 ) cqi_req=0; break; case 3: - if( subframeP == 1 ) cqi_req=0; + if( sched_subframeP == 1 ) cqi_req=0; break; @@ -2782,8 +2811,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, //power control //compute the expected ULSCH RX power (for the stats) // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; //(+eNB->measurements.n0_power_dB[0]) - target_rx_power= eNB->puSch10xSnr/10 + 30; //(+eNB->measurements.n0_power_dB[0]) + snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + target_snr = eNB->puSch10xSnr / 10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; @@ -2793,10 +2822,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_template->pusch_tpc_tx_frame=frameP; UE_template->pusch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+4)) { + if (snr > target_snr + 4) { tpc = 0; //-1 tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-4)) { + } else if (snr < target_snr - 4) { tpc = 2; //+1 tpc_accumulated++; } else { @@ -2807,9 +2836,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, } if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP,frameP,subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); + tpc_accumulated,snr,target_snr); } // new transmission @@ -2822,8 +2851,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_sched_ctrl->cqi_req_timer); ndi = 1-UE_template->oldNDI_UL[harq_pid]; UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS @@ -2872,6 +2901,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; @@ -2998,8 +3028,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb), T_INT(round)); - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; uint8_t mcs_rv = 0; if(rvidx_tab[round&3]==1) { @@ -3029,6 +3059,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 4f74ab0d09a908a0f139cc0c705ef90a8e442935..18f35d4fe3ad8303ded74420dcd2085ff177b774 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -199,8 +199,8 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s uint8_t mcs = 20; uint8_t harq_pid = 0; uint32_t cqi_req = 0,cshift,ndi,tpc = 1; - int32_t normalized_rx_power; - int32_t target_rx_power= 178; + int32_t snr; + int32_t target_snr = 10; /* TODO: target_rx_power was 178, what to put? is it meaningful? */ int CC_id = 0; int nb_rb = 24; int N_RB_UL; @@ -258,15 +258,15 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s //power control //compute the expected ULSCH RX power (for the stats) - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; + // this is the snr and this should be constant (regardless of mcs) + snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; // new transmission ndi = 1-UE_template->oldNDI_UL[harq_pid]; UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs; UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 856045166f7b3f3b277e3d23947948b0527b8438..63f838f652daa216fa49b6d02c7b8c8848de23ce 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2193,8 +2193,8 @@ add_new_ue(module_id_t mod_idP, UE_list->UE_sched_ctrl[UE_id].ta_update = 31; for (j = 0; j < 8; j++) { - UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 - UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; + UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = 0; + UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0; UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; } @@ -2319,9 +2319,10 @@ rrc_mac_remove_ue(module_id_t mod_idP, rntiP); } - pthread_mutex_lock(&rrc_release_freelist); - - if (rrc_release_info.num_UEs > 0) { + if(rrc_release_info.num_UEs > 0){ + while(pthread_mutex_trylock(&rrc_release_freelist)) { + /* spin... */ + } uint16_t release_total = 0; for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { @@ -2341,6 +2342,7 @@ rrc_mac_remove_ue(module_id_t mod_idP, break; } } + pthread_mutex_unlock(&rrc_release_freelist); } pthread_mutex_unlock(&rrc_release_freelist); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index dd228c4250eca1fb13b85294e7ff199765981d46..be1f838aaadaba7db8841bdb61d81b9649565714 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -460,7 +460,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (RA_id != -1) { RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); - mac_rrc_data_ind(enb_mod_idP, + int8_t ret = mac_rrc_data_ind(enb_mod_idP, CC_idP, frameP, subframeP, UE_id, @@ -474,6 +474,7 @@ rx_sdu(const module_id_t enb_mod_idP, #endif ); /* Received a new rnti */ + if (ret == 0) { ra->state = MSGCRNTI; LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n", enb_mod_idP, @@ -502,6 +503,9 @@ rx_sdu(const module_id_t enb_mod_idP, } UE_template_ptr->ul_SR = 1; UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + } else { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + } // break; } } @@ -797,6 +801,10 @@ rx_sdu(const module_id_t enb_mod_idP, mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + + if (mac_eNB_get_rrc_status(enb_mod_idP, current_rnti) < RRC_RECONFIGURED) { + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } } break; @@ -1329,8 +1337,8 @@ schedule_ulsch_rnti(module_id_t module_idP, uint32_t cshift = 0; uint32_t ndi = 0; uint32_t tpc = 0; - int32_t normalized_rx_power = 0; - int32_t target_rx_power = 0; + int32_t snr = 0; + int32_t target_snr = 0; int32_t framex10psubframe = 0; static int32_t tpc_accumulated = 0; int sched_frame = 0; @@ -1555,13 +1563,12 @@ schedule_ulsch_rnti(module_id_t module_idP, /* Power control */ /* - * Compute the expected ULSCH RX power (for the stats) - * This is the normalized RX power and this should be constant (regardless of mcs) + * Compute the expected ULSCH RX snr (for the stats) + * This is the normalized RX snr and this should be constant (regardless of mcs) * Is not in dBm, unit from nfapi, converting to dBm - * ToDo: Noise power hard coded to 30 */ - normalized_rx_power = ((5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10) + 30; - target_rx_power = (mac->puSch10xSnr / 10) + 30; + snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10; + target_snr = mac->puSch10xSnr / 10; /* * This assumes accumulated tpc @@ -1575,10 +1582,10 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template_ptr->pusch_tpc_tx_frame = frameP; UE_template_ptr->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { + if (snr > target_snr + 4) { tpc = 0; // -1 tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { + } else if (snr < target_snr - 4) { tpc = 2; // +1 tpc_accumulated++; } else { @@ -1589,21 +1596,21 @@ schedule_ulsch_rnti(module_id_t module_idP, } if (tpc != 1) { - LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP, frameP, subframeP, harq_pid, tpc, tpc_accumulated, - normalized_rx_power, - target_rx_power); + snr, + target_snr); } ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator UE_template_ptr->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; UE_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid]; @@ -1941,8 +1948,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, uint8_t status = 0; uint32_t cshift = 0; uint32_t ndi = 0; - int32_t normalized_rx_power = 0; - int32_t target_rx_power = -90; + int32_t snr = 0; + int32_t target_snr = 0; int n = 0; int CC_id = 0; int N_RB_UL = 0; @@ -2050,10 +2057,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, UE_template->ul_SR = 0; status = mac_eNB_get_rrc_status(module_idP,rnti); cqi_req = 0; - /* Power control: compute the expected ULSCH RX power (for the stats) */ - /* This is the normalized RX power and this should be constant (regardless of mcs) */ - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; + /* Power control: compute the expected ULSCH RX snr (for the stats) */ + /* This is the normalized snr and this should be constant (regardless of mcs) */ + snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */ /* This assumes accumulated tpc */ /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; @@ -2063,10 +2070,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, UE_template->pusch_tpc_tx_frame = frameP; UE_template->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { + if (snr > target_snr + 4) { tpc = 0; //-1 UE_sched_ctrl->tpc_accumulated[CC_id]--; - } else if (normalized_rx_power < (target_rx_power - 4)) { + } else if (snr < target_snr - 4) { tpc = 2; //+1 UE_sched_ctrl->tpc_accumulated[CC_id]++; } else { @@ -2077,15 +2084,15 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, } if (tpc != 1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n", module_idP, frameP, subframeP, harq_pid, tpc, UE_sched_ctrl->tpc_accumulated[CC_id], - normalized_rx_power, - target_rx_power); + snr, + target_snr); } /* New transmission */ @@ -2094,8 +2101,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, UE_template->oldNDI_UL[harq_pid] = ndi; UE_template->mcs_UL[harq_pid] = 4; UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6); - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr; + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6; diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 276f1e4e6f25af1a85c256d0eda2a48a10d553a7..1760355f6152f12640c1916f84f6d3458032d567 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -169,7 +169,7 @@ #define MAX_NUM_SLICES 10 -#define U_PLANE_INACTIVITY_VALUE 6000 +#define U_PLANE_INACTIVITY_VALUE 0 /* defined 10ms order (zero means infinity) */ /* * eNB part @@ -754,10 +754,10 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power - int32_t normalized_rx_power; - /// target rx power - int32_t target_rx_power; + /// snr + int32_t snr; + /// target snr + int32_t target_snr; /// num rx pdu uint32_t num_pdu_rx[NB_RB_MAX]; @@ -1438,6 +1438,8 @@ typedef struct eNB_MAC_INST_s { tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU]; /// NFAPI DL PDU structure nfapi_tx_request_t TX_req[NFAPI_CC_MAX]; + /// NFAPI UE_release_req structure + nfapi_ue_release_request_t UE_release_req; /// UL handle uint32_t ul_handle; UE_list_t UE_list; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 2f001bdcfd82eef375e29051555a352289bbbe1f..4d34338ea98097d1229d9ee26e79624ff17a951a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -806,6 +806,7 @@ mem_block_t * rlc_am_get_pdu_to_retransmit( rlc_sn_t sn = rlc_pP->vt_a; rlc_sn_t sn_end = rlc_pP->vt_s; mem_block_t* pdu_p = NULL; + mem_block_t* mb_p = NULL; rlc_am_tx_data_pdu_management_t* tx_data_pdu_management; //Assertion(eNB)_PRAN_DesignDocument_annex No.769 if((rlc_pP->retrans_num_pdus <= 0) || (rlc_pP->vt_a == rlc_pP->vt_s)) @@ -884,6 +885,18 @@ mem_block_t * rlc_am_get_pdu_to_retransmit( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), tx_data_pdu_management->retx_count_next, sn); + mb_p = rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE].mem_block; + if(mb_p != NULL){ + free_mem_block(mb_p, __func__); + tx_data_pdu_management->mem_block = NULL; + tx_data_pdu_management->flags.retransmit = 0; + tx_data_pdu_management->flags.ack = 1; + tx_data_pdu_management->flags.transmitted = 0; + rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_management->retx_payload_size; + tx_data_pdu_management->retx_payload_size = 0; + tx_data_pdu_management->num_holes = 0; + rlc_pP->retrans_num_pdus --; + } } } else if (rlc_pP->nb_bytes_requested_by_mac >= 5) @@ -938,6 +951,18 @@ mem_block_t * rlc_am_get_pdu_to_retransmit( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), tx_data_pdu_management->retx_count_next, sn); + mb_p = rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE].mem_block; + if(mb_p != NULL){ + free_mem_block(mb_p, __func__); + tx_data_pdu_management->mem_block = NULL; + tx_data_pdu_management->flags.retransmit = 0; + tx_data_pdu_management->flags.ack = 1; + tx_data_pdu_management->flags.transmitted = 0; + rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_management->retx_payload_size; + tx_data_pdu_management->retx_payload_size = 0; + tx_data_pdu_management->num_holes = 0; + rlc_pP->retrans_num_pdus --; + } } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 9d69882923d84e02d97cde5047c4cb50f00a85af..4a065539013f323cb16a146cf2dd07b975ff7a6d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -938,7 +938,7 @@ rlc_am_rx_check_all_byte_segments( rlc_am_pdu_info_t *pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; mem_block_t *cursor_p = NULL; mem_block_t *first_cursor_p = NULL; - rlc_sn_t sn = pdu_info_p->sn; + rlc_usn_t sn = pdu_info_p->sn; sdu_size_t next_waited_so; sdu_size_t last_end_so; @@ -969,6 +969,9 @@ rlc_am_rx_check_all_byte_segments( // the so field of the first PDU should be 0 //cursor_p = list.head; //we start from the first stored PDU segment of this SN + if(cursor_p->data == NULL){ + return; + } pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; // if the first segment does not have SO = 0 then no need to continue @@ -985,6 +988,9 @@ rlc_am_rx_check_all_byte_segments( while (cursor_p->next != NULL) { //msg("rlc_am_rx_check_all_byte_segments(%d) @4\n",sn); cursor_p = cursor_p->next; + if(cursor_p->data == NULL){ + return; + } pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; if (pdu_info_p->sn == sn) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index 40bab6ff0b0b9f4021e7204fd3ab4e8b5fdf0e19..dbe55c483da8322bb1e1e76a76faca01630ee795 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -358,8 +358,6 @@ void rlc_am_segment_10 ( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), pdu_remaining_size); //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] pdu_mem_p %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n", rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame, pdu_mem_p, pdu_p, pdu_p->data, data, data_sdu_p,pdu_remaining_size); - rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui; - rlc_am_mui.rrc_mui_num++; memcpy(data, data_sdu_p, pdu_remaining_size); pdu_mngt_p->payload_size += pdu_remaining_size; @@ -397,8 +395,6 @@ void rlc_am_segment_10 ( continue_fill_pdu_with_sdu = 0; pdu_remaining_size = 0; } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) { - rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui; - rlc_am_mui.rrc_mui_num++; if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] [SIZE %d] REACHING RLC_AM_MAX_SDU_IN_PDU LIs -> STOP SEGMENTATION FOR THIS PDU SDU\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -416,6 +412,8 @@ void rlc_am_segment_10 ( // reduce the size of the PDU continue_fill_pdu_with_sdu = 0; fi_last_byte_pdu_is_last_byte_sdu = 1; + rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui; + rlc_am_mui.rrc_mui_num++; } else { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling PDU with %d all remaining bytes of SDU\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index 2251344c47f1c6714bfdcf9b6c3a3ea613c0248f..32c4d9788cf84a59afe502babf54db8fd4a6044c 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -176,13 +176,13 @@ int dump_eNB_l2_stats(char *buffer, int length) { UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes, UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes ); - len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : rx power (normalized %d, target %d), MCS (pre %d, post %d), RB (rx %d, retx %d, total %d), Current TBS %d \n", + len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : snr (%d, target %d), MCS (pre %d, post %d), RB (rx %d, retx %d, total %d), Current TBS %d \n", UE_id, map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, UE_list->eNB_UE_stats[CC_id][UE_id].crnti, - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power, - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power, + UE_list->eNB_UE_stats[CC_id][UE_id].snr, + UE_list->eNB_UE_stats[CC_id][UE_id].target_snr, UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1, UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2, UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_rx, diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index ad49a16cec2e52534bd4e8a1f318924c8b50878b..2cc43189c696134b92bf82d14c53411516c35f13 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -17,10 +17,34 @@ extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern uint16_t sf_ahead; +extern UL_RCC_IND_t UL_RCC_INFO; + uint16_t frame_cnt=0; void handle_rach(UL_IND_t *UL_info) { int i; - + if(NFAPI_MODE == NFAPI_MODE_VNF){ + for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ + if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) { + + AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); + LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_RCC_INFO.rach_ind[j].sfn_sf)); + initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf), + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0 +#endif + ); + free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list); + UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0; + UL_RCC_INFO.rach_ind[j].header.message_id = 0; + } + } + }else{ if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); UL_info->rach_ind.rach_indication_body.number_of_preambles=0; @@ -37,6 +61,7 @@ void handle_rach(UL_IND_t *UL_info) { #endif ); } + } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -72,6 +97,22 @@ void handle_sr(UL_IND_t *UL_info) { if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) { oai_nfapi_sr_indication(&UL_info->sr_ind); } + } else if(NFAPI_MODE == NFAPI_MODE_VNF){ + for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ + if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0){ + for (i=0;i<UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs;i++){ + SR_indication(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.sr_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.sr_ind[j].sfn_sf), + UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, + UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); + } + free(UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list); + UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs=0; + UL_RCC_INFO.sr_ind[j].header.message_id = 0; + } + } } else { for (i=0; i<UL_info->sr_ind.sr_indication_body.number_of_srs; i++) SR_indication(UL_info->module_id, @@ -89,27 +130,46 @@ void handle_cqi(UL_IND_t *UL_info) { int i; if (NFAPI_MODE==NFAPI_MODE_PNF) { - if (UL_info->cqi_ind.number_of_cqis>0) { - LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.number_of_cqis); - nfapi_cqi_indication_t ind; - ind.header.message_id = NFAPI_RX_CQI_INDICATION; - ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; - ind.cqi_indication_body = UL_info->cqi_ind; - oai_nfapi_cqi_indication(&ind); - UL_info->cqi_ind.number_of_cqis=0; + if (UL_info->cqi_ind.cqi_indication_body.number_of_cqis>0) { + LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.cqi_indication_body.number_of_cqis); + UL_info->cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION; + UL_info->cqi_ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; + + oai_nfapi_cqi_indication(&UL_info->cqi_ind); + UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; + } + } else if (NFAPI_MODE == NFAPI_MODE_VNF) { + for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ + if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0){ + for (i=0;i<UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis;i++){ + cqi_indication(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.cqi_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.cqi_ind[j].sfn_sf), + UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti, + &UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9, + UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_raw_pdu_list[i].pdu, + &UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].ul_cqi_information); + } + + free(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list); + free(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_raw_pdu_list); + UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis=0; + UL_RCC_INFO.cqi_ind[j].header.message_id = 0; + } } } else { - for (i=0; i<UL_info->cqi_ind.number_of_cqis; i++) + for (i=0;i<UL_info->cqi_ind.cqi_indication_body.number_of_cqis;i++) cqi_indication(UL_info->module_id, UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, - &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9, - UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu, - &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information); - - UL_info->cqi_ind.number_of_cqis=0; + NFAPI_SFNSF2SFN(UL_info->cqi_ind.sfn_sf), + NFAPI_SFNSF2SF(UL_info->cqi_ind.sfn_sf), + UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti, + &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9, + UL_info->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[i].pdu, + &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].ul_cqi_information); + + UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; } } @@ -123,7 +183,22 @@ void handle_harq(UL_IND_t *UL_info) { } UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; + }else if(NFAPI_MODE == NFAPI_MODE_VNF){ + for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){ + if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0){ + for (int i=0;i<UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs;i++){ + harq_indication(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.harq_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.harq_ind[j].sfn_sf), + &UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list[i]); + } + free(UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list); + UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs=0; + UL_RCC_INFO.harq_ind[j].header.message_id = 0; + } + } } else { for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++) harq_indication(UL_info->module_id, @@ -151,6 +226,56 @@ void handle_ulsch(UL_IND_t *UL_info) { oai_nfapi_rx_ind(&UL_info->rx_ind); UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } + } else if(NFAPI_MODE == NFAPI_MODE_VNF){ + for(uint8_t k = 0;k < NUM_NFPAI_SUBFRAME;k++){ + if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)){ + for (i=0;i<UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus;i++) { + for (j=0;j<UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs;j++) { + // find crc_indication j corresponding rx_indication i + LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", + j,UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i,UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti); + if (UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti == UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) { + LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", + j, UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag); + if (UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication + LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); + rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + (uint8_t *)NULL, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + } + else { + LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); + rx_sdu(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + } + if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL){ + free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data); + } + break; + } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) + } // for (j=0;j<UL_info->crc_ind.crc_indication_body.number_of_crcs;j++) + } // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) + free(UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list); + free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list); + UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs = 0; + UL_RCC_INFO.crc_ind[k].header.message_id =0; + UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus = 0; + UL_RCC_INFO.rx_ind[k].header.message_id = 0; + } + } } else { if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { for (i=0; i<UL_info->rx_ind.rx_indication_body.number_of_pdus; i++) { @@ -574,11 +699,11 @@ void UL_indication(UL_IND_t *UL_info) { Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; IF_Module_t *ifi = if_inst[module_id]; eNB_MAC_INST *mac = RC.mac[module_id]; + LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", UL_info->frame,UL_info->subframe, module_id,CC_id, - UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, - UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); + UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.cqi_indication_body.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); if(UL_info->frame==1023&&UL_info->subframe==6) { // dl scheduling (0,0) frame_cnt= (frame_cnt + 1)%7; // to prevent frame_cnt get too big @@ -604,6 +729,7 @@ void UL_indication(UL_IND_t *UL_info) { handle_sr(UL_info); handle_cqi(UL_info); handle_harq(UL_info); + // clear HI prior to handling ULSCH uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_id], UL_info->subframe); @@ -634,6 +760,9 @@ void UL_indication(UL_IND_t *UL_info) { sched_info->UL_req = NULL; sched_info->TX_req = &mac->TX_req[CC_id]; + pthread_mutex_lock(&lock_ue_freelist); + sched_info->UE_release_req = &mac->UE_release_req; + pthread_mutex_unlock(&lock_ue_freelist); #ifdef DUMP_FAPI dump_dl(sched_info); #endif diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index b6ede7d598a05f1e06e802fb0d52b46a96510b50..c42ba992c912c9e1c008b9e4dad89e08ff5c6ffa 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -71,7 +71,7 @@ typedef struct{ nfapi_sr_indication_t sr_ind; /// CQI indication list - nfapi_cqi_indication_body_t cqi_ind; + nfapi_cqi_indication_t cqi_ind; /// RACH indication list nfapi_rach_indication_t rach_ind; @@ -90,7 +90,27 @@ typedef struct{ } UL_IND_t; // Downlink subframe P7 +#define NUM_NFPAI_SUBFRAME 5 +typedef struct{ + /// harq indication list + nfapi_harq_indication_t harq_ind[NUM_NFPAI_SUBFRAME]; + + /// crc indication list + nfapi_crc_indication_t crc_ind[NUM_NFPAI_SUBFRAME]; + + /// SR indication list + nfapi_sr_indication_t sr_ind[NUM_NFPAI_SUBFRAME]; + + /// CQI indication list + nfapi_cqi_indication_t cqi_ind[NUM_NFPAI_SUBFRAME]; + + /// RACH indication list + nfapi_rach_indication_t rach_ind[NUM_NFPAI_SUBFRAME]; + + /// RX indication + nfapi_rx_indication_t rx_ind[NUM_NFPAI_SUBFRAME]; +} UL_RCC_IND_t; typedef struct{ /// Module ID @@ -109,6 +129,8 @@ typedef struct{ nfapi_hi_dci0_request_t *HI_DCI0_req; /// Pointers to DL SDUs nfapi_tx_request_t *TX_req; + /// Pointers to ue_release + nfapi_ue_release_request_t *UE_release_req; }Sched_Rsp_t; typedef struct { diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 8d625fbdc59337c86d4609e9a386314e411243c5..930387c742489c1a413cd76b3bb3a56bb3f74502 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -236,8 +236,8 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram // change for mutiple UE's simulation. //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); - nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; - nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; + nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; + nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; @@ -263,7 +263,7 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram - UL_INFO->cqi_ind.number_of_cqis++; + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++; // change for mutiple UE's simulation. //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex); diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index de96213a7581b1f96ca322a48136ac2d4f40e6f2..b4281637a1b6ca9b2969fe07a1fd851f1b518e5c 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -310,10 +310,13 @@ mac_rrc_data_ind( ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP); if(ue_context_p) { - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, - ue_context_p, - 0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; + if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) { + LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status); + return (-1); + } else { + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0); + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + } } } @@ -363,8 +366,7 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, flexran_agent_get_rrc_xface(Mod_instP)->flexran_agent_notify_ue_state_change(Mod_instP, rntiP, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } - - rrc_mac_remove_ue(Mod_instP,rntiP); + //rrc_mac_remove_ue(Mod_instP,rntiP); } void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP, diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index f2845a50d7b124ee44c73a4000b9afc2a1ea2bf9..d4e00ca96d08ca44c4c5969792c5c9fd71740b9a 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -4071,6 +4071,7 @@ do_RRCConnectionReestablishment( LTE_DL_CCCH_Message_t dl_ccch_msg; LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL; int i = 0; + ue_context_pP->ue_context.reestablishment_xid = Transaction_id; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 559b2bfb3844251603cb2b44fb621f7e6371f890..8cb53e577b4029b0029af9be48821c204663b88d 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -348,11 +348,24 @@ typedef enum HO_STATE_e { HO_COMPLETE, // initiated by the target eNB HO_REQUEST, HO_ACK, + HO_FORWARDING, HO_CONFIGURED, + HO_END_MARKER, + HO_FORWARDING_COMPLETE, HO_RELEASE, HO_CANCEL } HO_STATE_t; +typedef enum DATA_FORWARDING_STATE_e { + FORWARDING_EMPTY=0, + FORWARDING_NO_EMPTY +} DATA_FORWARDING_STATE_t; + +typedef enum DATA_ENDMARK_STATE_e { + ENDMARK_EMPTY=0, + ENDMARK_NO_EMPTY +} DATA_ENDMARK_STATE_t; + typedef enum SL_TRIGGER_e { SL_RECEIVE_COMMUNICATION=0, SL_TRANSMIT_RELAY_ONE_TO_ONE, @@ -477,6 +490,9 @@ typedef struct HANDOVER_INFO_s { uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ int size; /* size of above message in bytes */ int x2_id; /* X2AP UE ID in the target eNB */ + uint32_t x2u_teid; + DATA_FORWARDING_STATE_t forwarding_state; + DATA_ENDMARK_STATE_t endmark_state; } HANDOVER_INFO; typedef struct PER_EVENT_s { @@ -693,6 +709,12 @@ typedef struct eNB_RRC_UE_s { uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + /* Total number of e_rab already setup in the list */ + uint8_t nb_x2u_e_rabs; + // LG: For GTPV1 TUNNELS(X2U) + uint32_t enb_gtp_x2u_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t enb_gtp_x2u_addrs[S1AP_MAX_E_RAB]; + rb_id_t enb_gtp_x2u_ebi[S1AP_MAX_E_RAB]; uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 78a94e5245eee868ac43a650ddd1831a9e5a30aa..2c4dea77af82a8eb8f46a630530a2c0593e5afeb 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1114,6 +1114,8 @@ void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; free_list->num_UEs++; + eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti; + eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++; free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); pthread_mutex_unlock(&lock_ue_freelist); } @@ -1158,28 +1160,32 @@ void release_UE_in_freeList(module_id_t mod_id) { for (i=0; i<MAX_MOBILES_PER_ENB; i++) { ulsch = eNB_PHY->ulsch[i]; - if((ulsch != NULL) && (ulsch->rnti == rnti)) { void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); clean_eNb_ulsch(ulsch); } - if(eNB_PHY->uci_vars[i].rnti == rnti) { - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - - for (i=0; i<MAX_MOBILES_PER_ENB; i++) { dlsch = eNB_PHY->dlsch[i][0]; - if((dlsch != NULL) && (dlsch->rnti == rnti)) { void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); clean_eNb_dlsch(dlsch); } } + ulsch = eNB_PHY->ulsch[i]; + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } + + for (i=0; i<NUMBER_OF_UCI_VARS_MAX; i++) { + if(eNB_PHY->uci_vars[i].rnti == rnti) { + LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + } if (flexran_agent_get_rrc_xface(mod_id)) { flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( @@ -1241,6 +1247,34 @@ void release_UE_in_freeList(module_id_t mod_id) { } } +int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t* ue_context_pP) +{ + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + uint8_t i; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t** SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[ue_context_pP->ue_context.reestablishment_xid]; + if (*SRB_configList2 != NULL) { + if((*SRB_configList2)->list.count!=0){ + LOG_D(RRC, "rrc_eNB_previous_SRB2 SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p", + SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); + } + for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { + if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ){ + SRB2_config = (*SRB_configList2)->list.array[i]; + break; + } + } + }else{ + LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB_configList2 NULL\n"); + } + + if (SRB2_config != NULL) { + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + }else{ + LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB2_config NULL\n"); + } + return 0; +} //----------------------------------------------------------------------------- /* * Process the rrc connection setup complete message from UE (SRB1 Active) @@ -1556,10 +1590,6 @@ rrc_eNB_generate_RRCConnectionReestablishment( rnti); } - /* Activate release timer, if RRCComplete not received after 100 frames, remove UE */ - ue_context_pP->ue_context.ue_reestablishment_timer = 1; - /* Remove UE after 100 frames after LTE_RRCConnectionReestablishmentReject is triggered */ - ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000; } //----------------------------------------------------------------------------- @@ -1606,6 +1636,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( LTE_C_RNTI_t *cba_RNTI = NULL; int measurements_enabled; uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); + int ret = 0; + ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED ue_context_pP->ue_context.reestablishment_xid = next_xid; @@ -1711,10 +1743,36 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above create_tunnel_req.num_tunnels = j; - gtpv1u_update_s1u_tunnel( + + ret = gtpv1u_update_s1u_tunnel( ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); + if ( ret != 0 ) { + LOG_E(RRC,"gtpv1u_update_s1u_tunnel failed,start to release UE %x\n",reestablish_rnti); + // update s1u tunnel failed,reset rnti? + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p); + if (h_rc == HASH_TABLE_OK ) { + rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti; + } + } + if (ue_initial_id != 0) { + h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p); + if (h_rc == HASH_TABLE_OK ) { + rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti; + } + } + ue_context_pP->ue_context.ue_release_timer_s1 = 1; + ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100; + ue_context_pP->ue_context.ue_release_timer = 0; + ue_context_pP->ue_context.ue_reestablishment_timer = 0; + ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + rrc_eNB_free_UE(ctxt_pP->module_id,ue_context_pP); + ue_context_pP->ue_context.ul_failure_timer = 0; + put_UE_in_freelist(ctxt_pP->module_id, ctxt_pP->rnti, 0); + return; + } } /* EPC_MODE_ENABLED */ /* Update RNTI in ue_context */ @@ -2236,8 +2294,9 @@ rrc_eNB_generate_RRCConnectionRelease( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - pthread_mutex_lock(&rrc_release_freelist); - + while (pthread_mutex_trylock(&rrc_release_freelist)) { + /* spin... */ + } for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) { @@ -4060,8 +4119,40 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; - MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t)); - *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB +//<<<<<<< HEAD + MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB + if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) { + MeasObj->measObject.choice.measObjectEUTRA.ext1 = CALLOC(1, sizeof(struct LTE_MeasObjectEUTRA__ext1)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measCycleSCell_r10 = NULL; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10 = CALLOC(1, sizeof(struct LTE_MeasSubframePatternConfigNeigh_r10)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->present=LTE_MeasSubframePatternConfigNeigh_r10_PR_setup; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.present=LTE_MeasSubframePattern_r10_PR_subframePatternTDD_r10; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.present=LTE_MeasSubframePattern_r10__subframePatternTDD_r10_PR_subframeConfig1_5_r10; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf=CALLOC(3, sizeof(uint8_t)); + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.size=3; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.bits_unused=4; + switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) { + case 1: //subframe 0,4,5,9 + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x8C; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x63; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x10; + break; + + default: //subframe 0 , 5 + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x84; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x21; + MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x00; + break; + } + } + + MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = + (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; +//======= +// MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t)); +// *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB +//>>>>>>> origin/OAI_develop if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) { MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = @@ -4557,7 +4648,9 @@ rrc_eNB_process_MeasurementReport( /* HO info struct may not be needed anymore */ ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); ue_context_pP->ue_context.Status = RRC_HO_EXECUTION; + ue_context_pP->ue_context.handover_info->state = HO_REQUEST; + /* HO Preparation message */ msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ); rrc_eNB_generate_HandoverPreparationInformation( @@ -4685,8 +4778,8 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p); LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid); ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; - ue_context_target_p->ue_context.handover_info->state = HO_ACK; + //ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; + //ue_context_target_p->ue_context.handover_info->state = HO_ACK; ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id; ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id; memset (ue_context_target_p->ue_context.nh, 0, 32); @@ -4760,6 +4853,10 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re ue_context_target_p->ue_context.e_rab[i].param.e_rab_id, ue_context_target_p->ue_context.e_rab[i].param.gtp_teid); } + rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p); + + ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; + ue_context_target_p->ue_context.handover_info->state = HO_ACK; } void rrc_eNB_process_handoverCommand( @@ -4975,7 +5072,8 @@ check_handovers( if (ue_context_p->ue_context.handover_info->state == HO_ACK) { MessageDef *msg; // Configure target - ue_context_p->ue_context.handover_info->state = HO_CONFIGURED; + ue_context_p->ue_context.handover_info->state = HO_FORWARDING; + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ_ACK); rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); @@ -4988,13 +5086,162 @@ check_handovers( X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs; for (int i=0; i<ue_context_p->ue_context.setup_e_rabs; i++) { + /* set gtpv teid info */ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_p->ue_context.enb_gtp_x2u_teid[i]; + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_p->ue_context.enb_gtp_x2u_addrs[i]; } itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); LOG_I(RRC, "RRC Sends X2 HO ACK to the source eNB at frame %d and subframe %d \n", ctxt_pP->frame,ctxt_pP->subframe); } } + + if (ue_context_p->ue_context.Status == RRC_RECONFIGURED + && ue_context_p->ue_context.handover_info != NULL && + ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) { + +#if defined(ENABLE_ITTI) + MessageDef *msg_p; + int result; + protocol_ctxt_t ctxt; + + do { + // Checks if a message has been sent to PDCP sub-task + itti_poll_msg (TASK_DATA_FORWARDING, &msg_p); + + if (msg_p != NULL) { + + switch (ITTI_MSG_ID(msg_p)) { + case GTPV1U_ENB_DATA_FORWARDING_IND: + PROTOCOL_CTXT_SET_BY_MODULE_ID( + &ctxt, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).module_id, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).enb_flag, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rnti, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame, + 0, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index); + LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + PROTOCOL_CTXT_ARGS(&ctxt), + ITTI_MSG_NAME (msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p), + ITTI_MSG_INSTANCE (msg_p), + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode); + + LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); + result = pdcp_data_req (&ctxt, + SRB_FLAG_NO, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_size, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , NULL, NULL +#endif + ); + if (result != TRUE){ + LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n"); + }else{ + LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n"); + } + + // Message buffer has been processed, free it now. + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; + + default: + LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + } while(msg_p != NULL); + ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_EMPTY; + } + if( ue_context_p->ue_context.Status == RRC_RECONFIGURED && + ue_context_p->ue_context.handover_info != NULL && + ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_EMPTY && + ue_context_p->ue_context.handover_info->endmark_state == ENDMARK_NO_EMPTY && + ue_context_p->ue_context.handover_info->state == HO_END_MARKER ){ + + MessageDef *msg_p; + int result; + protocol_ctxt_t ctxt; + + do { + // Checks if a message has been sent to PDCP sub-task + itti_poll_msg (TASK_END_MARKER, &msg_p); + + if (msg_p != NULL) { + + switch (ITTI_MSG_ID(msg_p)) { + case GTPV1U_ENB_END_MARKER_IND: + PROTOCOL_CTXT_SET_BY_MODULE_ID( + &ctxt, + GTPV1U_ENB_END_MARKER_IND (msg_p).module_id, + GTPV1U_ENB_END_MARKER_IND (msg_p).enb_flag, + GTPV1U_ENB_END_MARKER_IND (msg_p).rnti, + GTPV1U_ENB_END_MARKER_IND (msg_p).frame, + 0, + GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index); + LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + PROTOCOL_CTXT_ARGS(&ctxt), + ITTI_MSG_NAME (msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p), + ITTI_MSG_INSTANCE (msg_p), + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, + GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode); + + LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); + result = pdcp_data_req (&ctxt, + SRB_FLAG_NO, + GTPV1U_ENB_END_MARKER_IND (msg_p).rb_id, + GTPV1U_ENB_END_MARKER_IND (msg_p).muip, + GTPV1U_ENB_END_MARKER_IND (msg_p).confirmp, + GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_size, + GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p, + GTPV1U_ENB_END_MARKER_IND (msg_p).mode +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , NULL, NULL +#endif + ); + if (result != TRUE){ + LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n"); + }else{ + LOG_D(RRC, "target enb send spgw buffer to PDCP!\n"); + } + + // Message buffer has been processed, free it now. + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; + + default: + LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + } while(msg_p != NULL); + + ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_EMPTY; + ue_context_p->ue_context.handover_info->state = HO_FORWARDING_COMPLETE; + +#endif + } } } @@ -7006,15 +7253,51 @@ rrc_eNB_decode_ccch( rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); break; } - + if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) && + (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)){ + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the c-rnti UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000; + rrc_eNB_previous_SRB2(ue_context_p); + ue_context_p->ue_context.ue_reestablishment_timer = 0; + } + //previous rnti + rnti_t previous_rnti = 0; + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][1] == c_rnti) { + previous_rnti = reestablish_rnti_map[i][0]; + break; + } + } + if(previous_rnti != 0){ + UE_id = find_UE_id(ctxt_pP->module_id, previous_rnti); + if(UE_id == -1){ + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE_id(MAC) previous rnti %x, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + break; + } if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) && (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - } + rrc_eNB_previous_SRB2(ue_context_p); + ue_context_p->ue_context.ue_reestablishment_timer = 0; + } + } + + //c-plane not end + if((ue_context_p->ue_context.Status != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest (UE %x c-plane is not end), let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + break; + } if(ue_context_p->ue_context.ue_reestablishment_timer > 0) { LOG_E(RRC, @@ -7557,6 +7840,9 @@ rrc_eNB_decode_dcch( dedicated_DRB = 3; RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; ue_context_p->ue_context.Status = RRC_RECONFIGURED; + if(ue_context_p->ue_context.handover_info){ + ue_context_p->ue_context.handover_info->state = HO_CONFIGURED; + } LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); @@ -7635,6 +7921,7 @@ rrc_eNB_decode_dcch( } } else if(dedicated_DRB == 0) { if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) { + rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); } else { @@ -7729,7 +8016,7 @@ rrc_eNB_decode_dcch( } RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.reestablishment_xid = -1; if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present == LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) { @@ -8540,7 +8827,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { instance = ITTI_MSG_INSTANCE(msg_p); /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) - LOG_I(RRC,"Received message %s\n",msg_name_p); + LOG_D(RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -8679,6 +8966,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case X2AP_HANDOVER_REQ_ACK: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; + x2ap_handover_req_ack_t *x2ap_handover_req_ack = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti); if (ue_context_p == NULL) { /* is it possible? */ @@ -8690,7 +8980,44 @@ void *rrc_enb_process_itti_msg(void *notUsed) { DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort(); + + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, ue_context_p->ue_context.rnti, (void**)>pv1u_ue_data_p); + /* set target enb gtp teid */ + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + LOG_E(RRC, "X2AP_HANDOVER_REQ_ACK func(), hashtable_get failed: while getting ue rnti %x in hashtable ue_mapping\n", ue_context_p->ue_context.rnti); + } else { + uint8_t nb_e_rabs_tobesetup = 0; + ebi_t eps_bearer_id = 0; + int ip_offset = 0; + in_addr_t in_addr; + x2ap_handover_req_ack = &X2AP_HANDOVER_REQ_ACK(msg_p); + nb_e_rabs_tobesetup = x2ap_handover_req_ack->nb_e_rabs_tobesetup; + ue_context_p->ue_context.nb_x2u_e_rabs = nb_e_rabs_tobesetup; + for(int i=0; i< nb_e_rabs_tobesetup; i++){ + ip_offset = 0; + eps_bearer_id = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; + ue_context_p->ue_context.enb_gtp_x2u_ebi[i] = eps_bearer_id; + ue_context_p->ue_context.enb_gtp_x2u_teid[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid; + gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid; + + if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 4) || + (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) { + in_addr = *((in_addr_t*)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer); + ip_offset = 4; + gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = in_addr; + ue_context_p->ue_context.enb_gtp_x2u_addrs[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr; + } + + if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 16) || + (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) { + memcpy(gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr.s6_addr, + &x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer[ip_offset], + 16); + } + } + } + rrc_eNB_process_handoverCommand(instance, ue_context_p, &X2AP_HANDOVER_REQ_ACK(msg_p)); ue_context_p->ue_context.handover_info->state = HO_PREPARE; break; diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index ff8f455d6cb5d1c88e6b884984e6db5b46563e3d..d873a825ba9ee2661c5c88ec4dab6c876a4955cf 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -27,14 +27,19 @@ * \email: lionel.gauthier@eurecom.fr */ +//#if defined(ENABLE_USE_MME) # include "rrc_defs.h" # include "rrc_extern.h" # include "RRC/LTE/MESSAGES/asn1_msg.h" # include "rrc_eNB_GTPV1U.h" # include "rrc_eNB_UE_context.h" # include "msc.h" + +//# if defined(ENABLE_ITTI) # include "asn1_conversions.h" # include "intertask_interface.h" +//#endif + # include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -88,6 +93,88 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( } } +//------------------------------------------------------------------------------ +boolean_t +gtpv_data_req( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id +) +//------------------------------------------------------------------------------ +{ + if(sdu_sizeP == 0) + { + LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0"); + return FALSE; + } + LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %d", ctxt_pP->rnti, sdu_sizeP, rb_idP); +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + + if(task_id == TASK_DATA_FORWARDING){ + + LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n"); + + message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_IND); + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti; + GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + }else if(task_id == TASK_END_MARKER){ + + LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n"); + + message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP); + + memcpy (message_buffer, buffer_pP, sdu_sizeP); + + message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_IND); + GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame; + GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag; + GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP; + GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP; + GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP; + GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP; + GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer; + GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP; + GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id; + GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti; + GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index; + + itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + } + } +#endif + + return TRUE; + +} + +//#endif + void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP @@ -112,3 +199,5 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( } itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); } + + diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index 23806f6a0482544ee0bb8845dc89d043760422d5..00c7490359031a138200ee8c59db35023dcd4957 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -53,4 +53,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( const rrc_eNB_ue_context_t* const ue_context_pP ); +boolean_t +gtpv_data_req( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id +); + #endif /* RRC_ENB_GTPV1U_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 7bbd3a595dc6986b101e3d0a0056d969ae2d0273..115dc0126d3a373c1ebaec603cdba4ed945ba266 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -256,6 +256,15 @@ rrc_eNB_S1AP_get_ue_ids( } if (ue_desc_p != NULL) { + struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL; + if ((s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_desc_p)) != NULL) { + LOG_E(RRC, "Removed UE context eNB_ue_s1ap_id %u\n", s1ap_ue_context_p->eNB_ue_s1ap_id); + s1ap_eNB_free_ue_context(s1ap_ue_context_p); + } else { + LOG_E(RRC, "Removing UE context eNB_ue_s1ap_id %u: did not find context\n",ue_desc_p->eNB_ue_s1ap_id); + } + return NULL; //skip the operation below to avoid loop + result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); if (ue_desc_p->ue_initial_id != UE_INITIAL_ID_INVALID) { result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); @@ -934,6 +943,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; uint8_t inde_list[NB_RB_MAX - 3]= {0}; + int ret; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; ue_initial_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).ue_initial_id; @@ -975,10 +986,23 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above // create_tunnel_req.num_tunnels = i; - gtpv1u_create_s1u_tunnel( + + ret = gtpv1u_create_s1u_tunnel( instance, &create_tunnel_req, &create_tunnel_resp); + if ( ret != 0 ) { + LOG_E(RRC,"rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_s1 = 1; + ue_context_p->ue_context.ue_release_timer_thres_s1 = 100; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + rrc_eNB_free_UE(ctxt.module_id,ue_context_p); + ue_context_p->ue_context.ul_failure_timer = 0; + return (0); + } + rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( &ctxt, &create_tunnel_resp, @@ -1251,6 +1275,8 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; uint8_t e_rab_done; + int ret = 0; + ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); @@ -1313,10 +1339,22 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above create_tunnel_req.num_tunnels = e_rab_done; // NN: not sure if we should create a new tunnel: need to check teid, etc. - gtpv1u_create_s1u_tunnel( + ret = gtpv1u_create_s1u_tunnel( instance, &create_tunnel_req, &create_tunnel_resp); + if ( ret != 0 ) { + LOG_E(RRC,"rrc_eNB_process_S1AP_E_RAB_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_s1 = 1; + ue_context_p->ue_context.ue_release_timer_thres_s1 = 100; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + rrc_eNB_free_UE(ctxt.module_id,ue_context_p); + ue_context_p->ue_context.ul_failure_timer = 0; + return (0); + } + rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( &ctxt, &create_tunnel_resp, @@ -2039,6 +2077,68 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, return 0; } +int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p) { + gtpv1u_enb_create_x2u_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_x2u_tunnel_resp_t create_tunnel_resp; + uint8_t e_rab_done; + uint8_t inde_list[NB_RB_MAX - 3]= {0}; + + if (ue_context_target_p == NULL) { + + return (-1); + } else { + + /* Save e RAB information for later */ + { + LOG_I(RRC, "[eNB %d] rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ: rnti %u nb_of_e_rabs %d\n", + instance, ue_context_target_p->ue_context.rnti, ue_context_target_p->ue_context.nb_of_e_rabs); + int i; + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); + uint8_t nb_e_rabs_tosetup = ue_context_target_p->ue_context.nb_of_e_rabs; + e_rab_done = 0; + + for (i = 0;i < nb_e_rabs_tosetup; i++) { + + if(ue_context_target_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) + continue; + + create_tunnel_req.eps_bearer_id[e_rab_done] = ue_context_target_p->ue_context.e_rab[i].param.e_rab_id; + LOG_I(RRC,"x2 tunnel setup: local index %d UE id %x, eps id %d \n", + i, + ue_context_target_p->ue_context.rnti, + create_tunnel_req.eps_bearer_id[i] ); + inde_list[i] = e_rab_done; + e_rab_done++; + } + + create_tunnel_req.rnti = ue_context_target_p->ue_context.rnti; // warning put zero above + create_tunnel_req.num_tunnels = e_rab_done; + // NN: not sure if we should create a new tunnel: need to check teid, etc. + gtpv1u_create_x2u_tunnel( + instance, + &create_tunnel_req, + &create_tunnel_resp); + + ue_context_target_p->ue_context.nb_x2u_e_rabs = create_tunnel_resp.num_tunnels; + for (i = 0; i < create_tunnel_resp.num_tunnels; i++) { + ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]] = create_tunnel_resp.enb_X2u_teid[i]; + ue_context_target_p->ue_context.enb_gtp_x2u_addrs[inde_list[i]] = create_tunnel_resp.enb_addr; + ue_context_target_p->ue_context.enb_gtp_x2u_ebi[inde_list[i]] = create_tunnel_resp.eps_bearer_id[i]; + + LOG_I(RRC, "rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ tunnel (%u, %u) bearer UE context index %u, msg index %u, eps bearer id %u, gtp addr len %d \n", + create_tunnel_resp.enb_X2u_teid[i], + ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]], + inde_list[i], + i, + create_tunnel_resp.eps_bearer_id[i], + create_tunnel_resp.enb_addr.length); + } + } + + return (0); + } +} + int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index 5feb55d635c63461b237b439f5f1654d9e2882dc..e5ff9c27d600d6371132e3f33782caeb4a3a96eb 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -278,6 +278,7 @@ int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_p int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP); +int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p); int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance); int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP); diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index e1a8b506bcabeea022da333856c3b0a03626b481..03d8216b5666a0904fac6492c264384eef0862bd 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -173,6 +173,8 @@ typedef struct x2ap_eNB_instance_s { lte_frame_type_t frame_type[MAX_NUM_CCs]; uint32_t fdd_earfcn_DL[MAX_NUM_CCs]; uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; + uint32_t subframeAssignment[MAX_NUM_CCs]; + uint32_t specialSubframe[MAX_NUM_CCs]; int num_cc; net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS]; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 53ec8574fd80e4305fc5e6744d5b8b7748d8f459..38ebd732ac390c02832b9f9645c67b96e63fd84e 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -144,7 +144,92 @@ int x2ap_eNB_generate_x2_setup_request( } } else { - AssertFatal(0,"X2Setuprequest not supported for TDD!"); + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i]; + switch (instance_p->subframeAssignment[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + switch (instance_p->specialSubframe[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6; + break; + case 7: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7; + break; + case 8: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal; + + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } } } ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); @@ -279,7 +364,92 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN } } else { - AssertFatal(0,"X2Setupresponse not supported for TDD!"); + servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i]; + switch (instance_p->subframeAssignment[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + switch (instance_p->specialSubframe[i]) { + case 0: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0; + break; + case 1: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1; + break; + case 2: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2; + break; + case 3: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3; + break; + case 4: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4; + break; + case 5: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5; + break; + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6; + break; + case 7: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7; + break; + case 8: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal; + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal; + + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } } } ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember); @@ -627,6 +797,27 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; { e_RABs_Admitted_Item->e_RAB_ID = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; + e_RABs_Admitted_Item->uL_GTP_TunnelEndpoint = NULL; + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint = (X2AP_GTPtunnelEndpoint_t *)calloc(1, sizeof(*e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint)); + + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size = (uint8_t)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length; + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused = 0; + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf = + calloc(1, e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size); + + memcpy (e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf, + x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer, + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size); + + X2AP_DEBUG("X2 handover response target ip addr. length %lu bits_unused %d buf %d.%d.%d.%d\n", + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size, + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused, + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[0], + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[1], + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[2], + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[3]); + + INT32_TO_OCTET_STRING(x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid, &e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID); } ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); } diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 41d92a695e0da3b933a190502a44cdab1a831d08..33fd9c5295fb8ad890f297a4de96bb564f1f4b00 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -749,6 +749,8 @@ int x2ap_eNB_handle_handover_response (instance_t instance, { X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck; X2AP_HandoverRequestAcknowledge_IEs_t *ie; + X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; + X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; @@ -816,6 +818,56 @@ int x2ap_eNB_handle_handover_response (instance_t instance, X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_E_RABs_Admitted_List, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__); + return -1; + }else{ + if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) { + + uint8_t nb_e_rabs_tobesetup; + nb_e_rabs_tobesetup = ie->value.choice.E_RABs_Admitted_List.list.count; + X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = nb_e_rabs_tobesetup; + + for (int i=0; i<nb_e_rabs_tobesetup; i++) { + e_RABS_Admitted_ItemIEs = (X2AP_E_RABs_Admitted_ItemIEs_t *) ie->value.choice.E_RABs_Admitted_List.list.array[i]; + e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; + + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_Admitted_Item->e_RAB_ID ; + X2AP_ERROR("x2u tunnel: index %d e_rab_id %d\n", i, X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id); + + if(e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint == NULL){ + X2AP_DEBUG("%s %d: X2AP_E_RABs_Admitted_Item_t->dL_GTP_TunnelEndpoint is a NULL pointer \n", __FILE__, __LINE__); + continue; + } + + memcpy(X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer, + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf, + e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size); + + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length = e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size; + + OCTET_STRING_TO_INT32(&e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID, + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid); + + + X2AP_DEBUG("x2u tunnel: index %d target enb ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[0], + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[1], + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[2], + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[3], + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length, + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid); + } + + } + + } + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index fcadb0530e45be25a03b1985234ffa95cbd2c91a..e56edb8fe6b54f5e811d1f9fbe33fe79d746724c 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -50,12 +50,18 @@ #include "common/ran_context.h" #include "gtpv1u_eNB_defs.h" #include "gtpv1u_eNB_task.h" +#include "rrc_eNB_GTPV1U.h" #undef GTP_DUMP_SOCKET extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; +extern struct rrc_eNB_ue_context_s* +rrc_eNB_get_ue_context( + eNB_RRC_INST* rrc_instance_pP, + rnti_t rntiP); + #if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 #include <linux/if.h> static int gtpv1u_dump_socket_g; @@ -105,6 +111,27 @@ static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_len #endif +//----------------------------------------------------------------------------- +static int gtpv1u_eNB_get_msgsource(struct rrc_eNB_ue_context_s *ue_context_p, teid_t teid) +{ + int erab_index = 0; + + /* source enb */ + if(ue_context_p->ue_context.handover_info != NULL && ue_context_p->ue_context.handover_info->state == HO_COMPLETE) + { + return GTPV1U_MSG_FROM_SPGW; + } + + /* target enb */ + for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) { + if(ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index] == teid){ + return GTPV1U_MSG_FROM_SOURCE_ENB; + } + } + + return GTPV1U_MSG_FROM_SPGW; +} + //----------------------------------------------------------------------------- static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req *req) { // Create and alloc new message @@ -198,10 +225,16 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( case NW_GTPV1U_ULP_API_RECV_TPDU: { uint8_t buffer[4096]; uint32_t buffer_len; + struct rrc_eNB_ue_context_s *ue_context_p; + uint16_t msgType = NW_GTP_GPDU; + NwGtpv1uMsgT *pMsg = NULL; + /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP * for transmission. */ teid = pUlpApi->apiInfo.recvMsgInfo.teid; + pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg; + msgType = pMsg->msgType; if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, buffer, &buffer_len)) { @@ -243,6 +276,158 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( 0,0, (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, buffer_len); + + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti); + if((ue_context_p != NULL) && + (ue_context_p->ue_context.handover_info != NULL) && + (ue_context_p->ue_context.handover_info->state < HO_FORWARDING_COMPLETE)) { + + if(msgType == NW_GTP_END_MARKER){ + /* in the source enb, UE in RRC_HO_EXECUTION mode */ + if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info->state == HO_COMPLETE) { + /* set handover state */ + //ue_context_p->ue_context.handover_info->state = HO_END_MARKER; + + MessageDef *msg; + // Configure end marker + msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_REQ); + GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len); + memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len); + GTPV1U_ENB_END_MARKER_REQ(msg).length = buffer_len; + GTPV1U_ENB_END_MARKER_REQ(msg).rnti = ctxt.rnti; + GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = gtpv1u_teid_data_p->eps_bearer_id; + GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX; + LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt.frame,ctxt.subframe); + itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), msg); + return NW_GTPV1U_OK; + } + } + + if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION || ue_context_p->ue_context.Status == RRC_RECONFIGURED) { + + int msgsrc = gtpv1u_eNB_get_msgsource(ue_context_p, teid); + + LOG_D(GTPU,"UE INFO.ueStatus %d, handover state %d, forwarding state %d, from %s. message type %s\n", + ue_context_p->ue_context.Status, + ue_context_p->ue_context.handover_info->state, + ue_context_p->ue_context.handover_info->forwarding_state, + msgsrc == GTPV1U_MSG_FROM_SOURCE_ENB?"Source eNB":"EPC", + msgsrc != GTPV1U_MSG_FROM_SOURCE_ENB? "UDP DATA" : + msgType == NW_GTP_END_MARKER?"END MARKER":"DATA FORWARDING"); + + /* target enb */ + if(msgType == NW_GTP_END_MARKER){ + LOG_I(GTPU, "target end receive END MARKER\n"); + ue_context_p->ue_context.handover_info->state = HO_END_MARKER; + gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req; + memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req)); + delete_tunnel_req.rnti = ctxt.rnti; + gtpv1u_delete_x2u_tunnel(ctxt.module_id, &delete_tunnel_req, GTPV1U_TARGET_ENB); + return NW_GTPV1U_OK; + } + + /* form source eNB message */ + if(msgsrc == GTPV1U_MSG_FROM_SOURCE_ENB) + { + LOG_I(GTPU, "Received a message data forwarding length %d\n", buffer_len); + +#if defined(LOG_GTPU) && LOG_GTPU > 0 + LOG_T(GTPU, "forwarding data info:\n", buffer_len); + + for(int i=1;i<=buffer_len; i++){ + LOG_T(GTPU, "%02x ", buffer[i-1]); + if(i%20 == 0)LOG_T(GTPU, "\n"); + } + LOG_T(GTPU, "\n"); +#endif + + result = gtpv_data_req( + &ctxt, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + 0, // mui + SDU_CONFIRM_NO, // confirm + buffer_len, + buffer, + PDCP_TRANSMISSION_MODE_DATA, + TASK_DATA_FORWARDING + ); + + if ( result == FALSE ) { + LOG_W(GTPU, "DATA FORWARDING message save failed\n"); + return NW_GTPV1U_FAILURE; + } + ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY; + return NW_GTPV1U_OK; + } + /* from epc message */ + else + { + /* in the source enb, UE in RRC_HO_EXECUTION mode */ + if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) { + MessageDef *msg; + // Configure target + msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_REQ); + GTPV1U_ENB_DATA_FORWARDING_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len); + memcpy(>PV1U_ENB_DATA_FORWARDING_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len); + GTPV1U_ENB_DATA_FORWARDING_REQ(msg).length = buffer_len; + GTPV1U_ENB_DATA_FORWARDING_REQ(msg).rnti = ctxt.rnti; + GTPV1U_ENB_DATA_FORWARDING_REQ(msg).rab_id = gtpv1u_teid_data_p->eps_bearer_id; + GTPV1U_ENB_DATA_FORWARDING_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX; + +#if defined(LOG_GTPU) && LOG_GTPU > 0 + + LOG_T(GTPU, "Send data forwarding sdu_buffer to target enb. len %d info\n", buffer); + for(int i=1; i<=buffer_len; i++){ + LOG_T(GTPU, "%02x ", buffer[i-1]); + if(i%20 == 0)LOG_T(GTPU, "\n"); + } + LOG_T(GTPU, "\n"); +#endif + + LOG_I(GTPU, "Send data forwarding to GTPV1-U at frame %d and subframe %d \n", ctxt.frame,ctxt.subframe); + itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), msg); + return NW_GTPV1U_OK; + } + + /* target eNB. x2ho forwarding is processing. spgw message save to TASK_END_MARKER */ + if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE && + ue_context_p->ue_context.handover_info->state != HO_END_MARKER ) + { + LOG_I(GTPU, "x2ho forwarding is processing. Received a spgw message. length %d\n", buffer_len); +#if defined(LOG_GTPU) && LOG_GTPU > 0 + LOG_T(GTPU, "spgw data info:\n", buffer_len); + for(int i=1;i<=buffer_len; i++){ + LOG_T(GTPU, "%02x ", buffer[i-1]); + if(i%20 == 0)LOG_T(GTPU, "\n"); + } + LOG_T(GTPU, "\n"); +#endif + + result = gtpv_data_req( + &ctxt, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + 0, // mui + SDU_CONFIRM_NO, // confirm + buffer_len, + buffer, + PDCP_TRANSMISSION_MODE_DATA, + TASK_END_MARKER + ); + + if ( result == FALSE ) { + LOG_W(GTPU, "DATA FORWARDING message save failed\n"); + return NW_GTPV1U_FAILURE; + } + + ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_NO_EMPTY; + return NW_GTPV1U_OK; + } + + } + + } + + } result = pdcp_data_req( &ctxt, SRB_FLAG_NO, @@ -259,7 +444,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( if ( result == FALSE ) { if (ctxt.configured == FALSE ) - LOG_W(GTPU, "PDCP data request failed, cause: RB is not configured!\n") ; + LOG_W(GTPU, "PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ; else LOG_W(GTPU, "PDCP data request failed\n"); @@ -550,6 +735,154 @@ gtpv1u_new_data_req( return 0; } +//----------------------------------------------------------------------------- +int +gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP + ) +{ + /* Create a new nw-gtpv1-u stack req using API */ + NwGtpv1uUlpApiT stack_req; + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + /* Local tunnel end-point identifier */ + teid_t x2u_teid = 0; + gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + int i; + ebi_t eps_bearer_id = 0; + + MSC_LOG_RX_MESSAGE( + MSC_GTPU_ENB, + MSC_RRC_ENB, + NULL,0, + MSC_AS_TIME_FMT" CREATE_X2U_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u ebid %u enb-x2u teid %u", + 0,0,create_tunnel_req_pP->rnti, instanceP, + create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->eps_bearer_id[0], + create_tunnel_req_pP->tenb_X2u_teid[0]); + + create_tunnel_resp_pP->rnti = create_tunnel_req_pP->rnti; + create_tunnel_resp_pP->status = 0; + create_tunnel_resp_pP->num_tunnels = 0; + + for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { + eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i]; + LOG_D(GTPU, "Rx GTPV1U_ENB_CREATE_X2U_TUNNEL_REQ ue rnti %x eps bearer id %u\n", + create_tunnel_req_pP->rnti, eps_bearer_id); + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); + + stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT; + + do { + x2u_teid = gtpv1u_new_teid(); + LOG_D(GTPU, "gtpv1u_create_x2u_tunnel() 0x%x %u(dec)\n", x2u_teid, x2u_teid); + stack_req.apiInfo.createTunnelEndPointInfo.teid = x2u_teid; + stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0; + stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0; + + rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); + LOG_D(GTPU, ".\n"); + } while (rc != NW_GTPV1U_OK); + + memcpy(&create_tunnel_resp_pP->enb_addr.buffer, + &RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, + sizeof (in_addr_t)); + + LOG_D(GTPU, "gtpv1u_create_x2u_tunnel() end addr %d.%d.%d.%d\n", + create_tunnel_resp_pP->enb_addr.buffer[0], + create_tunnel_resp_pP->enb_addr.buffer[1], + create_tunnel_resp_pP->enb_addr.buffer[2], + create_tunnel_resp_pP->enb_addr.buffer[3]); + + create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t); + create_tunnel_resp_pP->eps_bearer_id[i] = eps_bearer_id; + create_tunnel_resp_pP->num_tunnels += 1; + + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + create_tunnel_resp_pP->enb_X2u_teid[i] = x2u_teid; + hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, x2u_teid, (void**)>pv1u_teid_data_p); + + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + gtpv1u_teid_data_p = calloc (1, sizeof(gtpv1u_teid_data_t)); + gtpv1u_teid_data_p->enb_id = 0; // TO DO + gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti; + gtpv1u_teid_data_p->eps_bearer_id = eps_bearer_id; + hash_rc = hashtable_insert(RC.gtpv1u_data_g->teid_mapping, x2u_teid, gtpv1u_teid_data_p); + AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting teid mapping in GTPV1U hashtable"); + } else { + create_tunnel_resp_pP->enb_X2u_teid[i] = 0; + create_tunnel_resp_pP->status = 0xFF; + } + } + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_RRC_ENB, + NULL,0, + "0 GTPV1U_ENB_CREATE_TUNNEL_RESP rnti %x teid %x", + create_tunnel_resp_pP->rnti, + x2u_teid); + + LOG_D(GTPU, "Tx GTPV1U_ENB_CREATE_TUNNEL_RESP ue rnti %x status %d\n", + create_tunnel_req_pP->rnti, + create_tunnel_resp_pP->status); + return 0; +} + +//----------------------------------------------------------------------------- +int gtpv1u_delete_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_delete_tunnel_req_t * const req_pP, + int enbflag) +{ + gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + int erab_index = 0; + ebi_t eps_bearer_id = 0; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instanceP], req_pP->rnti); + if(ue_context_p != NULL){ + /* in the source enb */ + if(enbflag == GTPV1U_SOURCE_ENB){ + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, req_pP->rnti, (void**)>pv1u_ue_data_p); + + if (hash_rc == HASH_TABLE_OK) { + for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) { + eps_bearer_id = ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index]; + LOG_I(GTPU, "gtpv1u_delete_x2u_tunnel user rnti %x teNB X2U teid %u eps bearer id %u\n", + req_pP->rnti, + gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB, + ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index]); + + gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = 0; + gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = 0; + //gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr = 0; + } + ue_context_p->ue_context.nb_x2u_e_rabs = 0; + } + } + /* in the target enb */ + else{ + for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) { + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + hash_rc = hashtable_remove(RC.gtpv1u_data_g->teid_mapping, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]); + LOG_I(GTPU, "Removed user rnti %x , enb X2U teid %u\n", req_pP->rnti, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]); + + if (hash_rc != HASH_TABLE_OK) { + LOG_D(GTPU, "Removed user rnti %x , enb X2U teid %u not found\n", req_pP->rnti, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]); + } + } + ue_context_p->ue_context.nb_x2u_e_rabs = 0; + } + } + return 0; +} + //----------------------------------------------------------------------------- int gtpv1u_create_s1u_tunnel( @@ -572,6 +905,10 @@ gtpv1u_create_s1u_tunnel( int ip_offset = 0; in_addr_t in_addr; int addrs_length_in_bytes= 0; + int loop_counter = 0; + int ret = 0; + + MSC_LOG_RX_MESSAGE( MSC_GTPU_ENB, MSC_RRC_ENB, @@ -586,6 +923,7 @@ gtpv1u_create_s1u_tunnel( for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { ip_offset = 0; + loop_counter = 0; eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i]; LOG_D(GTPU, "Rx GTPV1U_ENB_CREATE_TUNNEL_REQ ue rnti %x eps bearer id %u\n", create_tunnel_req_pP->rnti, eps_bearer_id); @@ -600,7 +938,13 @@ gtpv1u_create_s1u_tunnel( stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0; rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); LOG_D(GTPU, ".\n"); - } while (rc != NW_GTPV1U_OK); + loop_counter++; + } while (rc != NW_GTPV1U_OK && loop_counter < 10); + if ( rc != NW_GTPV1U_OK && loop_counter == 10 ) { + LOG_E(GTPU,"NwGtpv1uCreateTunnelEndPoint failed 10 times,start next loop\n"); + ret = -1; + continue; + } //----------------------- // PDCP->GTPV1U mapping @@ -682,7 +1026,8 @@ gtpv1u_create_s1u_tunnel( LOG_D(GTPU, "Tx GTPV1U_ENB_CREATE_TUNNEL_RESP ue rnti %x status %d\n", create_tunnel_req_pP->rnti, create_tunnel_resp_pP->status); - return 0; + //return 0; + return ret; } int gtpv1u_update_s1u_tunnel( @@ -713,9 +1058,15 @@ int gtpv1u_update_s1u_tunnel( memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(gtpv1u_ue_data_t)); gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti; hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p); - AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable"); + //AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable"); + if ( hash_rc != HASH_TABLE_OK ) { + LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti); + return -1; + } else { LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n", create_tunnel_req_pP->rnti); + } + hash_rc = hashtable_remove(RC.gtpv1u_data_g->ue_mapping, prior_rnti); LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n", prior_rnti); @@ -1043,6 +1394,176 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { } break; + case GTPV1U_ENB_DATA_FORWARDING_REQ: { + gtpv1u_enb_data_forwarding_req_t *data_req_p = NULL; + NwGtpv1uUlpApiT stack_req; + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + teid_t enb_s1u_teid = 0; + teid_t tenb_x2u_teid = 0; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN); + data_req_p = >PV1U_ENB_DATA_FORWARDING_REQ(received_message_p); + //ipv4_send_data(ipv4_data_p->sd, data_ind_p->buffer, data_ind_p->length); + +#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 + gtpv1u_eNB_write_dump_socket(&data_req_p->buffer[data_req_p->offset],data_req_p->length); +#endif + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); + + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, (uint64_t)data_req_p->rnti, (void**)>pv1u_ue_data_p); + + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti); + } else { + if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_LTE_DRB_Identity)) { + enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB; + tenb_x2u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_teNB; // target enb teid + stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; + stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid; + stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip + + rc = nwGtpv1uGpduMsgNew( + RC.gtpv1u_data_g->gtpv1u_stack, + tenb_x2u_teid, + NW_FALSE, + RC.gtpv1u_data_g->seq_num++, + data_req_p->buffer, + data_req_p->length, + data_req_p->offset, + &(stack_req.apiInfo.sendtoInfo.hMsg)); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); + MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", + enb_s1u_teid,tenb_x2u_teid,data_req_p->length); + (void)enb_s1u_teid; /* avoid gcc warning "set but not used" */ + } else { + rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); + MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", + enb_s1u_teid,tenb_x2u_teid,data_req_p->length); + } else { + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_GTPU_SGW, + NULL, + 0, + MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", + 0,0, + enb_s1u_teid, + tenb_x2u_teid, + data_req_p->length); + + } + + rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, + stack_req.apiInfo.sendtoInfo.hMsg); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); + } + } + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT); + /* Buffer still needed, do not free it */ + //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer) + } + break; + + case GTPV1U_ENB_END_MARKER_REQ:{ + gtpv1u_enb_end_marker_req_t *data_req_p = NULL; + NwGtpv1uUlpApiT stack_req; + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + teid_t enb_s1u_teid = 0; + teid_t tenb_x2u_teid = 0; + NwGtpv1uMsgT *pMsg = NULL; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN); + data_req_p = >PV1U_ENB_END_MARKER_REQ(received_message_p); + //ipv4_send_data(ipv4_data_p->sd, data_ind_p->buffer, data_ind_p->length); + +#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 + gtpv1u_eNB_write_dump_socket(&data_req_p->buffer[data_req_p->offset],data_req_p->length); +#endif + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); + + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, (uint64_t)data_req_p->rnti, (void**)>pv1u_ue_data_p); + + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti); + } else { + if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_LTE_DRB_Identity)) { + enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB; + tenb_x2u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_teNB; // target enb teid + stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; + stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid; + stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip + + rc = nwGtpv1uGpduMsgNew( + RC.gtpv1u_data_g->gtpv1u_stack, + tenb_x2u_teid, + NW_FALSE, + RC.gtpv1u_data_g->seq_num++, + data_req_p->buffer, + data_req_p->length, + data_req_p->offset, + &(stack_req.apiInfo.sendtoInfo.hMsg)); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); + MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", + enb_s1u_teid,tenb_x2u_teid,data_req_p->length); + (void)enb_s1u_teid; /* avoid gcc warning "set but not used" */ + } else { + pMsg = (NwGtpv1uMsgT *) stack_req.apiInfo.sendtoInfo.hMsg; + pMsg->msgType = NW_GTP_END_MARKER; + rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); + MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", + enb_s1u_teid,tenb_x2u_teid,data_req_p->length); + } else { + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_GTPU_SGW, + NULL, + 0, + MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", + 0,0, + enb_s1u_teid, + tenb_x2u_teid, + data_req_p->length); + + } + + rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, + stack_req.apiInfo.sendtoInfo.hMsg); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); + } + + gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req; + memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req)); + delete_tunnel_req.rnti = data_req_p->rnti; + gtpv1u_delete_x2u_tunnel(instance, &delete_tunnel_req, GTPV1U_SOURCE_ENB); + } + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT); + } + break; + case TERMINATE_MESSAGE: { if (RC.gtpv1u_data_g->ue_mapping != NULL) { hashtable_destroy (&(RC.gtpv1u_data_g->ue_mapping)); diff --git a/openair3/GTPV1-U/gtpv1u_eNB_defs.h b/openair3/GTPV1-U/gtpv1u_eNB_defs.h index 978a3c58bc01731a463bde048fcac72cb07a836a..79d9a1dcdd54cb28c850d38b0cd161c6d3478719 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_defs.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_defs.h @@ -40,6 +40,11 @@ #define GTPV1U_MAX_BEARERS_ID (max_val_LTE_DRB_Identity - GTPV1U_BEARER_OFFSET) +#define GTPV1U_SOURCE_ENB (0) +#define GTPV1U_TARGET_ENB (1) +#define GTPV1U_MSG_FROM_SOURCE_ENB (0) +#define GTPV1U_MSG_FROM_SPGW (1) + typedef enum { BEARER_DOWN = 0, BEARER_IN_CONFIG, @@ -65,6 +70,9 @@ typedef struct gtpv1u_bearer_s { teid_t teid_sgw; ///< Remote TEID in_addr_t sgw_ip_addr; struct in6_addr sgw_ip6_addr; + teid_t teid_teNB; + in_addr_t tenb_ip_addr; ///< target eNB ipv4 + struct in6_addr tenb_ip6_addr; ///< target eNB ipv6 tcp_udp_port_t port; //NwGtpv1uStackSessionHandleT stack_session; bearer_state_t state; diff --git a/openair3/GTPV1-U/gtpv1u_eNB_task.h b/openair3/GTPV1-U/gtpv1u_eNB_task.h index 9830ea6169975439e708a840e20e29ea4af91cee..a6e26259415bee26adf21407707cc01d3d46baf2 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_task.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_task.h @@ -44,6 +44,12 @@ int gtpv1u_eNB_init(void); void *gtpv1u_eNB_process_itti_msg(void*); void *gtpv1u_eNB_task(void *args); +int +gtpv1u_create_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP); + int gtpv1u_create_s1u_tunnel( const instance_t instanceP, @@ -55,4 +61,9 @@ gtpv1u_update_s1u_tunnel( const instance_t instanceP, const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP, const rnti_t prior_rnti); + +int gtpv1u_delete_x2u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_delete_tunnel_req_t * const req_pP, + int enbflag); #endif /* GTPV1U_ENB_TASK_H_ */ diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c index 3e8da5d015faa56051c35f48185908137d81afeb..0c7663921b71dbd85c74323715c30ab19b316995 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c +++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c @@ -378,9 +378,14 @@ NwGtpv1uCreateTunnelEndPoint( NW_IN NwGtpv1uStackT *thiz, *phStackSession = (NwGtpv1uStackSessionHandleT) pTunnelEndPoint; pTunnelEndPoint = RB_FIND(NwGtpv1uTunnelEndPointIdentifierMap, &(thiz->teidMap), pTunnelEndPoint); - NW_ASSERT(pTunnelEndPoint); - GTPU_DEBUG("Tunnel end-point 0x%p creation successful for teid 0x%x %u(dec)", - pTunnelEndPoint, (unsigned int)teid, (unsigned int)teid); + //NW_ASSERT(pTunnelEndPoint); + if (!pTunnelEndPoint) { + GTPU_ERROR("Tunnel end-point cannot be NULL"); + rc = NW_GTPV1U_FAILURE; + } else { + GTPU_DEBUG("Tunnel end-point 0x%p creation successful for teid 0x%x %u(dec)", + pTunnelEndPoint, (unsigned int)teid, (unsigned int)teid); + } } } else { @@ -893,8 +898,14 @@ nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, break; case NW_GTP_END_MARKER: - GTPU_DEBUG("NW_GTP_END_MARKER\n"); - ret = NW_GTPV1U_OK; +#if defined(LOG_GTPU) && LOG_GTPU > 0 + for(int i =1; i<= udpDataLen; i++){ + printf("%02x ", udpData[i-1]); + if(i % 20 == 0)printf("\n"); + } +#endif + GTPU_INFO("NW_GTP_END_MARKER\n"); + ret = nwGtpv1uProcessGpdu(thiz, udpData, udpDataLen, peerIp); break; default: diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index e11fa11950d38af5426cda03f0f7d5ddaad54ec5..4b50f1de8279f3cbbfea727ebc67239239484ea4 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -1519,7 +1519,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (stream == 0) { S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n", assoc_id, stream); - return -1; + //return -1; } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 27f754badc28af6d805eda340143c34912de03ef..90ee87900df1136baf30eb536cf53d8225a07c57 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -371,13 +371,13 @@ void *udp_eNB_task(void *args_p) udp_sd = udp_sock_p->sd; pthread_mutex_unlock(&udp_socket_list_mutex); -#if defined(LOG_UDP) && LOG_UDP > 0 +//#if defined(LOG_UDP) && LOG_UDP > 0 LOG_D(UDP_, "[%d] Sending message of size %u to "IPV4_ADDR" and port %u\n", udp_sd, udp_data_req_p->buffer_length, IPV4_ADDR_FORMAT(udp_data_req_p->peer_address), udp_data_req_p->peer_port); -#endif +//#endif bytes_written = sendto( udp_sd, &udp_data_req_p->buffer[udp_data_req_p->buffer_offset], diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index b55b4922c57bbf327f9ebc7b68afd2d4e2bfab10..fcb3c94b902693bc08feae7d30e326a864b762a7 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -16,23 +16,27 @@ # ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_NR_UE_MAX 16 +# define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 3 # define NUMBER_OF_CONNECTED_gNB_MAX 3 # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 16 +# define NUMBER_OF_UCI_VARS_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 3 # endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 256 +# define NUMBER_OF_UCI_VARS_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif # else # define NUMBER_OF_UE_MAX 1 # define NUMBER_OF_NR_UE_MAX 1 +# define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif @@ -50,17 +54,20 @@ and the other are using MAX_MOBILES_PER_ENB in for-loop. # ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_NR_UE_MAX 20 +# define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 3 # define NUMBER_OF_CONNECTED_gNB_MAX 3 # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 20 +# define NUMBER_OF_UCI_VARS_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 3 # endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_NR_UE_MAX 256 +# define NUMBER_OF_UCI_VARS_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index df2c81c21cec356c970237186d4a896af0c45ce4..6634ae51d29cbed9c1f477ab9f6a0e6e92cc82aa 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -194,14 +194,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB, eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || - eNB->UL_INFO.cqi_ind.number_of_cqis + eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis ) { LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, - eNB->UL_INFO.cqi_ind.number_of_cqis, + eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols); } @@ -223,9 +223,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB, wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); #endif } - - release_UE_in_freeList(eNB->Mod_id); - + if (NFAPI_MODE!=NFAPI_MODE_PNF) { + release_UE_in_freeList(eNB->Mod_id); + } else { + release_rnti_of_phy(eNB->Mod_id); + } // UE-specific RX processing for subframe n if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { phy_procedures_eNB_uespec_RX(eNB, proc); @@ -436,13 +438,12 @@ static void *L1_thread( void *param ) } LOG_D(PHY,"L1 RX %d.%d done\n",proc->frame_rx,proc->subframe_rx); - - if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) phy_procedures_eNB_TX(eNB, proc, 1); - - if (NFAPI_MODE!=NFAPI_MODE_VNF) { - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(eNB,proc,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx); + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) { + phy_procedures_eNB_TX(eNB, proc, 1); + wakeup_txfh(eNB,proc,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx); + } } if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; @@ -968,7 +969,9 @@ void init_eNB_proc(int inst) LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { + pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); + } else if ((get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc); } else if (NFAPI_MODE==NFAPI_MODE_VNF) { // this is neccesary in VNF or L2 FAPI simulator. @@ -979,10 +982,12 @@ void init_eNB_proc(int inst) pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, L1_proc_tx); } - pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); + if (NFAPI_MODE!=NFAPI_MODE_VNF) { + pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); + pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif + } AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB); @@ -1144,6 +1149,7 @@ void init_transport(PHY_VARS_eNB *eNB) LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LOG_I(PHY, "Initialise transport\n"); +if (NFAPI_MODE!=NFAPI_MODE_VNF) { for (i=0; i<NUMBER_OF_UE_MAX; i++) { LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i); @@ -1186,6 +1192,7 @@ void init_transport(PHY_VARS_eNB *eNB) LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); +} eNB->rx_total_gain_dB=130; for(i=0; i<NUMBER_OF_UE_MAX; i++) @@ -1328,8 +1335,8 @@ void init_eNB(int single_thread_flag, eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; eNB->prach_energy_counter = 0; } } diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index dd91f540047e7108102f04bb6102216395ce60b7..a5fee5397fdd7cababcceb9dce14af44d273c6b5 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -62,6 +62,7 @@ void get_common_options(void) { uint32_t nonbiot; uint32_t rfsim; uint32_t basicsim; + char *logmem_filename = NULL; uint32_t do_forms; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; @@ -83,6 +84,13 @@ void get_common_options(void) { load_module_shlib("telnetsrv",NULL,0,NULL); } + if (logmem_filename != NULL && strlen(logmem_filename) > 0) { + log_mem_filename = &logmem_filename[0]; + log_mem_flag = 1; + printf("Enabling OPT for log save at memory %s\n",log_mem_filename); + logInit_log_mem(); + } + if (noS1) { set_softmodem_optmask(SOFTMODEM_NOS1_BIT); } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index a842cba853a38246b762f818e3af4f7e26519624..24a15816a20f08597d5c59f2b759c096bd86c90d 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -259,7 +259,7 @@ void exit_function(const char *file, const char *function, const int line, const if (s != NULL) { printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } - + close_log_mem(); oai_exit = 1; if (RC.ru == NULL) @@ -523,6 +523,7 @@ int main ( int argc, char **argv ) int i; int CC_id = 0; int ru_id; + int node_type = ngran_eNB; if ( load_configmodule(argc,argv,0) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); @@ -603,12 +604,13 @@ int main ( int argc, char **argv ) RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } + node_type = RC.rrc[0]->node_type; } else { printf("RC.nb_inst = 0, Initializing L1\n"); RCconfig_L1(); } - if (RC.nb_inst > 0 && NODE_IS_CU(RC.rrc[0]->node_type)) { + if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) { protocol_ctxt_t ctxt; ctxt.module_id = 0 ; ctxt.instance = 0; @@ -620,7 +622,7 @@ int main ( int argc, char **argv ) } /* start threads if only L1 or not a CU */ - if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) { + if (RC.nb_inst == 0 || !NODE_IS_CU(node_type) || NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) { // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs); @@ -719,7 +721,7 @@ int main ( int argc, char **argv ) LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit); // stop threads - if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) { + if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) { if(IS_SOFTMODEM_DOFORMS) end_forms(); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index f2be4d54e6a78b8ef67a775a2ef29c13e576aa44..5b58a5daabfb02f3f7ea225f93703d9980279a02 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -216,16 +216,17 @@ #define CONFIG_HLP_LOGV "Set the global log verbosity \n" #define CONFIG_HLP_TELN "Start embedded telnet server \n" #define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters for LOG utility */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for LOG utility */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------*/ #define START_MSC softmodem_params.start_msc #define CMDLINE_LOGPARAMS_DESC { \ - {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ - {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ - {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ - {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ + {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ + {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ + {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ + {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ + {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \ } #define CMDLINE_ONLINELOG_IDX 0 @@ -235,10 +236,11 @@ /* check function for global log level */ #define CMDLINE_LOGPARAMS_CHECK_DESC { \ - { .s5= {NULL }} , \ - { .s2= { config_check_intrange, {0,4}}}, \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ + { .s5= {NULL} } , \ + { .s2= {config_check_intrange, {0,4}}}, \ + { .s5= {NULL} } , \ + { .s5= {NULL} } , \ + { .s5= {NULL} } , \ } /***************************************************************************************************************************************/ diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 10fc476868adfe6947ec95592f7fb2b987817c45..8a4172965e55b3b081d3f757d0658d9af6b9bf94 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1074,9 +1074,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; - UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); - UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); - UL_INFO->cqi_ind.number_of_cqis = 0; + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); @@ -1283,10 +1283,10 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; //} - free(UL_INFO->cqi_ind.cqi_pdu_list); - UL_INFO->cqi_ind.cqi_pdu_list = NULL; - free(UL_INFO->cqi_ind.cqi_raw_pdu_list); - UL_INFO->cqi_ind.cqi_raw_pdu_list = NULL; + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL; + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL; free(UL_INFO); UL_INFO = NULL;