diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index a6621afe25..b413617580 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -262,6 +262,7 @@ pipeline { echo "This is a MERGE event" addGitLabMRComment comment: message } + echo "Pipeline is SUCCESSFUL" } } failure { @@ -271,6 +272,7 @@ pipeline { echo "This is a MERGE event" addGitLabMRComment comment: message } + echo "Pipeline FAILED" } } } diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index a6350c9a03..33e29d172a 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -207,6 +207,7 @@ class Containerize(): self.testCase_id = HTML.testCase_id self._createWorkspace(mySSH, lPassword, lSourcePath) + # if asterix, copy the entitlement and subscription manager configurations if self.host == 'Red Hat': mySSH.command('mkdir -p tmp/ca/', '\$', 5) @@ -214,20 +215,29 @@ class Containerize(): mySSH.command('sudo cp /etc/rhsm/ca/redhat-uep.pem tmp/ca/', '\$', 5) mySSH.command('sudo cp /etc/pki/entitlement/*.pem tmp/entitlement/', '\$', 5) - imageTag = 'develop' + sharedimage = 'ran-build' sharedTag = 'develop' + forceSharedImageBuild = False + imageTag = 'develop' if (self.ranAllowMerge): imageTag = 'ci-temp' - sharedimage = 'ran-build' + if self.ranTargetBranch == 'develop': + mySSH.command('git diff HEAD..origin/develop -- docker/Dockerfile.ran' + self.dockerfileprefix + ' | grep -i INDEX', '\$', 5) + result = re.search('index', mySSH.getBefore()) + if result is not None: + forceSharedImageBuild = True + sharedTag = 'ci-temp' + # Let's remove any previous run artifacts if still there mySSH.command(self.cli + ' image prune --force', '\$', 30) - if (not self.ranAllowMerge): - mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + sharedTag, '\$', 30) + if forceSharedImageBuild: + mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + sharedTag + ' || true', '\$', 30) for image,pattern in imageNames: - mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag, '\$', 30) + mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag + ' || true', '\$', 30) # Build the shared image only on Push Events (not on Merge Requests) - if (not self.ranAllowMerge): + # On when the shared image docker file is being modified. + if forceSharedImageBuild: mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target ' + sharedimage + ' --tag ' + sharedimage + ':' + sharedTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600) # First verify if the shared image was properly created. status = True diff --git a/ci-scripts/conf_files/channelmod_rfsimu.conf b/ci-scripts/conf_files/channelmod_rfsimu.conf index 9a6ded24f1..cd4490d9ba 100644 --- a/ci-scripts/conf_files/channelmod_rfsimu.conf +++ b/ci-scripts/conf_files/channelmod_rfsimu.conf @@ -15,7 +15,7 @@ channelmod = { ds_tdl = 0; }, { - model_name = "rfsimu_channel_ue1" + model_name = "rfsimu_channel_ue0" type = "AWGN"; ploss_dB = 0; noise_power_dB = 0; diff --git a/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf new file mode 100644 index 0000000000..d2e91fb872 --- /dev/null +++ b/ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf @@ -0,0 +1,281 @@ +Active_eNBs = ( "eNB-Eurecom-B38"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe02; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-B38"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 97; mnc_length = 2; } ); + + 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 = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2605000000L; + nr_scg_ssb_freq = 624608; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 2; + nb_antennas_rx = 2; + tx_gain = 90; + rx_gain = 125; + 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 = -29; + 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"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eno1"; + 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; + scheduler_mode = "fairRR"; + bler_target_upper = 20.0; + bler_target_lower = 10.0; + max_ul_rb_index = 27; + puSch10xSnr = 200; + puCch10xSnr = 150; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 200; + pucch1_dtx_threshold = 5 + pucch1ab_dtx_threshold =0; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 2 + nb_rx = 2 + att_tx = 0 + att_rx = 0; + bands = [38]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + sdr_addrs = "mgmt_addr=192.168.18.241,addr=192.168.20.2,second_addr=192.168.10.2"; + + } +); + +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"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + 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.band38.nsa_2x2.100PRB.usrpn310.conf b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf index 3460b82ac5..6c8d5ba6f0 100644 --- a/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf +++ b/ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf @@ -6,7 +6,7 @@ eNBs = ( { ////////// Identification parameters: - eNB_ID = 0xe00; + eNB_ID = 0xe04; cell_type = "CELL_MACRO_ENB"; diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf index c5a7c39d0d..9bf3136690 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf @@ -254,7 +254,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 150; - ulsch_max_slots_inactivity=20; } ); diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf index 9e24ac62cd..dfbbdf659d 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf @@ -251,7 +251,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 150; - ulsch_max_slots_inactivity=20; } ); diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf index 0e503188c5..1c62882406 100644 --- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -228,9 +228,8 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - ulsch_max_slots_inactivity = 1; pusch_TargetSNRx10 = 200; - pucch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; } ); diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf index e6fafd1ef2..a4452b202d 100644 --- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf @@ -251,6 +251,7 @@ RUs = ( eNB_instances = [0]; bf_weights = [0x00007fff, 0x00007fff]; #clock_src = "external"; + sf_extension = 0 sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" } ); diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf index 819f48b7bd..c889ba2b89 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf @@ -253,8 +253,8 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 200; - pucch_TargetSNRx10 = 150; +# pusch_TargetSNRx10 = 200; +# pucch_TargetSNRx10 = 150; ulsch_max_slots_inactivity=20; } ); @@ -265,7 +265,7 @@ L1s = ( tr_n_preference = "local_mac"; pusch_proc_threads = 2; prach_dtx_threshold = 120; - pucch0_dtx_threshold = 150; +# pucch0_dtx_threshold = 150; } ); @@ -288,7 +288,7 @@ RUs = ( # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 4x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; - + sf_extension = 0 sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" } ); diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf index 145f58cb93..a5d35d450e 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -219,7 +219,7 @@ gNBs = GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR"; GNB_INTERFACE_NAME_FOR_NGU = "eth0"; GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR"; - GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_PORT_FOR_NGU = 2152; # Spec 2152 }; } @@ -232,7 +232,6 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 150; - ulsch_max_slots_inactivity = 10; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aaf4190087..4f0f7c6b2e 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -211,7 +211,6 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - ulsch_max_slots_inactivity = 1; } ); diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index d4b5ca33c2..1867091d93 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -66,6 +66,7 @@ class EPCManagement(): self.containerPrefix = 'prod' self.mmeConfFile = 'mme.conf' self.yamlPath = '' + self.isMagmaUsed = False #----------------------------------------------------------- @@ -164,7 +165,15 @@ class EPCManagement(): if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) - mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-oai-mme', '\$', 5) + self.isMagmaUsed = False + mySSH.command('docker ps -a', '\$', 5) + result = re.search('magma', mySSH.getBefore()) + if result is not None: + self.isMagmaUsed = True + if self.isMagmaUsed: + mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-magma-mme', '\$', 5) + else: + mySSH.command('docker inspect --format="MME_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ' + self.containerPrefix + '-oai-mme', '\$', 5) result = re.search('MME_IP_ADDR = (?P[0-9\.]+)', mySSH.getBefore()) if result is not None: self.MmeIPAddress = result.group('mme_ip_addr') @@ -289,7 +298,15 @@ class EPCManagement(): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5) + self.isMagmaUsed = False + mySSH.command('docker ps -a', '\$', 5) + result = re.search('magma', mySSH.getBefore()) + if result is not None: + self.isMagmaUsed = True + if self.isMagmaUsed: + mySSH.command('docker top ' + self.containerPrefix + '-magma-mme', '\$', 5) + else: + mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5) else: mySSH.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -489,6 +506,12 @@ class EPCManagement(): HTML.CreateHtmlTabFooter(False) sys.exit('docker-compose not installed on ' + self.IPAddress) + # Checking if it is a MAGMA deployment + self.isMagmaUsed = False + if os.path.isfile('./' + self.yamlPath + '/redis_extern.conf'): + self.isMagmaUsed = True + logging.debug('MAGMA MME is used!') + mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5) mySSH.command('if [ -d ' + self.SourceCodePath + '/logs ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/logs ; fi', '\$', 5) mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts ' + self.SourceCodePath + '/logs', '\$', 5) @@ -500,13 +523,19 @@ class EPCManagement(): # - docker-compose config | grep container_name mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/docker-compose.yml', self.SourceCodePath + '/scripts') - mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/entrypoint.sh', self.SourceCodePath + '/scripts') - mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme.conf', self.SourceCodePath + '/scripts') - mySSH.command('chmod 775 entrypoint.sh', '\$', 60) + if self.isMagmaUsed: + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/entrypoint.sh', self.SourceCodePath + '/scripts') + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme.conf', self.SourceCodePath + '/scripts') + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme_fd.sprint.conf', self.SourceCodePath + '/scripts') + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/redis_extern.conf', self.SourceCodePath + '/scripts') + mySSH.command('chmod a+x ' + self.SourceCodePath + '/scripts/entrypoint.sh', '\$', 5) + else: + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/entrypoint.sh', self.SourceCodePath + '/scripts') + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/mme.conf', self.SourceCodePath + '/scripts') + mySSH.command('chmod 775 entrypoint.sh', '\$', 60) mySSH.command('wget --quiet --tries=3 --retry-connrefused https://raw.githubusercontent.com/OPENAIRINTERFACE/openair-hss/develop/src/hss_rel14/db/oai_db.cql', '\$', 30) mySSH.command('docker-compose down', '\$', 60) mySSH.command('docker-compose up -d db_init', '\$', 60) - # databases take time... time.sleep(10) cnt = 0 @@ -528,8 +557,12 @@ class EPCManagement(): # deploying EPC cNFs mySSH.command('docker-compose up -d oai_spgwu', '\$', 60) - listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' - expectedHealthyContainers = 5 + if self.isMagmaUsed: + listOfContainers = 'prod-cassandra prod-oai-hss prod-magma-mme prod-oai-spgwc prod-oai-spgwu-tiny prod-redis' + expectedHealthyContainers = 6 + else: + listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' + expectedHealthyContainers = 5 # Checking for additional services mySSH.command('docker-compose config', '\$', 5) @@ -560,7 +593,10 @@ class EPCManagement(): logging.debug(' -- ' + str(startingNb) + ' still starting container(s)') if healthyNb == expectedHealthyContainers: mySSH.command('docker exec -d prod-oai-hss /bin/bash -c "nohup tshark -i any -f \'port 9042 or port 3868\' -w /tmp/hss_check_run.pcap 2>&1 > /dev/null"', '\$', 5) - mySSH.command('docker exec -d prod-oai-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10) + if self.isMagmaUsed: + mySSH.command('docker exec -d prod-magma-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10) + else: + mySSH.command('docker exec -d prod-oai-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10) mySSH.command('docker exec -d prod-oai-spgwc /bin/bash -c "nohup tshark -i any -f \'port 2123 or port 8805\' -w /tmp/spgwc_check_run.pcap 2>&1 > /dev/null"', '\$', 10) # on SPGW-U, not capturing on SGI to avoid huge file mySSH.command('docker exec -d prod-oai-spgwu-tiny /bin/bash -c "nohup tshark -i any -f \'port 8805\' -w /tmp/spgwu_check_run.pcap 2>&1 > /dev/null"', '\$', 10) @@ -578,24 +614,45 @@ class EPCManagement(): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) + # Checking if it is a MAGMA deployment. + mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) + mySSH.command('docker-compose ps -a', '\$', 5) + self.isMagmaUsed = False + result = re.search('magma', mySSH.getBefore()) + if result is not None: + self.isMagmaUsed = True + logging.debug('MAGMA MME is used!') # Recovering logs and pcap files mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5) mySSH.command('docker exec -it prod-oai-hss /bin/bash -c "killall --signal SIGINT oai_hss tshark"', '\$', 5) - mySSH.command('docker exec -it prod-oai-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) + if self.isMagmaUsed: + mySSH.command('docker exec -it prod-magma-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) + else: + mySSH.command('docker exec -it prod-oai-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) mySSH.command('docker exec -it prod-oai-spgwc /bin/bash -c "killall --signal SIGINT oai_spgwc tshark"', '\$', 5) mySSH.command('docker exec -it prod-oai-spgwu-tiny /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) mySSH.command('docker logs prod-oai-hss > hss_' + self.testCase_id + '.log', '\$', 5) - mySSH.command('docker logs prod-oai-mme > mme_' + self.testCase_id + '.log', '\$', 5) + if self.isMagmaUsed: + mySSH.command('docker cp --follow-link prod-magma-mme:/var/log/mme.log mme_' + self.testCase_id + '.log', '\$', 15) + else: + mySSH.command('docker logs prod-oai-mme > mme_' + self.testCase_id + '.log', '\$', 5) mySSH.command('docker logs prod-oai-spgwc > spgwc_' + self.testCase_id + '.log', '\$', 5) mySSH.command('docker logs prod-oai-spgwu-tiny > spgwu_' + self.testCase_id + '.log', '\$', 5) mySSH.command('docker cp prod-oai-hss:/tmp/hss_check_run.pcap hss_' + self.testCase_id + '.pcap', '\$', 60) - mySSH.command('docker cp prod-oai-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60) + if self.isMagmaUsed: + mySSH.command('docker cp prod-magma-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60) + else: + mySSH.command('docker cp prod-oai-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60) mySSH.command('docker cp prod-oai-spgwc:/tmp/spgwc_check_run.pcap spgwc_' + self.testCase_id + '.pcap', '\$', 60) mySSH.command('docker cp prod-oai-spgwu-tiny:/tmp/spgwu_check_run.pcap spgwu_' + self.testCase_id + '.pcap', '\$', 60) # Remove all mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) - listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' - nbContainers = 5 + if self.isMagmaUsed: + listOfContainers = 'prod-cassandra prod-oai-hss prod-magma-mme prod-oai-spgwc prod-oai-spgwu-tiny prod-redis' + nbContainers = 6 + else: + listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' + nbContainers = 5 # Checking for additional services mySSH.command('docker-compose config', '\$', 5) configResponse = mySSH.getBefore() diff --git a/ci-scripts/xml_files/fr1_lte_2x2_quectel.xml b/ci-scripts/xml_files/fr1_lte_2x2_quectel.xml index 86d9e5d5f0..03d474aef0 100644 --- a/ci-scripts/xml_files/fr1_lte_2x2_quectel.xml +++ b/ci-scripts/xml_files/fr1_lte_2x2_quectel.xml @@ -59,7 +59,7 @@ Initialize_eNB Initialize eNB - -O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + -O ci-scripts/conf_files/enb.band38.lte_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 0 0 lte diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml index 12a6186403..16dfd1e377 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml @@ -21,10 +21,10 @@ --> - TEST-NSA-FR1-TM2 + TEST-NSA-FR1-TM2-Tab1 NSA 2x2 Ping DL UL with QUECTEL tasks - 1 + 5 030000 040000 @@ -85,7 +85,7 @@ IdleSleep Sleep - 5 + 60 diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml new file mode 100644 index 0000000000..ebb5c880d5 --- /dev/null +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml @@ -0,0 +1,145 @@ + + + TEST-NSA-FR1-TM2-Tab2 + NSA 2x2 Attach-Detach with QUECTEL + tasks + 5 + + 031000 + 041000 + 000002 + 010000 + 000001 + 050000 + 000002 + 010004 + 000002 + 010003 + 000001 + 050000 + 000002 + 010004 + 000002 + 010003 + 000001 + 050000 + 000002 + 010002 + 080001 + 080000 + + + + + Initialize_UE + Initialize Quectel + nrmodule2_quectel + yes + + + + + Terminate_UE + Terminate Quectel + nrmodule2_quectel + + + + Attach_UE + Attach Quectel + nrmodule2_quectel + + + + Detach_UE + Detach Quectel + nrmodule2_quectel + + + + + Initialize_eNB + Initialize eNB + -O ci-scripts/conf_files/enb.band38.nsa_2x2.100PRB.usrpn310.conf --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + 0 + 0 + lte + yes + yes + 192.168.18.241 + + + + + Initialize_eNB + Initialize gNB + -O ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf -q --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + 1 + 1 + nr + yes + 192.168.18.240 + + + + IdleSleep + Sleep + 60 + + + + IdleSleep + Sleep + 20 + + + + + Ping + Ping: 20pings in 20sec + nrmodule2_quectel + -c 20 + 5 + + + + + + Terminate_eNB + Terminate eNB + 0 + 0 + lte + + + + Terminate_eNB + Terminate gNB + 1 + 1 + nr + + + + diff --git a/ci-scripts/xml_files/fr1_oai_cn_deploy.xml b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml index 1ccc952c56..26dbebc329 100644 --- a/ci-scripts/xml_files/fr1_oai_cn_deploy.xml +++ b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml @@ -33,7 +33,7 @@ Deploy_EPC Deploy all EPC containers - yaml_files/fr1_epc_20897 + yaml_files/magma_nsa_20897 diff --git a/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml b/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml new file mode 100644 index 0000000000..df14e900e7 --- /dev/null +++ b/ci-scripts/yaml_files/magma_nsa_20897/docker-compose.yml @@ -0,0 +1,198 @@ +version: '3.8' + +services: + cassandra: + image: cassandra:2.1 + container_name: prod-cassandra + networks: + private_net: + ipv4_address: 192.168.68.2 + environment: + CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster" + CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch + healthcheck: + test: /bin/bash -c "nodetool status" + interval: 10s + timeout: 5s + retries: 5 + + db_init: + image: cassandra:2.1 + container_name: prod-db-init + depends_on: [cassandra] + deploy: + restart_policy: + condition: on-failure + max_attempts: 10 + networks: + private_net: + ipv4_address: 192.168.68.4 + volumes: + - ./oai_db.cql:/home/oai_db.cql + entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'" + + oai_hss: + image: oai-hss:production + container_name: prod-oai-hss + privileged: true + depends_on: [cassandra] + networks: + private_net: + ipv4_address: 192.168.68.3 + public_net: + ipv4_address: 192.168.61.194 + environment: + TZ: Europe/Paris + REALM: openairinterface.org + HSS_FQDN: hss.openairinterface.org + PREFIX: /openair-hss/etc + cassandra_Server_IP: 192.168.68.2 + OP_KEY: 1006020f0a478bf6b699f15c062e42b3 + LTE_K: FEC86BA6EB707ED08905757B1BB44B8F + APN1: oai.ipv4 + APN2: oai2.ipv4 + FIRST_IMSI: 208970100001127 + NB_USERS: 10 + healthcheck: + test: /bin/bash -c "pgrep oai_hss" + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:6.0.5 + container_name: prod-redis + privileged: true + networks: + public_net: + ipv4_address: 192.168.61.198 + volumes: + - ./redis_extern.conf:/usr/local/etc/redis/redis.conf + entrypoint: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf" + healthcheck: + test: /bin/bash -c "redis-cli -h 192.168.61.198 -p 6380 ping" + interval: 10s + timeout: 5s + retries: 5 + + magma_mme: + image: magma-mme:production + container_name: prod-magma-mme + hostname: mme + privileged: true + depends_on: [oai_hss, redis] + networks: + public_net: + ipv4_address: 192.168.61.195 + environment: + TZ: Europe/Paris + REALM: openairinterface.org + PREFIX: /openair-mme/etc + HSS_HOSTNAME: hss + HSS_FQDN: hss.openairinterface.org + HSS_REALM: openairinterface.org + MME_FQDN: mme.openairinterface.org + FEATURES: mme_oai + volumes: + - ./mme_fd.sprint.conf:/magma-mme/etc/mme_fd.conf.tmplt + - ./mme.conf:/magma-mme/etc/mme.conf + - ./entrypoint.sh:/magma-mme/bin/entrypoint.sh + entrypoint: /bin/bash -c "/magma-mme/bin/entrypoint.sh" + healthcheck: + test: /bin/bash -c "pgrep oai_mme" + interval: 10s + timeout: 5s + retries: 5 + + oai_spgwc: + image: oai-spgwc:production + privileged: true + depends_on: [magma_mme] + container_name: prod-oai-spgwc + networks: + public_net: + ipv4_address: 192.168.61.196 + environment: + TZ: Europe/Paris + SGW_INTERFACE_NAME_FOR_S11: eth0 + PGW_INTERFACE_NAME_FOR_SX: eth0 + DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129 + DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4 + PUSH_PROTOCOL_OPTION: 'true' + APN_NI_1: oai.ipv4 + APN_NI_2: oai2.ipv4 + DEFAULT_APN_NI_1: oai.ipv4 + UE_IP_ADDRESS_POOL_1: '12.1.1.2 - 12.1.1.254' + UE_IP_ADDRESS_POOL_2: '12.0.0.2 - 12.0.0.254' + MCC: '208' + MNC: '97' + MNC03: '097' + TAC: 1 + GW_ID: 1 + REALM: openairinterface.org + UE_MTU_IPV4: 1500 + healthcheck: + test: /bin/bash -c "pgrep oai_spgwc" + interval: 10s + timeout: 5s + retries: 5 + + oai_spgwu: + image: oai-spgwu-tiny:production + privileged: true + container_name: prod-oai-spgwu-tiny + depends_on: [oai_spgwc] + networks: + public_net: + ipv4_address: 192.168.61.197 + environment: + TZ: Europe/Paris + PID_DIRECTORY: /var/run + INSTANCE: 1 + SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0 + PGW_INTERFACE_NAME_FOR_SGI: eth0 + SGW_INTERFACE_NAME_FOR_SX: eth0 + SPGWC0_IP_ADDRESS: 192.168.61.196 + NETWORK_UE_IP: '12.1.1.0/24' + NETWORK_UE_NAT_OPTION: 'yes' + MCC: '208' + MNC: '97' + MNC03: '097' + TAC: 1 + GW_ID: 1 + REALM: openairinterface.org + healthcheck: + test: /bin/bash -c "pgrep oai_spgwu" + interval: 10s + timeout: 5s + retries: 5 + + trf_gen: + image: trf-gen:production + privileged: true + container_name: prod-trf-gen + networks: + public_net: + ipv4_address: 192.168.61.200 + entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.197 dev eth0; sleep infinity" + healthcheck: + test: /bin/bash -c "ip route | grep '12.1.1.0'" + interval: 10s + timeout: 5s + retries: 5 + +networks: + private_net: + name: prod-oai-private-net + ipam: + config: + - subnet: 192.168.68.0/26 + driver_opts: + com.docker.network.bridge.name: "oai-priv-net" + public_net: + name: prod-oai-public-net + ipam: + config: + - subnet: 192.168.61.192/26 + driver_opts: + com.docker.network.bridge.name: "oai-pub-net" diff --git a/ci-scripts/yaml_files/magma_nsa_20897/entrypoint.sh b/ci-scripts/yaml_files/magma_nsa_20897/entrypoint.sh new file mode 100755 index 0000000000..859ff7d98f --- /dev/null +++ b/ci-scripts/yaml_files/magma_nsa_20897/entrypoint.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +INSTANCE=1 +PREFIX='/magma-mme/etc' +MY_REALM='openairinterface.org' + +declare -A MME_CONF + +pushd $PREFIX +MME_CONF[@MME_S6A_IP_ADDR@]="192.168.61.195" +MME_CONF[@INSTANCE@]=$INSTANCE +MME_CONF[@PREFIX@]=$PREFIX +MME_CONF[@REALM@]=$MY_REALM +MME_CONF[@MME_FQDN@]="mme.${MME_CONF[@REALM@]}" +MME_CONF[@HSS_HOSTNAME@]='hss' +MME_CONF[@HSS_FQDN@]="${MME_CONF[@HSS_HOSTNAME@]}.${MME_CONF[@REALM@]}" +MME_CONF[@HSS_IP_ADDR@]="192.168.61.194" + +cp mme_fd.conf.tmplt $PREFIX/mme_fd.conf + +for K in "${!MME_CONF[@]}"; do + egrep -lRZ "$K" $PREFIX/mme_fd.conf | xargs -0 -l sed -i -e "s|$K|${MME_CONF[$K]}|g" + ret=$?;[[ ret -ne 0 ]] && echo "Tried to replace $K with ${MME_CONF[$K]}" +done + +sed -i -e "s@etc/freeDiameter@etc@" /magma-mme/etc/mme_fd.conf +sed -i -e "s@bind: 127.0.0.1@bind: 192.168.61.198@" /etc/magma/redis.yml +# Generate freeDiameter certificate +popd +cd /magma-mme/scripts +./check_mme_s6a_certificate $PREFIX mme.${MME_CONF[@REALM@]} + +cd /magma-mme +nohup /magma-mme/bin/sctpd > /var/log/sctpd.log 2>&1 & +sleep 5 +/magma-mme/bin/oai_mme -c /magma-mme/etc/mme.conf diff --git a/ci-scripts/yaml_files/magma_nsa_20897/mme.conf b/ci-scripts/yaml_files/magma_nsa_20897/mme.conf new file mode 100644 index 0000000000..e41fbe6304 --- /dev/null +++ b/ci-scripts/yaml_files/magma_nsa_20897/mme.conf @@ -0,0 +1,136 @@ +# generated by generate_mme_config_script.py +MME : +{ + REALM = "openairinterface.org" + PID_DIRECTORY = "/var/run"; + MAXENB = 8; # power of 2 + MAXUE = 16; # power of 2 + RELATIVE_CAPACITY = 10; + + EMERGENCY_ATTACH_SUPPORTED = "no"; + UNAUTHENTICATED_IMSI_SUPPORTED = "no"; + + # EPS network feature support + EPS_NETWORK_FEATURE_SUPPORT_IMS_VOICE_OVER_PS_SESSION_IN_S1 = "no"; # DO NOT CHANGE + EPS_NETWORK_FEATURE_SUPPORT_EMERGENCY_BEARER_SERVICES_IN_S1_MODE = "no"; # DO NOT CHANGE + EPS_NETWORK_FEATURE_SUPPORT_LOCATION_SERVICES_VIA_EPC = "no"; # DO NOT CHANGE + EPS_NETWORK_FEATURE_SUPPORT_EXTENDED_SERVICE_REQUEST = "no"; # DO NOT CHANGE + + # Display statistics about whole system (expressed in seconds) + MME_STATISTIC_TIMER = 10; + IP_CAPABILITY = "IPV4"; # UE PDN_TYPE + USE_STATELESS = ""; + + INTERTASK_INTERFACE : + { + # max queue size per task + ITTI_QUEUE_SIZE = 2000000; + }; + + S6A : + { + S6A_CONF = "/magma-mme/etc/mme_fd.conf"; # YOUR MME freeDiameter config file path + HSS_HOSTNAME = "hss.openairinterface.org"; + HSS_REALM = "openairinterface.org"; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 8; + SCTP_OUTSTREAMS = 8; + }; + + # ------- S1AP definitions + S1AP : + { + # outcome drop timer value (seconds) + S1AP_OUTCOME_TIMER = 10; + }; + + # ------- MME served GUMMEIs + GUMMEI_LIST = ( + { MCC="208" ; MNC="97"; MME_GID="32768" ; MME_CODE="3"; } + ); + + # ------- MME served TAIs + TAI_LIST = ( + {MCC="208" ; MNC="97"; TAC = "1"; }, + {MCC="208" ; MNC="97"; TAC = "2"; }, + {MCC="208" ; MNC="97"; TAC = "3"; } + ); + + TAC_LIST = ( + {MCC="208" ; MNC="97"; TAC = "1"; } + ); + + CSFB : + { + NON_EPS_SERVICE_CONTROL = "OFF"; + CSFB_MCC = "208"; + CSFB_MNC = "97"; + LAC = "1"; + }; + NAS : + { + ORDERED_SUPPORTED_INTEGRITY_ALGORITHM_LIST = [ "EIA2" , "EIA1" , "EIA0" ]; + ORDERED_SUPPORTED_CIPHERING_ALGORITHM_LIST = [ "EEA0" , "EEA1" , "EEA2" ]; + T3402 = 1 # in minutes (default is 12 minutes) + T3412 = 54 # in minutes (default is 54 minutes, network dependent) + T3422 = 6 # in seconds (default is 6s) + T3450 = 6 # in seconds (default is 6s) + T3460 = 6 # in seconds (default is 6s) + T3470 = 6 # in seconds (default is 6s) + T3485 = 8 # UNUSED in seconds (default is 8s) + T3486 = 8 # UNUSED in seconds (default is 8s) + T3489 = 4 # UNUSED in seconds (default is 4s) + T3495 = 8 # UNUSED in seconds (default is 8s) + }; + + SGS : + { + TS6_1 = 10 # in seconds (default is 10s) + TS8 = 4 # in seconds (default is 4s) + TS9 = 2 # in seconds (default is 4s) + TS10 = 4 # in seconds (default is 4s) + TS13 = 4 # in seconds (default is 4s) + }; + + NETWORK_INTERFACES : + { + MME_INTERFACE_NAME_FOR_S1_MME = "eth0"; + MME_IPV4_ADDRESS_FOR_S1_MME = "192.168.61.195/24"; + MME_INTERFACE_NAME_FOR_S11_MME = "eth0"; + MME_IPV4_ADDRESS_FOR_S11_MME = "192.168.61.195/24"; + MME_PORT_FOR_S11_MME = 2123; + }; + + LOGGING : + { + OUTPUT = "CONSOLE"; + THREAD_SAFE = "no"; + COLOR = "no"; + + SCTP_LOG_LEVEL = "ERROR"; + GTPV1U_LOG_LEVEL = "INFO"; + SPGW_APP_LOG_LEVEL = "INFO"; + UDP_LOG_LEVEL = "INFO"; + S1AP_LOG_LEVEL = "DEBUG"; + NAS_LOG_LEVEL = "INFO"; + MME_APP_LOG_LEVEL = "DEBUG"; + GTPV2C_LOG_LEVEL = "INFO"; + S11_LOG_LEVEL = "DEBUG"; + S6A_LOG_LEVEL = "DEBUG"; + UTIL_LOG_LEVEL = "INFO"; + MSC_LOG_LEVEL = "ERROR"; + ITTI_LOG_LEVEL = "ERROR"; + MME_SCENARIO_PLAYER_LOG_LEVEL = "ERROR"; + ASN1_VERBOSITY = "INFO"; + }; + + S-GW : + { + SGW_IPV4_ADDRESS_FOR_S11 = "192.168.61.196"; + }; +}; diff --git a/ci-scripts/yaml_files/magma_nsa_20897/mme_fd.sprint.conf b/ci-scripts/yaml_files/magma_nsa_20897/mme_fd.sprint.conf new file mode 100644 index 0000000000..6f87ed8c2b --- /dev/null +++ b/ci-scripts/yaml_files/magma_nsa_20897/mme_fd.sprint.conf @@ -0,0 +1,169 @@ +# -------- Local --------- + +# Uncomment if the framework cannot resolv it. +Identity = "@MME_FQDN@"; +Realm = "@REALM@"; + +# TLS configuration (see previous section) +TLS_Cred = "@PREFIX@/freeDiameter/mme.cert.pem", + "@PREFIX@/freeDiameter/mme.key.pem"; +TLS_CA = "@PREFIX@/freeDiameter/mme.cacert.pem"; + +# Disable use of TCP protocol (only listen and connect in SCTP) +# Default : TCP enabled +No_SCTP; + +# This option is ignored if freeDiameter is compiled with DISABLE_SCTP option. +# Prefer TCP instead of SCTP for establishing new connections. +# This setting may be overwritten per peer in peer configuration blocs. +# Default : SCTP is attempted first. +Prefer_TCP; + + +No_IPv6; + +# Overwrite the number of SCTP streams. This value should be kept low, +# especially if you are using TLS over SCTP, because it consumes a lot of +# resources in that case. See tickets 19 and 27 for some additional details on +# this. +# Limit the number of SCTP streams +SCTP_streams = 3; + + +# By default, freeDiameter acts as a Diameter Relay Agent by forwarding all +# messages it cannot handle locally. This parameter disables this behavior. +NoRelay; + +# Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA exchange is completed +# on the unsecure connection. The alternative is RFC6733 mechanism, where TLS protects also the +# CER/CEA exchange on a dedicated secure port. +# This parameter only affects outgoing connections. +# The setting can be also defined per-peer (see Peers configuration section). +# Default: use RFC6733 method with separate port for TLS. + +#TLS_old_method; + +AppServThreads = 4; + +# Specify the addresses on which to bind the listening server. This must be +# specified if the framework is unable to auto-detect these addresses, or if the +# auto-detected values are incorrect. Note that the list of addresses is sent +# in CER or CEA message, so one should pay attention to this parameter if some +# adresses should be kept hidden. +ListenOn = "@MME_S6A_IP_ADDR@"; + +Port = 3870; +SecPort = 5870; + +# -------- Extensions --------- + +# Uncomment (and create rtd.conf) to specify routing table for this peer. +#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx" : "rtd.conf"; + +#LoadExtension = "/usr/local/lib/freeDiameter/_sample.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/app_acct.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/app_diameap.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/app_radgw.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/app_redirect.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/app_sip.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dbg_interactive.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dbg_monitor.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_dumps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dbg_msg_timings.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dbg_rt.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_3gpp2_avps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_CreditControl.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_CxDx.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Gx.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_NAS.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Ro.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rx.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_S6mS6n.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_SGd.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_SLh.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sd.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Sh.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_T4.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_T6aT6bT7.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Tsp.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_3gpp.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_dcca_starent.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_draftload_avps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_eap.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_etsi283034_avps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_legacy_xml.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6a.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_mip6i.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_nas_mipv6.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_nasreq.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4004_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4006bis_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4072_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc4590_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5447_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5580_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5777_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc5778_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6734_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc6942_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7155_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7683_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_rfc7944_avps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_sip.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29061_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29128_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29154_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29173_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29212_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29214_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29215_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29217_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29229_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29272_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29273_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29329_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29336_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29337_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29338_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29343_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29344_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29345_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29368_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts29468_avps.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_ts32299_avps.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_busypeers.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_default.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_ereg.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_ignore_dh.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_load_balance.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_randomize.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/rt_redirect.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_acct.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_app.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_hss.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_netemul.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_rt_any.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/test_sip.fdx"; +#LoadExtension = "/usr/local/lib/freeDiameter/dict_Rf.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_S6as6d.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_S6t.fdx"; +LoadExtension = "/usr/local/lib/freeDiameter/dict_S6c.fdx"; + + +# -------- Peers --------- + +# The framework will actively attempt to establish and maintain a connection +# with the peers listed here. +# For only accepting incoming connections, see the acl_wl.fx extension. + +# ConnectPeer +# Declare a remote peer to which this peer must maintain a connection. +# In addition, this allows specifying non-default parameters for this peer only +# (for example disable SCTP with this peer, or use RFC3588-flavour TLS). +# Note that by default, if a peer is not listed as a ConnectPeer entry, an +# incoming connection from this peer will be rejected. If you want to accept +# incoming connections from other peers, see the acl_wl.fdx? extension which +# allows exactly this. + +ConnectPeer= "@HSS_FQDN@" { ConnectTo = "@HSS_IP_ADDR@"; No_SCTP ; No_IPv6; Prefer_TCP; No_TLS; port = 3868;}; diff --git a/ci-scripts/yaml_files/magma_nsa_20897/redis_extern.conf b/ci-scripts/yaml_files/magma_nsa_20897/redis_extern.conf new file mode 100644 index 0000000000..565524080a --- /dev/null +++ b/ci-scripts/yaml_files/magma_nsa_20897/redis_extern.conf @@ -0,0 +1,33 @@ +# +# Copyright (c) 2016-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +# Jinja template for Redis configuration +# See the default config file for options and explanations: +# https://github.com/antirez/redis/blob/unstable/redis.conf + +# TODO: make sensible, production-aware config decisions + +bind 192.168.61.198 +port 6380 + +daemonize no +loglevel notice + +timeout 0 +databases 1 + +dbfilename redis_dump.rdb +dir /data + +# Save the DB on disk + +save 900 1 + +save 300 10 + +save 60 1000 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 9592334125..b18f92f9c2 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -309,6 +309,7 @@ endif() # # add autotools definitions that were maybe used! + add_definitions("-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP") set(commonOpts "-pipe -Wno-packed-bitfield-compat -fPIC -Wall -fno-strict-aliasing -rdynamic") @@ -318,11 +319,7 @@ set(CMAKE_C_FLAGS set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} ${commonOpts} -std=c++11") -# cuda compiler bug (limitation) on complex macro definition -if (CUDA_FOUND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCUDA_FLAG") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCUDA_FLAG") -endif() + if (SANITIZE_ADDRESS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-common") @@ -332,11 +329,11 @@ endif () add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ggdb3 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ggdb2 -Wl,-rpath -Wl,${CMAKE_CURRENT_BINARY_DIR}") ######################### # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files -set(debugOpt "-ggdb3 -DMALLOC_CHECK_=3 -fno-delete-null-pointer-checks") +set(debugOpt "-ggdb2 -DMALLOC_CHECK_=3 -fno-delete-null-pointer-checks") set(CMAKE_C_FLAGS_DEBUG "${debugOpt} -O0") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${debugOpt} -O2") set(CMAKE_C_FLAGS_RELEASE "-O3") @@ -1590,6 +1587,16 @@ set(PHY_LDPC_OPTIM8SEGMULTI_SRC ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c ) +set(PHY_LDPC_CUDA_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c +) + +set(PHY_LDPC_CL_SRC + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c +) + set(PHY_NR_CODINGIF ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c; ) @@ -1597,8 +1604,18 @@ set(PHY_NR_CODINGIF add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} ) add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} ) add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} ) +add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} ) +target_link_libraries(ldpc_cl OpenCL) + +if (CUDA_FOUND) + cuda_add_library(ldpc_cuda MODULE ${PHY_LDPC_CUDA_SRC} ) + set_target_properties(ldpc_cuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON) +# CUDA_ADD_CUFFT_TO_TARGET(ldpc_cuda) +endif (CUDA_FOUND) + add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) + add_library(coding MODULE ${PHY_TURBOSRC} ) add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c ) @@ -1744,7 +1761,6 @@ set(PHY_SRC_UE set(PHY_NR_SRC_COMMON ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c - ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools_common.c ) set(PHY_NR_SRC @@ -1983,6 +1999,10 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) +set(NR_SDAP_SRC + ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_gnb.c + ) + set(L2_SRC ${PDCP_DIR}/pdcp.c ${PDCP_DIR}/pdcp_fifo.c @@ -2026,6 +2046,7 @@ set(L2_LTE_SRC set(L2_NR_SRC ${NR_RLC_SRC} ${NR_PDCP_SRC} + ${NR_SDAP_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -2061,6 +2082,7 @@ set(L2_RRC_SRC_UE set(NR_L2_SRC_UE ${NR_RLC_SRC} ${NR_PDCP_SRC} + ${NR_SDAP_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c @@ -3113,7 +3135,11 @@ target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) - +if (CUDA_FOUND) + add_dependencies( nr-uesoftmodem ldpc_cuda) + add_dependencies( nr-softmodem ldpc_cuda) + add_dependencies( ocp-gnb ldpc_cuda) +endif (CUDA_FOUND) ###################################" # Addexecutables for tests #################################### @@ -3173,46 +3199,18 @@ target_link_libraries(smallblocktest m pthread ${ATLAS_LIBRARIES} dl ) -if (CUDA_FOUND) -################################################### -# For CUDA library -################################################### - CUDA_ADD_LIBRARY(LDPC_CU - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu - ) - CUDA_ADD_CUFFT_TO_TARGET(LDPC_CU) - cuda_add_executable(ldpctest - ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ) - target_link_libraries(ldpctest -ldl - -Wl,--start-group - LDPC_CU UTIL SIMU PHY_NR CONFIG_LIB - -Wl,--end-group - m pthread ${ATLAS_LIBRARIES} dl - ) +add_executable(ldpctest + ${PHY_NR_CODINGIF} + ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) -else (CUDA_FOUND) - add_executable(ldpctest - ${PHY_NR_CODINGIF} - ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ) - -endif () - - -# add_executable(ldpctest - # ${PHY_NR_CODINGIF} - # ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c - # ${T_SOURCE} - # ${SHLIB_LOADER_SOURCES} - # ) add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) - +if (CUDA_FOUND) + add_dependencies( ldpctest ldpc_cuda) +endif (CUDA_FOUND) target_link_libraries(ldpctest -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index c9390d67ce..c68ca8a553 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -551,7 +551,7 @@ function main() { if [ "$HW" == "OAI_USRP" ] ; then echo_info "installing packages for USRP support" check_install_usrp_uhd_driver - if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then + if [ ! -v BUILD_UHD_FROM_SOURCE ] && [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then install_usrp_uhd_driver $UHD_IMAGES_DIR fi fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index d3fcf615e2..c5cc9d054d 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -317,19 +317,30 @@ install_usrp_uhd_driver_from_source(){ echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log " ( pushd /tmp - echo "Downloading UHD driver" + echo "Cloning UHD driver repository" rm -rf /tmp/uhd git clone https://github.com/EttusResearch/uhd.git cd uhd - git checkout tags/v4.0.0.0 + if [[ -v UHD_VERSION ]]; then + git checkout tags/v${UHD_VERSION} + else + git checkout tags/v4.0.0.0 + fi mkdir -p host/build - cd host/build - $CMAKE ../ + cd host/build || true + $CMAKE ../ -GNinja echo "Compiling UHD" - make -j`nproc` - make test - $SUDO make install + ninja + $SUDO ninja install $SUDO ldconfig -v + if [ $IS_CONTAINER -eq 0 ]; then + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + $SUDO /usr/local/lib/uhd/utils/uhd_images_downloader.py + fi + if [[ "$OS_DISTRO" == "rhel" ]]; then + $SUDO /usr/local/lib64/uhd/utils/uhd_images_downloader.py + fi + fi popd rm -rf /tmp/uhd ) >& $uhd_install_log @@ -338,10 +349,26 @@ install_usrp_uhd_driver_from_source(){ check_install_usrp_uhd_driver(){ if [[ "$OS_DISTRO" == "ubuntu" ]]; then #first we remove old installation - $SUDO apt-get remove -y uhd || true - $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y || true + $SUDO apt-get remove uhd -y || true + $SUDO apt-get remove uhd-host -y || true + $SUDO apt-get remove libuhd-dev -y || true + $SUDO apt-get remove libuhd003 -y || true + $SUDO apt-get remove libuhd3.13.1 -y || true + $SUDO apt-get remove libuhd3.14.0 -y || true + $SUDO apt-get remove libuhd3.14.1 -y || true + $SUDO apt-get remove libuhd3.15.0 -y || true + local distribution=$(get_distribution_release) + if [[ "$distribution" == "ubuntu18.04" ]]; then + $SUDO apt-get remove libuhd4.0.0 -y || true + $SUDO apt-get remove libuhd4.1.0 -y || true + fi v=$(lsb_release -cs) $SUDO apt-add-repository --remove "deb http://files.ettus.com/binaries/uhd/repo/uhd/ubuntu/$v $v main" + if [[ -v BUILD_UHD_FROM_SOURCE ]]; then + $SUDO apt-get install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-setuptools ninja-build + install_usrp_uhd_driver_from_source + return + fi # The new USRP repository # Raphael Defosseux: Adding a loop on adding PPA because in CI the gpg key retrieve may # timeout due to proxy / network latencies in Eurecom on VM @@ -361,7 +388,12 @@ check_install_usrp_uhd_driver(){ done $SUDO apt-get update $SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev - $SUDO apt-get -y install libuhd-dev libuhd003 uhd-host + if [[ "$distribution" == "ubuntu16.04" ]]; then + $SUDO apt-get -y install libuhd-dev libuhd3.15.0 uhd-host + fi + if [[ "$distribution" == "ubuntu18.04" ]]; then + $SUDO apt-get -y install libuhd-dev libuhd4.1.0 uhd-host + fi elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [ $IS_CONTAINER -eq 0 ] then @@ -692,6 +724,7 @@ check_install_oai_software() { build-essential \ $CMAKE \ cmake-curses-gui \ + curl \ ninja-build \ doxygen \ doxygen-gui \ diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index a6e59c5938..41a0807a24 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -10,6 +10,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) * If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields). * looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers +```c +int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf) +``` +Allows loading a specific library version, as specified by the `version` parameter. When version is not NULL the version that is possibly specified as a config module parameter is ignored. This call has been introduced for phy simulators executables which do not use the config module. It is used, for example, by the ldcp initialization (`load_nrLDPClib` function in [nrLDPC_load.c](../../../../../openair1/PHY/CODING/nrLDPC_load.c) to allow the `ldpctest` simulator to select the cuda accelerated ldcp implementation. `load_module_shlib` is just a define macro to switch to a `load_module_version_shlib` call, adding a NULL pointer for the version parameter. ```c void * get_shlibmodule_fptr(char *modname, char *fname) diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index a4b4742c94..2b0d339358 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -63,7 +63,7 @@ void loader_init(void) { } /* build the full shared lib name from the module name */ -char *loader_format_shlibpath(char *modname) +char *loader_format_shlibpath(char *modname, char *version) { char *tmpstr; @@ -97,7 +97,10 @@ int ret; shlibpath = loader_data.shlibpath ; } /* no specific shared lib version */ - if (shlibversion == NULL) { + if (version != NULL) { // version specified as a function parameter + shlibversion=version; + } + if (shlibversion == NULL) { // no specific version specified, neither as a config param or as a function param shlibversion = "" ; } /* alloc memory for full module shared lib file name */ @@ -118,7 +121,7 @@ int ret; return tmpstr; } -int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg) +int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *autoinit_arg) { void *lib_handle = NULL; initfunc_t fpi; @@ -138,7 +141,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void * loader_init(); } - shlib_path = loader_format_shlibpath(modname); + shlib_path = loader_format_shlibpath(modname, version); for (int i = 0; i < loader_data.numshlibs; i++) { if (strcmp(loader_data.shlibs[i].name, modname) == 0) { diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h index 685b3d1b65..0e80a5353c 100644 --- a/common/utils/load_module_shlib.h +++ b/common/utils/load_module_shlib.h @@ -84,10 +84,11 @@ loader_data_t loader_data; /*-------------------------------------------------------------------------------------------------------------*/ #else /* LOAD_MODULE_SHLIB_MAIN */ -extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf, void *initfunc_arg); + +extern int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *initfunc_arg); extern void * get_shlibmodule_fptr(char *modname, char *fname); extern loader_data_t loader_data; #endif /* LOAD_MODULE_SHLIB_MAIN */ - +#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I) #endif diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 8ba4633604..0a532c346b 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -34,6 +34,8 @@ #include "assertions.h" #include "nr_common.h" +const char *duplex_mode[]={"FDD","TDD"}; + // Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) // Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) // Notes: @@ -231,6 +233,30 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) { } +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { + + uint8_t count=0, start=0, start_set=0; + + uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)| + (((uint64_t)FreqDomainResource[1])<<29)| + (((uint64_t)FreqDomainResource[2])<<21)| + (((uint64_t)FreqDomainResource[3])<<13)| + (((uint64_t)FreqDomainResource[4])<<5)| + (((uint64_t)FreqDomainResource[5])>>3); + + for (int i=0; i<45; i++) + if ((bitmap>>(44-i))&1) { + count++; + if (!start_set) { + start = i; + start_set = 1; + } + } + *rb_offset = 6*start; + *n_rb = 6*count; +} + + int get_dmrs_port(int nl, uint16_t dmrs_ports) { if (dmrs_ports == 0) return 0; // dci 1_0 @@ -249,6 +275,176 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports) { return p; } +int get_num_dmrs(uint16_t dmrs_mask ) { + + int num_dmrs=0; + + for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1); + return(num_dmrs); +} + +lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index) +{ + lte_frame_type_t current_type; + int32_t delta_duplex = get_delta_duplex(current_band, scs_index); + + if (delta_duplex == 0) + current_type = TDD; + else + current_type = FDD; + + LOG_I(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); + + return current_type; +} + +// Computes the duplex spacing (either positive or negative) in KHz +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) +{ + int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index); + + int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); + + LOG_I(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + + return delta_duplex; +} + +uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) +{ + + if (nr_band < 100) { //FR1 + switch(mu) { + case 0 : + if (nb_rb<=25) + return 5; + if (nb_rb<=52) + return 10; + if (nb_rb<=79) + return 15; + if (nb_rb<=106) + return 20; + if (nb_rb<=133) + return 25; + if (nb_rb<=160) + return 30; + if (nb_rb<=216) + return 40; + if (nb_rb<=270) + return 50; + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); + break; + case 1 : + if (nb_rb<=11) + return 5; + if (nb_rb<=24) + return 10; + if (nb_rb<=38) + return 15; + if (nb_rb<=51) + return 20; + if (nb_rb<=65) + return 25; + if (nb_rb<=78) + return 30; + if (nb_rb<=106) + return 40; + if (nb_rb<=133) + return 50; + if (nb_rb<=162) + return 60; + if (nb_rb<=189) + return 70; + if (nb_rb<=217) + return 80; + if (nb_rb<=245) + return 90; + if (nb_rb<=273) + return 100; + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); + break; + case 2 : + if (nb_rb<=11) + return 10; + if (nb_rb<=18) + return 15; + if (nb_rb<=24) + return 20; + if (nb_rb<=31) + return 25; + if (nb_rb<=38) + return 30; + if (nb_rb<=51) + return 40; + if (nb_rb<=65) + return 50; + if (nb_rb<=79) + return 60; + if (nb_rb<=93) + return 70; + if (nb_rb<=107) + return 80; + if (nb_rb<=121) + return 90; + if (nb_rb<=135) + return 100; + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); + break; + default: + AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); + } + } + else { + switch(mu) { + case 2 : + if (nb_rb<=66) + return 50; + if (nb_rb<=132) + return 100; + if (nb_rb<=264) + return 200; + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); + break; + case 3 : + if (nb_rb<=32) + return 50; + if (nb_rb<=66) + return 100; + if (nb_rb<=132) + return 200; + if (nb_rb<=264) + return 400; + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); + break; + default: + AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); + } + } +} + +// Returns the corresponding row index of the NR table +int get_nr_table_idx(int nr_bandP, uint8_t scs_index) { + int i, j; + int scs_khz = 15 << scs_index; + int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; + size_t s = sizeof(supplementary_bands)/sizeof(supplementary_bands[0]); + + for(j = 0; j < s; j++){ + if (nr_bandP == supplementary_bands[j]) + AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); + } + + AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band); + for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++); + + // selection of correct Deltaf raster according to SCS + if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) + i++; + + LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); + + return i; +} int get_subband_size(int NPRB,int size) { // implements table 5.2.1.4-2 from 36.214 diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index b3d2469a12..d9f2b0c03a 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -35,6 +35,7 @@ #include #include "assertions.h" +#include "PHY/defs_common.h" typedef struct nr_bandentry_s { int16_t band; @@ -50,6 +51,12 @@ typedef struct nr_bandentry_s { extern const size_t nr_bandtable_size; extern nr_bandentry_t nr_bandtable[]; +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); +int get_num_dmrs(uint16_t dmrs_mask); +uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); +int get_nr_table_idx(int nr_bandP, uint8_t scs_index); +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); +lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex); int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 734126721a..9e4eeca205 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" #include "common/utils/threadPool/thread-pool.h" @@ -62,34 +63,27 @@ #include "telnetsrv_proccmd.h" static char *telnet_defstatmod[] = {"softmodem","phy","loader","measur"}; static telnetsrv_params_t telnetparams; -#define TELNETSRV_LISTENADDR 0 -#define TELNETSRV_LISTENPORT 1 -#define TELNETSRV_PRIORITY 2 -#define TELNETSRV_DEBUG 3 -#define TELNETSRV_LOOPC 4 -#define TELNETSRV_LOOPD 5 -#define TELNETSRV_HISFILE 6 -#define TELNETSRV_HISSIZE 7 -#define TELNETSRV_PHYBSIZE 8 -#define TELNETSRV_STATICMOD 9 -#define TELNETSRV_SHRMOD 10 + +#define TELNETSRV_OPTNAME_STATICMOD "staticmod" +#define TELNETSRV_OPTNAME_SHRMOD "shrmod" paramdef_t telnetoptions[] = { - /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ - /* configuration parameters for telnet utility */ - /* optname helpstr paramflags XXXptr defXXXval type numelt */ - /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ - {"listenaddr", "\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, - {"listenport", "\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, - {"priority", "\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, - {"loopcount", "\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, - {"loopdelay", "\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, - {"histfile", "\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, - {"histsize", "\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, - {"phypbsize", "\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, - {"staticmod", "\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, - {"shrmod", "\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } + /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /* configuration parameters for telnet utility */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ + /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + {"listenaddr", "\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, + {"listenport", "\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, + {"listenstdin", "enable input from stdin\n", PARAMFLAG_BOOL, uptr:&(telnetparams.listenstdin), defuintval:0, TYPE_UINT, 0 }, + {"priority", "\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, + {"loopcount", "\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, + {"loopdelay", "\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, + {"histfile", "\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, + {"histsize", "\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, + {"phypbsize", "\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, + {TELNETSRV_OPTNAME_STATICMOD, "\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, + {TELNETSRV_OPTNAME_SHRMOD, "\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } }; int get_phybsize(void) { @@ -682,6 +676,77 @@ void run_telnetsrv(void) { return; } +void run_telnetclt(void) { + int sock; + struct sockaddr_in name; + pthread_setname_np(pthread_self(), "telnetclt"); + set_sched(pthread_self(),0,telnetparams.priority); + char prompt[sizeof(TELNET_PROMPT_PREFIX)+10]; + sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL)); + name.sin_family = AF_INET; + struct in_addr addr; + inet_aton("127.0.0.1", &addr) ; + name.sin_addr.s_addr = addr.s_addr; + name.sin_port = htons((unsigned short)(telnetparams.listenport)); + while (1) { + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno)); + + if(connect(sock, (void *) &name, sizeof(name))) + fprintf(stderr,"[TELNETSRV] Error %s on connect call\n",strerror(errno)); + + struct timeval ts; + ts.tv_sec = 1; // 1 second + ts.tv_usec = 0; + while (1) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + FD_SET(STDIN_FILENO , &fds); + // wait for data + int nready = select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); + if (nready < 0) { + perror("select. Error"); + break; + } + else if (nready == 0) { + ts.tv_sec = 1; // 1 second + ts.tv_usec = 0; + } + else if ( FD_ISSET(sock, &fds)) { + int rv; + char inbuf[TELNET_MAX_MSGLENGTH*2]; + memset(inbuf,0,sizeof(inbuf)); + rv = recv(sock , inbuf , sizeof(inbuf)-1 , 0); + if (rv > 0) { + printf("%s",inbuf); + } + else if (rv == 0) { + printf("Connection closed by the remote end\n\r"); + break; + } + else { + perror("recv error"); + break; + } + } + else if (FD_ISSET(STDIN_FILENO , &fds)) { + char *inbuf=NULL; + size_t inlen=0; + inlen = getline( &inbuf,&inlen, stdin); + if ( inlen > 0 ) { + if ( send(sock, inbuf,inlen, 0) < 0) + break; + } + free(inbuf); + } + } + close(sock); + } + return; +} /* run_telnetclt */ + void poll_telnetcmdq(void *qid, void *arg) { notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid); @@ -720,10 +785,10 @@ void exec_moduleinit(char *modname) { int add_embeddedmodules(void) { int ret=0; - - for(int i=0; i +#include +#include +#include +#include +#include +#include + + + + +#define TELNETSERVERCODE +#include "telnetsrv.h" + +#include "common/utils/LOG/log.h" +#include "common/config/config_userapi.h" +#include "telnetsrv_measurements.h" +#include "telnetsrv_ltemeasur_def.h" +#include "telnetsrv_cpumeasur_def.h" +#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" +#include "openair1/PHY/phy_extern_nr_ue.h" + +void measurcmd_display_macstats(telnet_printfunc_t prnt); +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt); +void measurcmd_display_rlcstats(telnet_printfunc_t prnt); +void measurcmd_display_phycpu(telnet_printfunc_t prnt); +void measurcmd_display_maccpu(telnet_printfunc_t prnt); +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt); + + +static telnet_measurgroupdef_t nrUEmeasurgroups[] = { +// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}}, +// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}}, + {"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}}, +// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}}, +// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}}, +}; +#define TELNET_NUM_NRUEMEASURGROUPS (sizeof(nrUEmeasurgroups)/sizeof(telnet_measurgroupdef_t)) + + +static double cpufreq; + + +#define HDR "---------------------------------" + + +int get_measurgroups(telnet_measurgroupdef_t **measurgroups) { + *measurgroups = nrUEmeasurgroups; + return TELNET_NUM_NRUEMEASURGROUPS; +} + + +void measurcmd_display_phycpu(telnet_printfunc_t prnt) { + PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_PHYNRUE_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PHY (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} +/* +void measurcmd_display_maccpu(telnet_printfunc_t prnt) { + eNB_MAC_INST *macvars = RC.mac[eNB_id]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_MACENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: MAC (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} + +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt) { + pdcp_stats_t *pdcpvars = &(eNB_pdcp_stats[eNB_id]); + telnet_cpumeasurdef_t cpumeasur[]=CPU_PDCPENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PDCP (cpustats %s) %s \n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} +//---------------------------------------------------------------------------------------------------- + + +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt) { + UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info); + + for (int UE_id=UE_info->list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) { + for (int i=0; inumactiveCCs[UE_id]; i++) { + int CC_id = UE_info->ordered_CCids[i][UE_id]; + prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR); + eNB_UE_STATS *macuestatptr = &(UE_info->eNB_UE_stats[CC_id][UE_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_UEMEASURE; + measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } + } +} // measurcmd_display_macstats_ue + +void measurcmd_display_macstats(telnet_printfunc_t prnt) { + for (int CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_STATS *macstatptr=&(RC.mac[eNB_id]->eNB_stats[CC_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_MEASURE; + prnt("%s eNB %i mac stats CC %i frame %u %s\n", + HDR, eNB_id, CC_id, RC.mac[eNB_id]->frame,HDR); + measurcmd_display_measures(prnt,statsptr,sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } +} // measurcmd_display_macstats + + +void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_ltemeasurdef_t *statsptr, int num_rlcmeasure, unsigned int *rlcstats, + char *rbid_str, protocol_ctxt_t *ctxt, const srb_flag_t srb_flagP, const rb_id_t rb_idP) + +{ + int rlc_status = rlc_stat_req(ctxt,srb_flagP,rb_idP, + rlcstats, rlcstats+1, rlcstats+2, rlcstats+3, rlcstats+4, rlcstats+5, + rlcstats+6, rlcstats+7, rlcstats+8, rlcstats+9, rlcstats+10, rlcstats+11, + rlcstats+12, rlcstats+13, rlcstats+14, rlcstats+15, rlcstats+16, rlcstats+17, + rlcstats+18, rlcstats+19, rlcstats+20, rlcstats+21, rlcstats+22, rlcstats+23, + rlcstats+24, rlcstats+25, rlcstats+26, rlcstats+27); + + if (rlc_status == RLC_OP_STATUS_OK) { + prnt("%s UE %i RLC %s mode %s %s\n",HDR,UE_id, rbid_str, + (rlcstats[0]==RLC_MODE_AM)? "AM": (rlcstats[0]==RLC_MODE_UM)?"UM":"NONE",HDR); + measurcmd_display_measures(prnt, statsptr, num_rlcmeasure); + } +} // status measurcmd_rlc_stat_req + + +void measurcmd_display_rlcstats(telnet_printfunc_t prnt) { + protocol_ctxt_t ctxt; + UE_info_t *UE_info = &(RC.mac[eNB_id]->UE_info); + telnet_ltemeasurdef_t statsptr[]=LTE_RLCMEASURE; + int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t ); + unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int)); + eNB_MAC_INST *eNB = RC.mac[eNB_id]; + + for(int i=0; i list.head; UE_id>=0; UE_id=UE_info->list.next[UE_id]) { +#define NB_eNB_INST 1 + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_info->eNB_UE_stats[0][UE_id].crnti, + eNB->frame,eNB->subframe,eNB_id); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO, DTCH-2); + } +} // measurcmd_display_macstats_ue + +*/ + + diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt index 519a1a72ff..2713c71cc0 100644 --- a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -8,9 +8,9 @@ set(TELNETSRV_SOURCE ) add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) -target_link_libraries(telnetsrv PRIVATE history) +target_link_libraries(telnetsrv PRIVATE history ncurses form ) -foreach(TELNETLIB enb gnb 4gUE 5gUE) +foreach(TELNETLIB enb gnb 4Gue 5Gue) set(TELNETLIB_SRCS "") foreach(TELNETLIB_ASRC measurements phycmd) set(TELNETLIB_SRC ${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_${TELNETLIB}_${TELNETLIB_ASRC}.c) @@ -32,4 +32,4 @@ install(TARGETS telnetsrv DESTINATION bin) if (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build") install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/ran_build/build) -endif (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build") \ No newline at end of file +endif (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build") diff --git a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h index 7a45b351f3..a275272e80 100644 --- a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h +++ b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h @@ -24,8 +24,8 @@ * \ strucures arrays which are then used by the display functions * \ in telnetsrv_measurements.c. * \author Francois TABURET - * \date 2019 - * \version 0.1 + * \date 2021 + * \version 0.2 * \company NOKIA BellLabs France * \email: francois.taburet@nokia-bell-labs.com * \note @@ -37,67 +37,119 @@ #define CPU_PHYENB_MEASURE \ { \ - {"phy_proc_tx", &(phyvars->phy_proc_tx),0},\ - {"phy_proc_rx", &(phyvars->phy_proc_rx),0},\ - {"rx_prach", &(phyvars->rx_prach),0},\ - {"ofdm_mod", &(phyvars->ofdm_mod_stats),0},\ - {"dlsch_common_and_dci", &(phyvars->dlsch_common_and_dci),0},\ - {"dlsch_ue_specific", &(phyvars->dlsch_ue_specific),0},\ - {"dlsch_encoding", &(phyvars->dlsch_encoding_stats),0},\ - {"dlsch_modulation", &(phyvars->dlsch_modulation_stats),0},\ - {"dlsch_scrambling", &(phyvars->dlsch_scrambling_stats),0},\ - {"dlsch_rate_matching", &(phyvars->dlsch_rate_matching_stats),0},\ - {"dlsch_turbo_encod_prep", &(phyvars->dlsch_turbo_encoding_preperation_stats),0},\ - {"dlsch_turbo_encod_segm", &(phyvars->dlsch_turbo_encoding_segmentation_stats),0},\ - {"dlsch_turbo_encod", &(phyvars->dlsch_turbo_encoding_stats),0},\ - {"dlsch_turbo_encod_waiting", &(phyvars->dlsch_turbo_encoding_waiting_stats),0},\ - {"dlsch_turbo_encod_signal", &(phyvars->dlsch_turbo_encoding_signal_stats),0},\ - {"dlsch_turbo_encod_main", &(phyvars->dlsch_turbo_encoding_main_stats),0},\ - {"dlsch_turbo_encod_wakeup0", &(phyvars->dlsch_turbo_encoding_wakeup_stats0),0},\ - {"dlsch_turbo_encod_wakeup1", &(phyvars->dlsch_turbo_encoding_wakeup_stats1),0},\ - {"dlsch_interleaving", &(phyvars->dlsch_interleaving_stats),0},\ - {"rx_dft", &(phyvars->rx_dft_stats),0},\ - {"ulsch_channel_estimation", &(phyvars->ulsch_channel_estimation_stats),0},\ - {"ulsch_freq_offset_estimation", &(phyvars->ulsch_freq_offset_estimation_stats),0},\ - {"ulsch_decoding", &(phyvars->ulsch_decoding_stats),0},\ - {"ulsch_demodulation", &(phyvars->ulsch_demodulation_stats),0},\ - {"ulsch_rate_unmatching", &(phyvars->ulsch_rate_unmatching_stats),0},\ - {"ulsch_turbo_decoding", &(phyvars->ulsch_turbo_decoding_stats),0},\ - {"ulsch_deinterleaving", &(phyvars->ulsch_deinterleaving_stats),0},\ - {"ulsch_demultiplexing", &(phyvars->ulsch_demultiplexing_stats),0},\ - {"ulsch_llr", &(phyvars->ulsch_llr_stats),0},\ - {"ulsch_tc_init", &(phyvars->ulsch_tc_init_stats),0},\ - {"ulsch_tc_alpha", &(phyvars->ulsch_tc_alpha_stats),0},\ - {"ulsch_tc_beta", &(phyvars->ulsch_tc_beta_stats),0},\ - {"ulsch_tc_gamma", &(phyvars->ulsch_tc_gamma_stats),0},\ - {"ulsch_tc_ext", &(phyvars->ulsch_tc_ext_stats),0},\ - {"ulsch_tc_intl1", &(phyvars->ulsch_tc_intl1_stats),0},\ - {"ulsch_tc_intl2", &(phyvars->ulsch_tc_intl2_stats),0},\ + {"phy_proc_tx", &(phyvars->phy_proc_tx),0,1},\ + {"phy_proc_rx", &(phyvars->phy_proc_rx),0,1},\ + {"rx_prach", &(phyvars->rx_prach),0,1},\ + {"ofdm_mod", &(phyvars->ofdm_mod_stats),0,1},\ + {"dlsch_common_and_dci", &(phyvars->dlsch_common_and_dci),0,1},\ + {"dlsch_ue_specific", &(phyvars->dlsch_ue_specific),0,1},\ + {"dlsch_encoding", &(phyvars->dlsch_encoding_stats),0,1},\ + {"dlsch_modulation", &(phyvars->dlsch_modulation_stats),0,1},\ + {"dlsch_scrambling", &(phyvars->dlsch_scrambling_stats),0,1},\ + {"dlsch_rate_matching", &(phyvars->dlsch_rate_matching_stats),0,1},\ + {"dlsch_turbo_encod_prep", &(phyvars->dlsch_turbo_encoding_preperation_stats),0,1},\ + {"dlsch_turbo_encod_segm", &(phyvars->dlsch_turbo_encoding_segmentation_stats),0,1},\ + {"dlsch_turbo_encod", &(phyvars->dlsch_turbo_encoding_stats),0,1},\ + {"dlsch_turbo_encod_waiting", &(phyvars->dlsch_turbo_encoding_waiting_stats),0,1},\ + {"dlsch_turbo_encod_signal", &(phyvars->dlsch_turbo_encoding_signal_stats),0,1},\ + {"dlsch_turbo_encod_main", &(phyvars->dlsch_turbo_encoding_main_stats),0,1},\ + {"dlsch_turbo_encod_wakeup0", &(phyvars->dlsch_turbo_encoding_wakeup_stats0),0,1},\ + {"dlsch_turbo_encod_wakeup1", &(phyvars->dlsch_turbo_encoding_wakeup_stats1),0,1},\ + {"dlsch_interleaving", &(phyvars->dlsch_interleaving_stats),0,1},\ + {"rx_dft", &(phyvars->rx_dft_stats),0,1},\ + {"ulsch_channel_estimation", &(phyvars->ulsch_channel_estimation_stats),0,1},\ + {"ulsch_freq_offset_estimation", &(phyvars->ulsch_freq_offset_estimation_stats),0,1},\ + {"ulsch_decoding", &(phyvars->ulsch_decoding_stats),0,1},\ + {"ulsch_demodulation", &(phyvars->ulsch_demodulation_stats),0,1},\ + {"ulsch_rate_unmatching", &(phyvars->ulsch_rate_unmatching_stats),0,1},\ + {"ulsch_turbo_decoding", &(phyvars->ulsch_turbo_decoding_stats),0,1},\ + {"ulsch_deinterleaving", &(phyvars->ulsch_deinterleaving_stats),0,1},\ + {"ulsch_demultiplexing", &(phyvars->ulsch_demultiplexing_stats),0,1},\ + {"ulsch_llr", &(phyvars->ulsch_llr_stats),0,1},\ + {"ulsch_tc_init", &(phyvars->ulsch_tc_init_stats),0,1},\ + {"ulsch_tc_alpha", &(phyvars->ulsch_tc_alpha_stats),0,1},\ + {"ulsch_tc_beta", &(phyvars->ulsch_tc_beta_stats),0,1},\ + {"ulsch_tc_gamma", &(phyvars->ulsch_tc_gamma_stats),0,1},\ + {"ulsch_tc_ext", &(phyvars->ulsch_tc_ext_stats),0,1},\ + {"ulsch_tc_intl1", &(phyvars->ulsch_tc_intl1_stats),0,1},\ + {"ulsch_tc_intl2", &(phyvars->ulsch_tc_intl2_stats),0,1},\ } #define CPU_MACENB_MEASURE \ { \ - {"eNB_scheduler", &(macvars->eNB_scheduler),0},\ - {"schedule_si", &(macvars->schedule_si),0},\ - {"schedule_ra", &(macvars->schedule_ra),0},\ - {"schedule_ulsch", &(macvars->schedule_ulsch),0},\ - {"fill_DLSCH_dci", &(macvars->fill_DLSCH_dci),0},\ - {"schedule_dlsch_pre", &(macvars->schedule_dlsch_preprocessor),0},\ - {"schedule_dlsch", &(macvars->schedule_dlsch),0},\ - {"schedule_mch", &(macvars->schedule_mch),0},\ - {"rx_ulsch_sdu", &(macvars->rx_ulsch_sdu),0},\ - {"schedule_pch", &(macvars->schedule_pch),0},\ + {"eNB_scheduler", &(macvars->eNB_scheduler),0,1},\ + {"schedule_si", &(macvars->schedule_si),0,1},\ + {"schedule_ra", &(macvars->schedule_ra),0,1},\ + {"schedule_ulsch", &(macvars->schedule_ulsch),0,1},\ + {"fill_DLSCH_dci", &(macvars->fill_DLSCH_dci),0,1},\ + {"schedule_dlsch_pre", &(macvars->schedule_dlsch_preprocessor),0,1},\ + {"schedule_dlsch", &(macvars->schedule_dlsch),0,1},\ + {"schedule_mch", &(macvars->schedule_mch),0,1},\ + {"rx_ulsch_sdu", &(macvars->rx_ulsch_sdu),0,1},\ + {"schedule_pch", &(macvars->schedule_pch),0,1},\ } #define CPU_PDCPENB_MEASURE \ { \ - {"pdcp_run", &(pdcpvars->pdcp_run),0},\ - {"data_req", &(pdcpvars->data_req),0},\ - {"data_ind", &(pdcpvars->data_ind),0},\ - {"apply_security", &(pdcpvars->apply_security),0},\ - {"validate_security", &(pdcpvars->validate_security),0},\ - {"pdcp_ip", &(pdcpvars->pdcp_ip),0},\ - {"ip_pdcp", &(pdcpvars->ip_pdcp),0},\ + {"pdcp_run", &(pdcpvars->pdcp_run),0,1},\ + {"data_req", &(pdcpvars->data_req),0,1},\ + {"data_ind", &(pdcpvars->data_ind),0,1},\ + {"apply_security", &(pdcpvars->apply_security),0,1},\ + {"validate_security", &(pdcpvars->validate_security),0,1},\ + {"pdcp_ip", &(pdcpvars->pdcp_ip),0,1},\ + {"ip_pdcp", &(pdcpvars->ip_pdcp),0,1},\ } +/* from openair1/PHY/defs_nr_UE.h */ +#define CPU_PHYNRUE_MEASURE \ +{ \ + {"phy_proc", &(UE->phy_proc[0]),0,RX_NB_TH},\ + {"phy_proc_rx", &(UE-> phy_proc_rx[0]),0,RX_NB_TH},\ + {"phy_proc_tx", &(UE->phy_proc_tx),0,1},\ + {"ofdm_mod_stats", &(UE->ofdm_mod_stats),0,1},\ + {"ulsch_encoding_stats", &(UE->ulsch_encoding_stats),0,1},\ + {"ulsch_modulation_stats", &(UE->ulsch_modulation_stats),0,1},\ + {"ulsch_segmentation_stats", &(UE->ulsch_segmentation_stats),0,1},\ + {"ulsch_rate_matching_stats", &(UE->ulsch_rate_matching_stats),0,1},\ + {"ulsch_turbo_encoding_stats", &(UE->ulsch_turbo_encoding_stats),0,1},\ + {"ulsch_interleaving_stats", &(UE->ulsch_interleaving_stats),0,1},\ + {"ulsch_multiplexing_stats", &(UE->ulsch_multiplexing_stats),0,1},\ + {"generic_stat", &(UE->generic_stat),0,1},\ + {"generic_stat_bis", &(UE->generic_stat_bis[0][0]),0,RX_NB_TH,LTE_SLOTS_PER_SUBFRAME},\ + {"ofdm_demod_stats", &(UE->ofdm_demod_stats),0,1},\ + {"dlsch_rx_pdcch_stats", &(UE->dlsch_rx_pdcch_stats),0,1},\ + {"rx_dft_stats", &(UE->rx_dft_stats),0,1},\ + {"dlsch_c...timation_stats", &(UE->dlsch_channel_estimation_stats),0,1},\ + {"dlsch_f...timation_stats", &(UE->dlsch_freq_offset_estimation_stats),0,1},\ + {"dlsch_demodulation_stats", &(UE->dlsch_demodulation_stats),0,1},\ + {"dlsch_rate_unmatching_stats", &(UE->dlsch_rate_unmatching_stats),0,1},\ + {"dlsch_turbo_decoding_stats", &(UE->dlsch_turbo_decoding_stats),0,1},\ + {"dlsch_deinterleaving_stats", &(UE->dlsch_deinterleaving_stats),0,1},\ + {"dlsch_llr_stats", &(UE->dlsch_llr_stats),0,1},\ + {"dlsch_unscrambling_stats", &(UE->dlsch_unscrambling_stats),0,1},\ + {"dlsch_rate_matching_stats", &(UE->dlsch_rate_matching_stats),0,1},\ + {"dlsch_turbo_encoding_stats", &(UE->dlsch_turbo_encoding_stats),0,1},\ + {"dlsch_interleaving_stats", &(UE->dlsch_interleaving_stats),0,1},\ + {"dlsch_tc_init_stats", &(UE->dlsch_tc_init_stats),0,1},\ + {"dlsch_tc_alpha_stats", &(UE->dlsch_tc_alpha_stats),0,1},\ + {"dlsch_tc_beta_stats", &(UE->dlsch_tc_beta_stats),0,1},\ + {"dlsch_tc_gamma_stats", &(UE->dlsch_tc_gamma_stats),0,1},\ + {"dlsch_tc_ext_stats", &(UE->dlsch_tc_ext_stats),0,1},\ + {"dlsch_tc_intl1_stats", &(UE->dlsch_tc_intl1_stats),0,1},\ + {"dlsch_tc_intl2_stats", &(UE->dlsch_tc_intl2_stats),0,1},\ + {"tx_prach", &(UE->tx_prach),0,1},\ + {"dlsch_encoding_SIC_stats", &(UE->dlsch_encoding_SIC_stats),0,1},\ + {"dlsch_scrambling_SIC_stats", &(UE->dlsch_scrambling_SIC_stats),0,1},\ + {"dlsch_modulation_SIC_stats", &(UE->dlsch_modulation_SIC_stats),0,1},\ + {"dlsch...ping_unit_SIC_stats", &(UE->dlsch_llr_stripping_unit_SIC_stats),0,1},\ + {"dlsch_unscrambling_SIC_stats", &(UE->dlsch_unscrambling_SIC_stats),0,1},\ + {"ue_front_end_stat", &(UE->ue_front_end_stat[0]),0,RX_NB_TH},\ + {"ue_front_end_per_slot_stat", &(UE->ue_front_end_per_slot_stat[0][0]),0,RX_NB_TH,LTE_SLOTS_PER_SUBFRAME},\ + {"pdcch_procedures_stat", &(UE->pdcch_procedures_stat[0]),0,RX_NB_TH},\ + {"pdsch_procedures_stat", &(UE->pdsch_procedures_stat[0]),0,RX_NB_TH},\ + {"pdsch_procedures_per_slot_stat", &(UE->pdsch_procedures_per_slot_stat[0][0]),0,RX_NB_TH,LTE_SLOTS_PER_SUBFRAME},\ + {"dlsch_procedures_stat", &(UE->dlsch_procedures_stat[0]),0,RX_NB_TH},\ + {"dlsch_decoding_stats", &(UE->dlsch_decoding_stats[0]),0,RX_NB_TH},\ + {"dlsch_llr_stats_para", &(UE->dlsch_llr_stats_parallelization[0][0]),0,RX_NB_TH,LTE_SLOTS_PER_SUBFRAME},\ +} #endif diff --git a/common/utils/telnetsrv/telnetsrv_measurements.c b/common/utils/telnetsrv/telnetsrv_measurements.c index 4a11e7c2dd..786cbd094c 100644 --- a/common/utils/telnetsrv/telnetsrv_measurements.c +++ b/common/utils/telnetsrv/telnetsrv_measurements.c @@ -64,13 +64,30 @@ void measurcmd_display_groups(telnet_printfunc_t prnt,telnet_measurgroupdef_t *m } /* measurcmd_display_groups */ /*----------------------------------------------------------------------------------------------------*/ /* cpu measurements functions */ -void measurcmd_display_cpumeasures(telnet_printfunc_t prnt, telnet_cpumeasurdef_t *cpumeasure, int cpumeasure_size) { - for (int i=0; istatname, - ((cpumeasure+i)->astatptr->trials!=0)?(((cpumeasure+i)->astatptr->diff)/((cpumeasure+i)->astatptr->trials))/cpufreq/1000:0, - (cpumeasure+i)->astatptr->trials, ((i%2)==1)?"|\n":" | " ); - } + +static char *stridx(int max,int i, char *buff) { + if (max>1) + sprintf(buff,"[%d]",i); + else + sprintf(buff," "); + return buff; + +} +void measurcmd_display_cpumeasures(telnet_printfunc_t prnt, telnet_cpumeasurdef_t *cpumeasure, int cpumeasure_size) { + int p=0; + char stridx1[16]; + char stridx2[16]; + for (int i=0; istatname, + stridx(cpumeasure[i].num_occur1,o1,stridx1),stridx(cpumeasure[i].num_occur2,o2,stridx2), + ((cpumeasure+i+o1+o2)->astatptr->trials!=0)?(((cpumeasure+i+o1+o2)->astatptr->diff)/((cpumeasure+i+o1+o2)->astatptr->trials))/cpufreq/1000:0, + (cpumeasure+i+o1+o2)->astatptr->trials, ((p%2)==1)?"|\n":" | " ); + p++; + } prnt("\n\n"); } /* measurcmd_display_measures */ @@ -137,11 +154,17 @@ int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt) { } telnet_measurgroupdef_t *measurgroups; int num_measurgroups = fptr( &measurgroups); - + int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); if (s>0) { - if ( strcmp(subcmd,"groups") == 0) { + if ( strcmp(subcmd,"inq") == 0) { + notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL); + time_stats_msg_t *msgdata=NotifiedFifoData(msg); + msgdata->msgid = TIMESTAT_MSGID_DISPLAY; + msgdata->displayFunc = prnt; + pushNotifiedFIFO(&measur_fifo, msg); + } else if ( strcmp(subcmd,"groups") == 0){ measurcmd_display_groups(prnt,measurgroups,num_measurgroups); badcmd=0; } else { @@ -182,13 +205,13 @@ int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt) { int badcmd=1; if (debug > 0) - prnt(" measurcmd_show received %s\n",buf); + prnt(" measurcmd_cpustats received %s\n",buf); int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); if (s>0) { if ( strcmp(subcmd,"enable") == 0) { - cpumeas(CPUMEAS_ENABLE); + badcmd=0; } else if ( strcmp(subcmd,"disable") == 0) { cpumeas(CPUMEAS_DISABLE); @@ -203,6 +226,64 @@ int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt) { free(subcmd); return CMDSTATUS_FOUND; } + +void measurcmd_async_help(telnet_printfunc_t prnt) { +} + +int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt) { + char *subcmd=NULL; + int idx1, idx2; + int okcmd=0; + + if (buf == NULL) { + measurcmd_async_help(prnt); + return CMDSTATUS_FOUND; + } + if (debug > 0) + prnt(" measurcmd_async received %s\n",buf); + + + int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); + + if (s==1) { + if ( strcmp(subcmd,"enable") == 0) { + init_meas(); + okcmd=1; + } else if ( strcmp(subcmd,"disable") == 0) { + end_meas(); + okcmd=1; + } + } else if ( s == 3 ) { + int msgid; + if ( strcmp(subcmd,"enable") == 0) { + msgid = TIMESTAT_MSGID_ENABLE; + okcmd=1; + } else if ( strcmp(subcmd,"disable") == 0) { + msgid = TIMESTAT_MSGID_DISABLE; + okcmd=1; + } else if ( strcmp(subcmd,"display") == 0) { + msgid = TIMESTAT_MSGID_DISPLAY; + okcmd=1; + } + if (okcmd) { + notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL); + time_stats_msg_t *msg = (time_stats_msg_t *)NotifiedFifoData(nfe); + msg->msgid = msgid ; + msg->displayFunc = prnt; + for(int i=idx1; itimestat_id =i; + pushNotifiedFIFO(&measur_fifo, nfe); + } + } + } + + if (!(okcmd)) { + prnt("Unknown command: %s\n",buf); + } + + free(subcmd); + return CMDSTATUS_FOUND; +} /*-------------------------------------------------------------------------------------*/ /* function called at telnet server init to add the measur command */ diff --git a/common/utils/telnetsrv/telnetsrv_measurements.h b/common/utils/telnetsrv/telnetsrv_measurements.h index 08136df0fd..99ae695f41 100644 --- a/common/utils/telnetsrv/telnetsrv_measurements.h +++ b/common/utils/telnetsrv/telnetsrv_measurements.h @@ -49,6 +49,9 @@ typedef struct cpumeasurdef { char statname[TELNET_MAXMEASURNAME_LEN]; time_stats_t *astatptr; unsigned int statemask; + uint8_t num_occur1; + uint8_t num_occur2; + uint8_t num_occur3; } telnet_cpumeasurdef_t; typedef struct ltemeasurdef { @@ -60,6 +63,7 @@ typedef struct ltemeasurdef { #define GROUP_LTESTATS 0 #define GROUP_CPUSTATS 1 + typedef void(*measur_dislayfunc_t)(telnet_printfunc_t prnt); typedef struct mesurgroupdef { char groupname[TELNET_MAXMEASURNAME_LEN]; @@ -79,9 +83,11 @@ typedef struct mesurgroupdef { #ifdef TELNETSRV_MEASURMENTS_MAIN int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt); int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt); +int measurcmd_async(char *buf, int debug, telnet_printfunc_t prnt); telnetshell_cmddef_t measur_cmdarray[] = { - {"show", "groups | " , measurcmd_show}, + {"show", "groups | | inq" , measurcmd_show}, {"cpustats","[enable | disable]",measurcmd_cpustats}, + {"async","[enable | disable]",measurcmd_async}, {"","",NULL} }; diff --git a/doc/BUILD.md b/doc/BUILD.md index 166563877e..40b63ac697 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -88,6 +88,21 @@ You can build any oai softmodem executable separately, you may not need all of t After completing the build, the binaries are available in the `cmake_targets/ran_build/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel15. +When installing the pre-requisites, especially the `UHD` driver, you can now specify if you want to install from source or not. + +- For `fedora`-based OS, it was already the case all the time. But now you can specify which version to install. +- For `ubuntu` OS, the Ettus PPA currently installs the following versions: + * `Ubuntu16.04`: --> version `3.15.0.0` + * `Ubuntu18.04`: --> version `4.1.0.0` + +```bash +export BUILD_UHD_FROM_SOURCE=True +export UHD_VERSION=3.15.0.0 +./build_oai -I -w USRP +``` + +The `UHD_VERSION` env variable `SHALL` be a valid tag (minus `v`) from the `https://github.com/EttusResearch/uhd.git` repository. + ## Issue when building `nasmeh` module ## A lot of users and contributors have faced the issue: `nasmesh` module does not build. diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index dc7a982310..d063afd5d9 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -203,10 +203,7 @@ UE on machine 2: - - - - +[Selecting an alternative ldpc implementation at run time](../openair1/PHY/CODING/DOC/LDPCImplementation.md) [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index 90c807fc0e..0522271df0 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -41,17 +41,23 @@ RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters #start from scratch for target executable FROM registry.access.redhat.com/ubi8/ubi:latest as oai-enb +ENV TZ=Europe/Paris RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ nettle \ + tzdata \ procps-ng \ atlas \ + python3 \ + python3-pip \ net-tools \ iputils \ iproute \ libyaml && \ + pip3 install six && \ + pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -78,6 +84,8 @@ COPY --from=enb-build /lib64/libconfig.so.9 /lib64 COPY --from=enb-build /lib64/libblas.so.3 /lib64 COPY --from=enb-build /lib64/liblapack.so.3 /lib64 COPY --from=enb-build /lib64/liblapacke.so.3 /lib64 + +# Now we are copying from builder-image the UHD files. COPY --from=enb-build /lib64/libboost_chrono.so.1.66.0 /lib64 COPY --from=enb-build /lib64/libboost_date_time.so.1.66.0 /lib64 COPY --from=enb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 @@ -88,7 +96,14 @@ COPY --from=enb-build /lib64/libboost_system.so.1.66.0 /lib64 COPY --from=enb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 COPY --from=enb-build /lib64/libboost_atomic.so.1.66.0 /lib64 COPY --from=enb-build /lib64/libboost_timer.so.1.66.0 /lib64 -COPY --from=enb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 +COPY --from=enb-build /lib64/libboost_regex.so.1.66.0 /lib64 + +COPY --from=enb-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=enb-build /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64 +COPY --from=enb-build /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-enb/bin + +WORKDIR /usr/local/share/uhd/rfnoc +COPY --from=enb-build /usr/local/share/uhd/rfnoc/ . RUN ldconfig diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index c4393dc78e..cf748784e5 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -25,7 +25,7 @@ # #--------------------------------------------------------------------- -FROM ran-build:latest AS enb-build +FROM ran-build:latest AS enb-build RUN rm -Rf /oai-ran WORKDIR /oai-ran @@ -42,8 +42,7 @@ RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters #start from scratch for target executable FROM ubuntu:bionic as oai-enb ENV DEBIAN_FRONTEND=noninteractive -ENV TZ=Europe -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +ENV TZ=Europe/Paris RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ @@ -60,16 +59,12 @@ RUN apt-get update && \ iputils-ping \ iproute2 \ iperf \ - libyaml-0-2 && \ - # Install UHD driver from ettus ppa - # At time of writing, it is 3.14 - add-apt-repository ppa:ettusresearch/uhd --yes && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install --yes \ python \ + python3 \ + python3-six \ + python3-requests \ libusb-1.0-0 \ - libuhd003 \ - uhd-host && \ + libyaml-0-2 && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-enb/bin @@ -90,6 +85,17 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 . +# Now we are copying from builder-image the UHD files. +COPY --from=enb-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=enb-build /usr/local/lib/libuhd.so.3.15.0 /usr/local/lib +COPY --from=enb-build /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-enb/bin +WORKDIR /usr/lib/x86_64-linux-gnu +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.65.1 . +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 . +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.65.1 . +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.65.1 . +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 . +COPY --from=enb-build /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 . RUN ldconfig diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index 9ee0bf9ae9..b34a9d242d 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -41,6 +41,7 @@ RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/gnb_parameters #start from scratch for target executable FROM registry.access.redhat.com/ubi8/ubi:latest as oai-gnb +ENV TZ=Europe/Paris RUN yum repolist --disablerepo=* && \ yum update -y && \ @@ -51,9 +52,14 @@ RUN yum repolist --disablerepo=* && \ atlas \ lksctp-tools \ nettle \ + tzdata \ + python3 \ + python3-pip \ net-tools \ iputils \ libyaml && \ + pip3 install six && \ + pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -84,6 +90,8 @@ COPY --from=gnb-build /lib64/libforms.so.2 /lib64 COPY --from=gnb-build /lib64/libblas.so.3 /lib64 COPY --from=gnb-build /lib64/liblapack.so.3 /lib64 COPY --from=gnb-build /lib64/liblapacke.so.3 /lib64 + +# Now we are copying from builder-image the UHD files. COPY --from=gnb-build /lib64/libboost_chrono.so.1.66.0 /lib64 COPY --from=gnb-build /lib64/libboost_date_time.so.1.66.0 /lib64 COPY --from=gnb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 @@ -94,7 +102,14 @@ COPY --from=gnb-build /lib64/libboost_system.so.1.66.0 /lib64 COPY --from=gnb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 COPY --from=gnb-build /lib64/libboost_atomic.so.1.66.0 /lib64 COPY --from=gnb-build /lib64/libboost_timer.so.1.66.0 /lib64 -COPY --from=gnb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 +COPY --from=gnb-build /lib64/libboost_regex.so.1.66.0 /lib64 + +COPY --from=gnb-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=gnb-build /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64 +COPY --from=gnb-build /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin + +WORKDIR /usr/local/share/uhd/rfnoc +COPY --from=gnb-build /usr/local/share/uhd/rfnoc/ . RUN ldconfig diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index 990c4363e5..cfd9d82144 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -59,16 +59,12 @@ RUN apt-get update && \ net-tools \ iproute2 \ iputils-ping \ - libyaml-0-2 && \ - # Install UHD driver from ettus ppa - # At time of writing, it is 3.14 - add-apt-repository ppa:ettusresearch/uhd --yes && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install --yes \ python \ + python3 \ + python3-six \ + python3-requests \ libusb-1.0-0 \ - libuhd003 \ - uhd-host && \ + libyaml-0-2 && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-gnb/bin @@ -93,6 +89,18 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" COPY --from=gnb-build /usr/local/lib/libprotobuf-c.so.1 . +# Now we are copying from builder-image the UHD files. +COPY --from=gnb-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=gnb-build /usr/local/lib/libuhd.so.3.15.0 /usr/local/lib +COPY --from=gnb-build /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-gnb/bin +WORKDIR /usr/lib/x86_64-linux-gnu +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.65.1 . +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 . +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.65.1 . +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.65.1 . +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 . +COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 . + RUN ldconfig # Copy the relevant configuration files for gNB diff --git a/docker/Dockerfile.lteRU.rhel8.2 b/docker/Dockerfile.lteRU.rhel8.2 index 314c01dff3..7e2a054a12 100644 --- a/docker/Dockerfile.lteRU.rhel8.2 +++ b/docker/Dockerfile.lteRU.rhel8.2 @@ -48,9 +48,13 @@ RUN yum update -y && \ tzdata \ procps-ng \ atlas \ + python3 \ + python3-pip \ net-tools \ iputils \ iproute && \ + pip3 install six && \ + pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -66,11 +70,12 @@ COPY --from=ru-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . COPY --from=ru-build /oai-ran/targets/bin/libparams_libconfig.so . COPY --from=ru-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . -# Copying from the ran-build image the USRP needed packages COPY --from=ru-build /lib64/libconfig.so.9 /lib64 COPY --from=ru-build /lib64/libblas.so.3 /lib64 COPY --from=ru-build /lib64/liblapack.so.3 /lib64 COPY --from=ru-build /lib64/liblapacke.so.3 /lib64 + +# Copying from the ran-build image the USRP needed packages COPY --from=ru-build /lib64/libboost_chrono.so.1.66.0 /lib64 COPY --from=ru-build /lib64/libboost_date_time.so.1.66.0 /lib64 COPY --from=ru-build /lib64/libboost_filesystem.so.1.66.0 /lib64 @@ -81,7 +86,14 @@ COPY --from=ru-build /lib64/libboost_system.so.1.66.0 /lib64 COPY --from=ru-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 COPY --from=ru-build /lib64/libboost_atomic.so.1.66.0 /lib64 COPY --from=ru-build /lib64/libboost_timer.so.1.66.0 /lib64 -COPY --from=ru-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 +COPY --from=ru-build /lib64/libboost_regex.so.1.66.0 /lib64 + +COPY --from=ru-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=ru-build /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64 +COPY --from=ru-build /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ru/bin + +WORKDIR /usr/local/share/uhd/rfnoc +COPY --from=ru-build /usr/local/share/uhd/rfnoc/ . RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" && \ diff --git a/docker/Dockerfile.lteRU.ubuntu18 b/docker/Dockerfile.lteRU.ubuntu18 index fa99827d94..eafb8fa8af 100644 --- a/docker/Dockerfile.lteRU.ubuntu18 +++ b/docker/Dockerfile.lteRU.ubuntu18 @@ -54,17 +54,13 @@ RUN apt-get update && \ libatlas3-base \ libconfig9 \ net-tools \ + python \ + python3 \ + python3-six \ + python3-requests \ + libusb-1.0-0 \ iputils-ping \ iproute2 && \ - # Install UHD driver from ettus ppa - # At time of writing, it is 3.14 - add-apt-repository ppa:ettusresearch/uhd --yes && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - python \ - libusb-1.0-0 \ - libuhd003 \ - uhd-host && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-lte-ru/bin @@ -78,6 +74,19 @@ COPY --from=ru-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . COPY --from=ru-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . COPY --from=ru-build /oai-ran/targets/bin/libparams_libconfig.so . COPY --from=ru-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . + +# Now we are copying from builder-image the UHD files. +COPY --from=ru-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=ru-build /usr/local/lib/libuhd.so.3.15.0 /usr/local/lib +COPY --from=ru-build /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ru/bin +WORKDIR /usr/lib/x86_64-linux-gnu +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.65.1 . +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 . +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.65.1 . +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.65.1 . +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 . +COPY --from=ru-build /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 . + RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" && \ /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" && \ /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" && \ diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index 936780297a..a6814be136 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -42,17 +42,23 @@ RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_paramet #start from scratch for target executable FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue +ENV TZ=Europe/Paris RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ procps-ng \ nettle \ + tzdata \ atlas \ + python3 \ + python3-pip \ iproute \ net-tools \ iputils \ libyaml && \ + pip3 install six && \ + pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -82,6 +88,8 @@ COPY --from=lte-ue-build /lib64/libconfig.so.9 /lib64 COPY --from=lte-ue-build /lib64/libblas.so.3 /lib64 COPY --from=lte-ue-build /lib64/liblapack.so.3 /lib64 COPY --from=lte-ue-build /lib64/liblapacke.so.3 /lib64 + +# Now we are copying from builder-image the UHD files. COPY --from=lte-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 COPY --from=lte-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 COPY --from=lte-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 @@ -92,7 +100,14 @@ COPY --from=lte-ue-build /lib64/libboost_system.so.1.66.0 /lib64 COPY --from=lte-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 COPY --from=lte-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 COPY --from=lte-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 -COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 +COPY --from=lte-ue-build /lib64/libboost_regex.so.1.66.0 /lib64 + +COPY --from=lte-ue-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64 +COPY --from=lte-ue-build /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ue/bin + +WORKDIR /usr/local/share/uhd/rfnoc +COPY --from=lte-ue-build /usr/local/share/uhd/rfnoc/ . RUN ldconfig diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index 34cbe651ad..6d54ab08fc 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -43,8 +43,7 @@ RUN python3 ./docker/scripts/generateTemplate.py ./docker/scripts/lte_ue_paramet #start from scratch for target executable FROM ubuntu:bionic as oai-lte-ue ENV DEBIAN_FRONTEND=noninteractive -ENV TZ=Europe -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +ENV TZ=Europe/Paris RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ @@ -58,19 +57,15 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + python \ + python3 \ + python3-six \ + python3-requests \ + libusb-1.0-0 \ iputils-ping \ iproute2 \ iperf \ libyaml-0-2 && \ - # Install UHD driver from ettus ppa - # At time of writing, it is 3.14 - add-apt-repository ppa:ettusresearch/uhd --yes && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - python \ - libusb-1.0-0 \ - libuhd003 \ - uhd-host && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-lte-ue/bin @@ -95,6 +90,18 @@ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/li COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 . +# Now we are copying from builder-image the UHD files. +COPY --from=lte-ue-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=lte-ue-build /usr/local/lib/libuhd.so.3.15.0 /usr/local/lib +COPY --from=lte-ue-build /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-lte-ue/bin +WORKDIR /usr/lib/x86_64-linux-gnu +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.65.1 . +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 . +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.65.1 . +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.65.1 . +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 . +COPY --from=lte-ue-build /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 . + RUN ldconfig # Copy the relevant configuration files for UE diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index 56fc746ade..ec74d11940 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -51,9 +51,13 @@ RUN yum update -y && \ iputils \ iproute \ atlas \ + python3 \ + python3-pip \ libXpm \ libX11 \ libyaml && \ + pip3 install six && \ + pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -87,6 +91,8 @@ COPY --from=nr-ue-build /lib64/libblas.so.3 /lib64 COPY --from=nr-ue-build /lib64/liblapack.so.3 /lib64 COPY --from=nr-ue-build /lib64/liblapacke.so.3 /lib64 COPY --from=nr-ue-build /lib64/libforms.so.2 /lib64 + +# Now we are copying from builder-image the UHD files. COPY --from=nr-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 COPY --from=nr-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 COPY --from=nr-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 @@ -97,7 +103,15 @@ COPY --from=nr-ue-build /lib64/libboost_system.so.1.66.0 /lib64 COPY --from=nr-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 COPY --from=nr-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 COPY --from=nr-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 -COPY --from=nr-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 +COPY --from=nr-ue-build /lib64/libboost_regex.so.1.66.0 /lib64 + +COPY --from=nr-ue-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=nr-ue-build /usr/local/lib64/libuhd.so.3.15.0 /usr/local/lib64 +COPY --from=nr-ue-build /usr/local/lib64/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin + +WORKDIR /usr/local/share/uhd/rfnoc +COPY --from=nr-ue-build /usr/local/share/uhd/rfnoc/ . + RUN ldconfig diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index fc30af7286..49e3f3213b 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -55,19 +55,15 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + python \ + python3 \ + python3-six \ + python3-requests \ + libusb-1.0-0 \ iputils-ping \ iproute2 \ iperf \ libyaml-0-2 && \ - # Install UHD driver from ettus ppa - # At time of writing, it is 3.14 - add-apt-repository ppa:ettusresearch/uhd --yes && \ - apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - python \ - libusb-1.0-0 \ - libuhd003 \ - uhd-host && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/oai-nr-ue/bin @@ -95,6 +91,18 @@ RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/li COPY --from=nr-ue-build /usr/local/lib/libprotobuf-c.so.1 . +# Now we are copying from builder-image the UHD files. +COPY --from=nr-ue-build /usr/local/bin/uhd_find_devices /usr/local/bin +COPY --from=nr-ue-build /usr/local/lib/libuhd.so.3.15.0 /usr/local/lib +COPY --from=nr-ue-build /usr/local/lib/uhd/utils/uhd_images_downloader.py /opt/oai-nr-ue/bin +WORKDIR /usr/lib/x86_64-linux-gnu +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_date_time.so.1.65.1 . +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 . +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.65.1 . +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_serialization.so.1.65.1 . +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 . +COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 . + RUN ldconfig WORKDIR /opt/oai-nr-ue diff --git a/docker/Dockerfile.ran.rhel8.2 b/docker/Dockerfile.ran.rhel8.2 index 3972fd0c35..4d15220ca8 100644 --- a/docker/Dockerfile.ran.rhel8.2 +++ b/docker/Dockerfile.ran.rhel8.2 @@ -28,6 +28,9 @@ FROM registry.access.redhat.com/ubi8/ubi:latest AS ran-build ARG NEEDED_GIT_PROXY +ENV TZ=Europe/Paris +ENV BUILD_UHD_FROM_SOURCE=True +ENV UHD_VERSION=3.15.0.0 COPY tmp/ca/redhat-uep.pem /etc/rhsm/ca COPY tmp/entitlement/*.pem /etc/pki/entitlement diff --git a/docker/Dockerfile.ran.ubuntu18 b/docker/Dockerfile.ran.ubuntu18 index 4b296408fd..3ef81ec030 100644 --- a/docker/Dockerfile.ran.ubuntu18 +++ b/docker/Dockerfile.ran.ubuntu18 @@ -29,8 +29,9 @@ FROM ubuntu:bionic AS ran-build ARG NEEDED_GIT_PROXY ENV DEBIAN_FRONTEND=noninteractive -ENV TZ=Europe -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +ENV TZ=Europe/Paris +ENV BUILD_UHD_FROM_SOURCE=True +ENV UHD_VERSION=3.15.0.0 #install developers pkg/repo RUN apt-get update && \ diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh index 2e8886e855..ff92e3c86f 100755 --- a/docker/scripts/enb_entrypoint.sh +++ b/docker/scripts/enb_entrypoint.sh @@ -46,11 +46,11 @@ done # Load the USRP binaries if [[ -v USE_B2XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx + $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx + $PREFIX/bin/uhd_images_downloader.py -t x3xx elif [[ -v USE_N3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx + $PREFIX/bin/uhd_images_downloader.py -t n3xx fi echo "==================================" diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index 678ec6cb1b..05b42d76bb 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -37,11 +37,11 @@ done # Load the USRP binaries if [[ -v USE_B2XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx + $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx + $PREFIX/bin/uhd_images_downloader.py -t x3xx elif [[ -v USE_N3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx + $PREFIX/bin/uhd_images_downloader.py -t n3xx fi echo "==================================" diff --git a/docker/scripts/lte_ru_entrypoint.sh b/docker/scripts/lte_ru_entrypoint.sh index f466e25ec2..93122b0d02 100755 --- a/docker/scripts/lte_ru_entrypoint.sh +++ b/docker/scripts/lte_ru_entrypoint.sh @@ -35,11 +35,11 @@ done # Load the USRP binaries if [[ -v USE_B2XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx + $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx + $PREFIX/bin/uhd_images_downloader.py -t x3xx elif [[ -v USE_N3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx + $PREFIX/bin/uhd_images_downloader.py -t n3xx fi echo "==================================" diff --git a/docker/scripts/lte_ue_entrypoint.sh b/docker/scripts/lte_ue_entrypoint.sh index 235128f738..de7ae8b496 100755 --- a/docker/scripts/lte_ue_entrypoint.sh +++ b/docker/scripts/lte_ue_entrypoint.sh @@ -39,11 +39,11 @@ $PREFIX/bin/conf2uedata -c $PREFIX/etc/ue_usim.conf -o $PREFIX # Load the USRP binaries if [[ -v USE_B2XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx + $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx + $PREFIX/bin/uhd_images_downloader.py -t x3xx elif [[ -v USE_N3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx + $PREFIX/bin/uhd_images_downloader.py -t n3xx fi # in case we have conf file, append diff --git a/docker/scripts/nr_ue_entrypoint.sh b/docker/scripts/nr_ue_entrypoint.sh index 691258b8fa..91d25c9e1e 100755 --- a/docker/scripts/nr_ue_entrypoint.sh +++ b/docker/scripts/nr_ue_entrypoint.sh @@ -34,11 +34,11 @@ done # Load the USRP binaries if [[ -v USE_B2XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx + $PREFIX/bin/uhd_images_downloader.py -t b2xx elif [[ -v USE_X3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx + $PREFIX/bin/uhd_images_downloader.py -t x3xx elif [[ -v USE_N3XX ]]; then - /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx + $PREFIX/bin/uhd_images_downloader.py -t n3xx fi # in case we have conf file, append diff --git a/executables/nr-ru.c b/executables/nr-ru.c index e3c6a3d964..336b7bec12 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -33,6 +33,7 @@ #include "common/utils/assertions.h" #include "common/utils/system.h" +#include "common/ran_context.h" #include "../../ARCH/COMMON/common_lib.h" #include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" @@ -47,8 +48,6 @@ #include "PHY/INIT/phy_init.h" #include "SCHED_NR/sched_nr.h" -#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" - #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 5a8b381206..fca9c72f42 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -436,7 +436,7 @@ int main( int argc, char **argv ) { itti_init(TASK_MAX, tasks_info); init_opt() ; - load_nrLDPClib(); + load_nrLDPClib(NULL); if (ouput_vcd) { vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd"); diff --git a/openair1/PHY/CODING/DOC/LDPCImplementation.md b/openair1/PHY/CODING/DOC/LDPCImplementation.md index 89ae6b4dbb..c5411540b6 100644 --- a/openair1/PHY/CODING/DOC/LDPCImplementation.md +++ b/openair1/PHY/CODING/DOC/LDPCImplementation.md @@ -1,11 +1,13 @@ -#LDPC coder/decoder implementation +# LDPC coder/decoder implementation The LDPC coder and decoder are implemented in a shared library, dynamically loaded at run-time using the [oai shared library loader](file://../../../../common/utils/DOC/loader.md). The code loading the LDPC library is in [nrLDPC_load.c](file://../nrLDPC_load.c), in function `load_nrLDPClib`, which must be called at init time. ## Selecting the LDPC library at run time By default the function `int load_nrLDPClib(void)` looks for `libldpc.so`, this default behavior can be changed using the oai loader configuration options in the configuration file or from the command line as shown below: ->loading `libldpc_optim8seg.so` instead of `libldpc.so` +#### Examples of ldpc shared lib selection when running nr softmodem's: + +loading `libldpc_optim8seg.so` instead of `libldpc.so`: ``` ./nr-softmodem -O libconfig:gnb.band78.tm1.106PRB.usrpx300.conf:dbgl5 --loader.ldpc.shlibversion _optim8seg @@ -18,9 +20,160 @@ By default the function `int load_nrLDPClib(void)` looks for `libldpc.so`, this ........................ ``` -Today, this mechanism is not available in the `ldpctest` phy simulator which doesn't initialize the [configuration module](file://../../../../common/config/DOC/config.md). loads `libldpc.so` and `libldpc_orig.so` to compare the performance of the two implementations. +loading `libldpc_cl.so` instead of `libldpc.so`: -###LDPC libraries -Libraries implementing the LDPC algorithms must be named `libldpc<_version>.so`, they must implement two functions: `nrLDPC_decod` and `nrLDPC_encod`. The prototypes for these functions is defined in [nrLDPC_defs.h](file://nrLDPC_defs.h). +`make ldpc_cl` + +`cp ../../../openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl` + +`./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.serveraddr server --sa --log_config.gtpu_log_level info --loader.ldpc.shlibversion _cl` + +``` [LOADER] library libldpc_cl.so successfully loaded +------------------------------------------------ +[HW] Platform 0, OpenCL profile FULL_PROFILE +[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX +[HW] Device 0 is available +[HW] Device 0, type 2 = 0x00000002: cpu +[HW] Device 0, number of Compute Units: 8 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 8192 +[HW] Device 0, max Work Items size for dimension: 1 8192 +[HW] Device 0, max Work Items size for dimension: 2 8192 +[New Thread 0x7fffcc258700 (LWP 3945123)] +[New Thread 0x7fffc3e57700 (LWP 3945124)] +[New Thread 0x7fffcbe57700 (LWP 3945125)] +[New Thread 0x7fffcba56700 (LWP 3945126)] +[New Thread 0x7fffcb254700 (LWP 3945128)] +[New Thread 0x7fffcb655700 (LWP 3945127)] +[New Thread 0x7fffcae53700 (LWP 3945129)] +[HW] Platform 1, OpenCL profile FULL_PROFILE +[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3 +[New Thread 0x7fffc965a700 (LWP 3945130)] +[Thread 0x7fffc965a700 (LWP 3945130) exited] +[HW] Device 0 is available +[HW] Device 0, type 4 = 0x00000004: gpu +[HW] Device 0, number of Compute Units: 20 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 512 +[HW] Device 0, max Work Items size for dimension: 1 512 +[HW] Device 0, max Work Items size for dimension: 2 512 +----------------------------------------------------------------- +``` + +`./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa -O libconfig:/usr/local/oai/conf/nrue_sim.conf:dbgl5 --nokrnmod --loader.ldpc.shlibversion _cl --log_config.hw_log_level info` + +```[CONFIG] shlibversion set to _cl from command line +............................................................ +[CONFIG] loader.ldpc 1 options set from command line +[LOADER] library libldpc_cl.so successfully loaded +[HW] Platform 0, OpenCL profile FULL_PROFILE +[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX +[HW] Device 0 is available +[HW] Device 0, type 2 = 0x00000002: cpu +[HW] Device 0, number of Compute Units: 8 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 8192 +[HW] Device 0, max Work Items size for dimension: 1 8192 +[HW] Device 0, max Work Items size for dimension: 2 8192 +[New Thread 0x7fffecccc700 (LWP 3945413)] +[New Thread 0x7fffec8cb700 (LWP 3945415)] +[New Thread 0x7fffec4ca700 (LWP 3945414)] +[New Thread 0x7fffdf7fd700 (LWP 3945417)] +[New Thread 0x7fffdfbfe700 (LWP 3945418)] +[New Thread 0x7fffdffff700 (LWP 3945416)] +[New Thread 0x7fffd73fc700 (LWP 3945419)] +[HW] Platform 1, OpenCL profile FULL_PROFILE +[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3 +[New Thread 0x7fffde105700 (LWP 3945420)] +[Thread 0x7fffde105700 (LWP 3945420) exited] +[HW] Device 0 is available +[HW] Device 0, type 4 = 0x00000004: gpu +[HW] Device 0, number of Compute Units: 20 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 512 +[HW] Device 0, max Work Items size for dimension: 1 512 +[HW] Device 0, max Work Items size for dimension: 2 512 +------------------------------------------------------------ +​``` +``` + +A mechanism to select ldpc implementation is also available in the `ldpctest` phy simulator via the `-v`option, which can be used to specify the version of the ldpc shared library to be used. + +#### Examples of ldpc shared lib selection when running ldpctest: + +Loading libldpc_cuda.so, the cuda implementation of the ldpc decoder: + +```$ ./ldpctest -v _cuda +Initializing random number generator, seed 0 +block length 8448: +n_trials 1: +SNR0 -2.000000: +[CONFIG] get parameters from cmdline , debug flags: 0x00400000 +[CONFIG] log_config: 2/3 parameters successfully set +[CONFIG] log_config: 53/53 parameters successfully set +[CONFIG] log_config: 53/53 parameters successfully set +[CONFIG] log_config: 16/16 parameters successfully set +[CONFIG] log_config: 16/16 parameters successfully set +log init done +[CONFIG] loader: 2/2 parameters successfully set +[CONFIG] loader.ldpc: 1/2 parameters successfully set +[LOADER] library libldpc_cuda.so successfully loaded +................................... +​``` +``` + +Loading libldpc_cl.so, the opencl implementation of the ldpc decoder: + +`make ldpc_cl` + +`cp ../../../openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl` + +`./ldpctest -v _cl` + +```$ ./ldpctest -v _cl +Initializing random number generator, seed 0 +block length 8448: +n_trials 1: +SNR0 -2.000000: +[CONFIG] get parameters from cmdline , debug flags: 0x00400000 +[CONFIG] log_config: 2/3 parameters successfully set +[CONFIG] log_config: 53/53 parameters successfully set +[CONFIG] log_config: 53/53 parameters successfully set +[CONFIG] log_config: 16/16 parameters successfully set +[CONFIG] log_config: 16/16 parameters successfully set +log init done +[CONFIG] loader: 2/2 parameters successfully set +[CONFIG] loader.ldpc: 1/2 parameters successfully set +[LOADER] library libldpc_cl.so successfully loaded +[HW] Platform 0, OpenCL profile FULL_PROFILE +[HW] Platform 0, OpenCL version OpenCL 2.1 LINUX +[HW] Device 0 is available +[HW] Device 0, type 2 = 0x00000002: cpu +[HW] Device 0, number of Compute Units: 8 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 8192 +[HW] Device 0, max Work Items size for dimension: 1 8192 +[HW] Device 0, max Work Items size for dimension: 2 8192 +[HW] Platform 1, OpenCL profile FULL_PROFILE +[HW] Platform 1, OpenCL version OpenCL 2.0 beignet 1.3 +[HW] Device 0 is available +[HW] Device 0, type 4 = 0x00000004: gpu +[HW] Device 0, number of Compute Units: 20 +[HW] Device 0, max Work Items dimension: 3 +[HW] Device 0, max Work Items size for dimension: 0 512 +[HW] Device 0, max Work Items size for dimension: 1 512 +[HW] Device 0, max Work Items size for dimension: 2 512 +................................ +​``` +``` + + + +### LDPC libraries +Libraries implementing the LDPC algorithms must be named `libldpc<_version>.so`, they must implement three functions: `nrLDPC_initcall` `nrLDPC_decod` and `nrLDPC_encod`. The prototypes for these functions is defined in [nrLDPC_defs.h](file://nrLDPC_defs.h). + +`libldpc_cuda.so`has been tested with the `ldpctest` executable, usage from the softmodem's has to be tested. + +`libldpc_cl`is under development. [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 91c5d59611..aff707a1d5 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -101,8 +101,8 @@ int test_ldpc(short No_iteration, unsigned int *crc_misses, time_stats_t *time_optim, time_stats_t *time_decoder, - n_iter_stats_t *dec_iter, - short run_cuda) + n_iter_stats_t *dec_iter + ) { //clock initiate //time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder; @@ -393,28 +393,13 @@ int test_ldpc(short No_iteration, decParams.R=code_rate_vec[R_ind];//13; decParams.numMaxIter=No_iteration; decParams.outMode = nrLDPC_outMode_BIT; + decParams.block_length=block_length; //decParams.outMode =nrLDPC_outMode_LLRINT8; -#ifdef CUDA_FLAG - set_compact_BG(Zc,BG); - init_LLR_DMA_for_CUDA(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], block_length); -#endif + nrLDPC_initcall(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j]); for(j=0;j 1280, 2401 -> 2560 - + char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */ short No_iteration=5; int n_segments=1; //double rate=0.333; - short run_cuda = 0; int nom_rate=1; int denom_rate=3; @@ -544,7 +526,7 @@ int main(int argc, char *argv[]) short BG=0,Zc,Kb=0; - while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:h")) != -1) + while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1) switch (c) { case 'q': @@ -564,7 +546,7 @@ int main(int argc, char *argv[]) break; case 'G': - run_cuda = atoi(optarg); + ldpc_version="_cuda"; break; case 'n': @@ -590,9 +572,11 @@ int main(int argc, char *argv[]) case 'u': test_uncoded = atoi(optarg); break; - + case 'v': + ldpc_version=strdup(optarg); + break; case 'h': - default: + default: printf("CURRENTLY SUPPORTED CODE RATES: \n"); printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n"); printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n"); @@ -609,6 +593,7 @@ int main(int argc, char *argv[]) printf("-t SNR simulation step, Default: 0.1\n"); printf("-i Max decoder iterations, Default: 5\n"); printf("-u Set SNR per coded bit, Default: 0\n"); + printf("-v XXX Set ldpc shared library version. libldpc_XXX.so will be used \n"); exit(1); break; } @@ -619,7 +604,10 @@ int main(int argc, char *argv[]) printf("SNR0 %f: \n", SNR0); - load_nrLDPClib(); + if (ldpc_version != NULL) + load_nrLDPClib(ldpc_version); + else + load_nrLDPClib(NULL); load_nrLDPClib_ref("_orig", &encoder_orig); //for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8) @@ -691,8 +679,7 @@ int main(int argc, char *argv[]) &crc_misses, time_optim, time_decoder, - dec_iter, - run_cuda); + dec_iter); printf("SNR %f, BLER %f (%u/%d)\n", SNR, (float)decoded_errors[i]/(float)n_trials, decoded_errors[i], n_trials); printf("SNR %f, BER %f (%u/%d)\n", SNR, (float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments, decoded_errors[i], n_trials); diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c index 587b2bceaa..166cd9a5a3 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c @@ -46,7 +46,8 @@ #endif static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler); - +void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { +} int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats* p_profiler) { uint32_t numLLR; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c new file mode 100644 index 0000000000..58e6b507af --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c @@ -0,0 +1,436 @@ +/* + * 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.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file nrLDPC_decoder_CL.c +* \brief ldpc decoder, openCL implementaion +* \author Francois TABURET +* \date 2021 +* \version 1.0 +* \note initial implem - translation of cuda version +*/ +/* uses HW component id for log messages ( --log_config.hw_log_level ) */ +#include +#include +#include +#include +#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h" +#include "assertions.h" +#include "common/utils/LOG/log.h" + +#define MAX_ITERATION 2 +#define MC 1 + +#define MAX_OCLDEV 10 +#define MAX_OCLRUNTIME 5 + + +#define CLSETKERNELARG(A,B,C,D) \ +rt=clSetKernelArg(A,B,C,D) ;\ +AssertFatal(rt == CL_SUCCESS, "Error %d setting kernel argument index %d\n" , (int)rt, B); + +typedef struct{ + char x; + char y; + short value; +} h_element; +#include "../nrLDPC_decoder_LYC/bgs/BG1_compact_in_C.h" + +typedef struct{ + cl_uint max_CU; + cl_uint max_WID; + size_t *max_WIS; +} ocldev_t; + +typedef struct { + cl_kernel cnp_kernel_1st; + cl_kernel cnp_kernel; + cl_kernel vnp_kernel_normal; + cl_kernel pack_decoded_bit; +} oclkernels_t; + +typedef struct{ + cl_uint num_devices; + cl_device_id devices[MAX_OCLDEV]; + ocldev_t ocldev[MAX_OCLDEV]; + cl_context context; + cl_program program; + cl_mem dev_h_compact1; + cl_mem dev_h_compact2; + cl_mem dev_const_llr; + cl_mem dev_llr; + cl_mem dev_dt; + cl_mem dev_tmp; + oclkernels_t kernels[MAX_OCLDEV]; + cl_command_queue queue[MAX_OCLDEV]; +} oclruntime_t; + +typedef struct{ + oclruntime_t runtime[MAX_OCLRUNTIME]; +} ocl_t; + + + +ocl_t ocl; + + +void set_compact_BG(int Zc,short BG){ + cl_uint rt; + int row,col; + if(BG == 1){ + row = 46; + col = 68; + } + else{ + row = 42; + col = 52; + } + int compact_row = 30; + int compact_col = 19; + if(BG==2){compact_row = 10, compact_col = 23;} + int memorySize_h_compact1 = row * compact_col * sizeof(h_element); + int memorySize_h_compact2 = compact_row * col * sizeof(h_element); + int lift_index = 0; + short lift_set[][9] = { + {2,4,8,16,32,64,128,256}, + {3,6,12,24,48,96,192,384}, + {5,10,20,40,80,160,320}, + {7,14,28,56,112,224}, + {9,18,36,72,144,288}, + {11,22,44,88,176,352}, + {13,26,52,104,208}, + {15,30,60,120,240}, + {0} + }; + + for(int i = 0; lift_set[i][0] != 0; i++){ + for(int j = 0; lift_set[i][j] != 0; j++){ + if(Zc == lift_set[i][j]){ + lift_index = i; + break; + } + } + } + printf("\nZc = %d BG = %d\n",Zc,BG); + ocl.runtime[0].dev_h_compact1 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact1, NULL, (cl_int *)&rt); + AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact1 for platform %i \n" , (int)rt, 0); + ocl.runtime[0].dev_h_compact2 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact2, NULL, (cl_int *)&rt); + AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact2 for platform %i \n" , (int)rt, 0); + h_element *h1; + h_element *h2; + switch(lift_index){ + case 0: + h1 = host_h_compact1_I0; + h2 = host_h_compact2_I0; + break; + case 1: + h1 = host_h_compact1_I1; + h2 = host_h_compact2_I1; + break; + case 2: + h1 = host_h_compact1_I2; + h2 = host_h_compact2_I2; + break; + case 3: + h1 = host_h_compact1_I3; + h2 = host_h_compact2_I3; + break; + case 4: + h1 = host_h_compact1_I4; + h2 = host_h_compact2_I4; + break; + case 5: + h1 = host_h_compact1_I5; + h2 = host_h_compact2_I5; + break; + case 6: + h1 = host_h_compact1_I6; + h2 = host_h_compact2_I6; + break; + case 7: + h1 = host_h_compact1_I7; + h2 = host_h_compact2_I7; + break; + default: + AssertFatal(0, "Invalid lift_index value %i\n" , lift_index); + break; + } + rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_h_compact1, CL_TRUE, 0,memorySize_h_compact1, h1, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving h_compact1 memory to pltf %i dev %i\n" , (int)rt, 0,0); + rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_h_compact2, CL_TRUE, 0,memorySize_h_compact2, h2, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving h_compact2 memory to pltf %i dev %i\n" , (int)rt, 0,0); + // return 0; +} +void cl_error_callback(const char* errinfo, const void* private_info, size_t cb, void* user_data) { + oclruntime_t *runtime = (oclruntime_t *)user_data; + LOG_E(HW,"OpenCL accelerator error %s\n", errinfo ); +} + +char *clutil_getstrdev(int intdev) { + static char retstring[255]=""; + char *retptr=retstring; + retptr+=sprintf(retptr,"0x%08x: ",(uint32_t)intdev); + if (intdev & CL_DEVICE_TYPE_CPU) + retptr+=sprintf(retptr,"%s","cpu "); + if (intdev & CL_DEVICE_TYPE_GPU) + retptr+=sprintf(retptr,"%s","gpu "); + if (intdev & CL_DEVICE_TYPE_ACCELERATOR) + retptr+=sprintf(retptr,"%s","acc "); + return retstring; +} + +void get_CompilErr(cl_program program, int pltf) { + + // Determine the size of the log + size_t log_size; + for(int i=0; i0 , "clGetPlatformIDs: no cl compatible platform found\n"); + for (int i=0 ; i<(int)num_platforms_found ; i++) { + char stringval[255]; + rt = clGetPlatformInfo(platforms[i],CL_PLATFORM_PROFILE, sizeof(stringval),stringval,NULL); + AssertFatal(rt == CL_SUCCESS, "clGetPlatformInfo PROFILE error %d\n" , (int)rt); + LOG_I(HW,"Platform %i, OpenCL profile %s\n", i,stringval ); + rt = clGetPlatformInfo(platforms[i],CL_PLATFORM_VERSION, sizeof(stringval),stringval,NULL); + AssertFatal(rt == CL_SUCCESS, "clGetPlatformInfo VERSION error %d\n" , (int)rt); + LOG_I(HW,"Platform %i, OpenCL version %s\n", i,stringval ); + rt = clGetDeviceIDs(platforms[i],CL_DEVICE_TYPE_ALL, sizeof(ocl.runtime[i].devices)/sizeof(cl_device_id),ocl.runtime[i].devices,&(ocl.runtime[i].num_devices)); + AssertFatal(rt == CL_SUCCESS, "clGetDeviceIDs error %d\n" , (int)rt); + int devok=0; + for (int j=0; j0) { + ocl.runtime[i].context = clCreateContext(NULL, ocl.runtime[i].num_devices, ocl.runtime[i].devices, cl_error_callback, &(ocl.runtime[i]), (cl_int *)&rt); + AssertFatal(rt == CL_SUCCESS, "Error %d creating context for platform %i\n" , (int)rt, i); + for(int dev=0; dev0, "No openCL device available to accelerate ldpc\n"); + return 0; +} + + +void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { + set_compact_BG(p_decParams->Z,p_decParams->BG); +// init_LLR_DMA(p_decParams, p_llr, p_out); +} + + +int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder) +{ + uint16_t Zc = p_decParams->Z; + uint8_t BG = p_decParams->BG; +// uint8_t numMaxIter = p_decParams->numMaxIter; + int block_length = p_decParams->block_length; +// e_nrLDPC_outMode outMode = p_decParams->outMode; + uint8_t row,col; + if(BG == 1){ + row = 46; + col = 68; + } + else{ + row = 42; + col = 52; + } + +// alloc memory +// unsigned char *hard_decision = (unsigned char*)p_out; +// gpu + int memorySize_llr = col * Zc * sizeof(char) * MC; +// cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) ); +// cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) ); + int rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_const_llr, CL_TRUE, 0, + memorySize_llr, p_llr, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read only memory in pltf %i dev %i\n" , (int)rt, 0,0); + rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_llr, CL_TRUE, 0, + memorySize_llr, p_llr, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read-write memory in pltf %i dev %i\n" , (int)rt, 0,0); +// Define CUDA kernel dimension +// int blockSizeX = Zc; +// dim3 dimGridKernel1(row, MC, 1); // dim of the thread blocks +// dim3 dimBlockKernel1(blockSizeX, 1, 1); + +// dim3 dimGridKernel2(col, MC, 1); +// dim3 dimBlockKernel2(blockSizeX, 1, 1); +// cudaDeviceSynchronize(); + +// lauch kernel + size_t global_item_sizek0[2] = {row*Zc,MC}; // Process the entire lists + size_t global_item_sizek1[2] = {col*Zc,MC}; // Process the entire lists + size_t local_item_sizek[2] = {128,1}; // Divide work items into groups of 128 + + for(int ii = 0; ii < MAX_ITERATION; ii++){ + // first kernel + if(ii == 0){ +// ldpc_cnp_kernel_1st_iter +// <<>> +// ( BG, row, col, Zc); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact1)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 3, sizeof(int), (void *)&(BG)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 4, sizeof(int), (void *)&(row)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 5, sizeof(int), (void *)&(col)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel_1st, 6, sizeof(int), (void *)&(Zc)); + rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].cnp_kernel_1st, 2, NULL, + global_item_sizek0, local_item_sizek, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d enqueing cnp_kernel_1st \n" , (int)rt); + }else{ +// ldpc_cnp_kernel +// <<>> +// ( BG, row, col, Zc); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact1)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 3, sizeof(int), (void *)&(BG)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 4, sizeof(int), (void *)&(row)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 5, sizeof(int), (void *)&(col)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].cnp_kernel, 6, sizeof(int), (void *)&(Zc)); + rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].cnp_kernel, 2, NULL, + global_item_sizek0, local_item_sizek, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d enqueing cnp_kernel\n" , (int)rt); + } + // second kernel +// ldpc_vnp_kernel_normal +// <<>> +// // (dev_llr, dev_const_llr,BG, row, col, Zc); +// (BG, row, col, Zc); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_dt)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 2, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_const_llr)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 3, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_h_compact2)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 4, sizeof(int), (void *)&(BG)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 5, sizeof(int), (void *)&(row)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 6, sizeof(int), (void *)&(col)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].vnp_kernel_normal, 7, sizeof(int), (void *)&(Zc)); + rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].vnp_kernel_normal, 2, NULL, + global_item_sizek1, local_item_sizek, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d enqueing vnp_kernel_normal \n" , (int)rt); + } + +// int pack = (block_length/128)+1; +// dim3 pack_block(pack, MC, 1); +// pack_decoded_bit<<>>( col, Zc); + CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 0, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_llr)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 1, sizeof(cl_mem), (void *)&(ocl.runtime[0].dev_tmp)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 2, sizeof(int), (void *)&(col)); + CLSETKERNELARG(ocl.runtime[0].kernels[0].pack_decoded_bit, 3, sizeof(int), (void *)&(Zc)); + + // Execute the OpenCL kernel on the list + size_t global_item_size[2] = {block_length,MC}; // Process the entire lists + size_t local_item_size[2] = {128,1}; // Divide work items into groups of 128 + rt = clEnqueueNDRangeKernel(ocl.runtime[0].queue[0], ocl.runtime[0].kernels[0].pack_decoded_bit, 2, NULL, + global_item_size, local_item_size, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d enqueing pack_decoded_bit \n" , (int)rt); +// cudaCheck( cudaMemcpyFromSymbol((void*)hard_decision, (const void*)dev_tmp, (block_length/8)*sizeof(unsigned char)) ); +// cudaDeviceSynchronize(); + + rt = clEnqueueReadBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_tmp, CL_TRUE, 0, + (block_length/8)*sizeof(unsigned char) , p_llr, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to pltf %i dev %i\n" , (int)rt, 0,0); + return MAX_ITERATION; + +} diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl new file mode 100644 index 0000000000..d5e2fa5695 --- /dev/null +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_kernels_CL.cl @@ -0,0 +1,302 @@ +/* + * 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.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/CODING/nrLDPC_decoder_kernels_CL.cl +* \brief kernel functions for ldpc decoder accelerated via openCL +* \author Francois TABURET +* \date 2021 +* \version 1.0 +* \company Nokia BellLabs France +* \email: francois.taburet@nokia-bell-labs.com +* \note initial implem - translation of cuda version +* \warning +*/ +#define define MAX_ITERATION 2 +#define MC 1 + +#define INT32_MAX 2147483647 + +typedef struct{ + char x; + char y; + short value; +} h_element; + +//__global char dev_dt [46*68*384]; +//__local char *dev_t; +//__global char dev_llr[68*384]; +//__global unsigned char dev_tmp[68*384]; + + + + +//__constant h_element dev_h_compact1[46*19] = {}; // used in kernel 1 +//__constant h_element dev_h_compact2[68*30] = {}; // used in kernel 2 + +// __device__ __constantant__ h_element dev_h_compact1[46*19]; // used in kernel 1 +// __device__ __constantant__ h_element dev_h_compact2[68*30]; // used in kernel 2 + +// row and col element count +__constant char h_ele_row_bg1_count[46] = { + 19, 19, 19, 19, 3, 8, 9, 7, 10, 9, + 7, 8, 7, 6, 7, 7, 6, 6, 6, 6, + 6, 6, 5, 5, 6, 5, 5, 4, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, + 4, 5, 4, 5, 5, 4}; +__constant char h_ele_col_bg1_count[68] = { + 30, 28, 7, 11, 9, 4, 8, 12, 8, 7, + 12, 10, 12, 11, 10, 7, 10, 10, 13, 7, + 8, 11, 12, 5, 6, 6, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1}; +__constant char h_ele_row_bg2_count[42] = { + 8, 10, 8, 10, 4, 6, 6, 6, 4, 5, + 5, 5, 4, 5, 5, 4, 5, 5, 4, 4, + 4, 4, 3, 4, 4, 3, 5, 3, 4, 3, + 5, 3, 4, 4, 4, 4, 4, 3, 4, 4, + 4, 4}; +__constant char h_ele_col_bg2_count[52] = { + 22, 23, 10, 5, 5, 14, 7, 13, 6, 8, + 9, 16, 9, 12, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1}; + + + +// Kernel 1 +__kernel void ldpc_cnp_kernel_1st_iter( __global char * dev_llr, __global char * dev_dt, __local h_element *dev_h_compact1, int BG, int row, int col, int Zc) +{ +// int iMCW = blockIdx.y; // codeword id +// int iBlkRow = blockIdx.x; // block row in h_base +// int iSubRow = threadIdx.x; // row index in sub_block of h_base +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp %d\n", threadIdx.x); + int iMCW = get_group_id(1); // codeword id + int iBlkRow = get_group_id(0); // block row in h_base + int iBlkCol; // block col in h_base + int iSubRow = get_local_id(0);; // row index in sub_block of h_base + int iCol; // overall col index in h_base + int offsetR; + int shift_t; + +// For 2-min algorithm. + int Q_sign = 0; + int sq; + int Q, Q_abs; + int R_temp; + + int sign = 1; + int rmin1 = INT32_MAX; + int rmin2 = INT32_MAX; + char idx_min = 0; + + h_element h_element_t; + int s = (BG==1)? h_ele_row_bg1_count[iBlkRow]:h_ele_row_bg2_count[iBlkRow]; + offsetR = (iMCW * row*col*Zc) + iBlkRow * Zc + iSubRow; // row*col*Zc = size of dev_dt +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("s: %d, offset %d\n", s, offsetR); +// The 1st recursion + for(int i = 0; i < s; i++) // loop through all the ZxZ sub-blocks in a row + { + h_element_t = dev_h_compact1[i*row+iBlkRow]; // compact_col == row + + iBlkCol = h_element_t.y; + shift_t = h_element_t.value; + + shift_t = (iSubRow + shift_t) % Zc; + iCol = (iMCW * col*Zc) + iBlkCol * Zc + shift_t; // col*Zc = size of llr + Q = dev_llr[iCol]; + Q_abs = (Q>0)? Q : -Q; + sq = Q < 0; +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("i %d, icol %d, Q: %d\n", i, iCol, Q); + // quick version + sign = sign * (1 - sq * 2); + Q_sign |= sq << i; + + if (Q_abs < rmin1){ + rmin2 = rmin1; + rmin1 = Q_abs; + idx_min = i; + } else if (Q_abs < rmin2){ + rmin2 = Q_abs; + } + } + +// if(blockIdx.x == 0 && threadIdx.x == 1)printf("min1 %d, min2 %d, min1_idx %d\n", rmin1, rmin2, idx_min); + +// The 2nd recursion + for(int i = 0; i < s; i++){ + // v0: Best performance so far. 0.75f is the value of alpha. + sq = 1 - 2 * ((Q_sign >> i) & 0x01); + R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2); + // write results to global memory + h_element_t = dev_h_compact1[i*row+iBlkRow]; + int addr_temp = offsetR + h_element_t.y * row * Zc; + dev_dt[addr_temp] = R_temp; +// if(blockIdx.x == 0 && threadIdx.x == 1)printf("R_temp %d, temp_addr %d\n", R_temp, addr_temp); + } +} + +// Kernel_1 +__kernel void ldpc_cnp_kernel( __global char * dev_llr, __global char * dev_dt, __local h_element *dev_h_compact1, int BG, int row, int col, int Zc) +{ +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("cnp\n"); +// int iMCW = blockIdx.y; +// int iBlkRow = blockIdx.x; // block row in h_base // block col in h_base +// int iSubRow = threadIdx.x; // row index in sub_block of h_base + int iMCW = get_group_id(1); + int iBlkRow = get_group_id(0); // block row in h_base + int iBlkCol; // block col in h_base + int iSubRow = get_local_id(0);; // row index in sub_block of h_base + int iCol; // overall col index in h_base + int offsetR; + int shift_t; + +// For 2-min algorithm. + int Q_sign = 0; + int sq; + int Q, Q_abs; + int R_temp; + + int sign = 1; + int rmin1 = INT32_MAX; + int rmin2 = INT32_MAX; + char idx_min = 0; + + h_element h_element_t; + int s = (BG==1)? h_ele_row_bg1_count[iBlkRow]: h_ele_row_bg2_count[iBlkRow]; + offsetR = (iMCW *row*col*Zc) + iBlkRow * Zc + iSubRow; // row * col * Zc = size of dev_dt +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("s: %d, offset %d\n", s, offsetR); +// The 1st recursion + for(int i = 0; i < s; i++) // loop through all the ZxZ sub-blocks in a row + { + h_element_t = dev_h_compact1[i*row+iBlkRow]; + + iBlkCol = h_element_t.y; + shift_t = h_element_t.value; + shift_t = (iSubRow + shift_t) % Zc; + iCol = iBlkCol * Zc + shift_t; + + R_temp = dev_dt[offsetR + iBlkCol * row * Zc]; + + Q = dev_llr[iMCW * (col*Zc) + iCol] - R_temp; + Q_abs = (Q>0)? Q : -Q; +// if(blockIdx.x == 0 && threadIdx.x == 1) printf("i %d, icol %d, Q: %d\n", i, iCol, Q); + sq = Q < 0; + sign = sign * (1 - sq * 2); + Q_sign |= sq << i; + + if (Q_abs < rmin1){ + rmin2 = rmin1; + rmin1 = Q_abs; + idx_min = i; + } else if (Q_abs < rmin2){ + rmin2 = Q_abs; + } + + } + +// if(blockIdx.x == 0 && threadIdx.x == 1)printf("min1 %d, min2 %d, min1_idx %d\n", rmin1, rmin2, idx_min); + +// The 2nd recursion + for(int i = 0; i < s; i ++){ + sq = 1 - 2 * ((Q_sign >> i) & 0x01); + R_temp = 0.75f * sign * sq * (i != idx_min ? rmin1 : rmin2); + + + // write results to global memory + h_element_t = dev_h_compact1[i*row+iBlkRow]; + int addr_temp = h_element_t.y * row * Zc + offsetR; + dev_dt[addr_temp] = R_temp; +// if(blockIdx.x == 0 && threadIdx.x == 1)printf("R_temp %d, temp_addr %d\n", R_temp, addr_temp); + } +} + +// Kernel 2: VNP processing +__kernel void +ldpc_vnp_kernel_normal(__global char * dev_llr, __global char * dev_dt, __global char * dev_const_llr, __local h_element *dev_h_compact2, int BG, int row, int col, int Zc) +{ +// int iMCW = blockIdx.y; +// int iBlkCol = blockIdx.x; +// int iSubCol = threadIdx.x; + int iMCW = get_group_id(1); + int iBlkCol = get_group_id(0); + int iBlkRow; + int iSubCol = get_local_id(0); + int iRow; + int iCol; + + int shift_t, sf; + int APP; + + h_element h_element_t; + + // update all the llr values + iCol = iBlkCol * Zc + iSubCol; + APP = dev_const_llr[iMCW *col*Zc + iCol]; + int offsetDt = iMCW *row*col*Zc + iBlkCol * row * Zc; + int s = (BG==1)? h_ele_col_bg1_count[iBlkCol]:h_ele_col_bg2_count[iBlkCol]; + + for(int i = 0; i < s; i++) + { + h_element_t = dev_h_compact2[i*col+iBlkCol]; + + shift_t = h_element_t.value%Zc; + iBlkRow = h_element_t.x; + + sf = iSubCol - shift_t; + sf = (sf + Zc) % Zc; + + iRow = iBlkRow * Zc + sf; + APP = APP + dev_dt[offsetDt + iRow]; + } + if(APP > SCHAR_MAX) APP = SCHAR_MAX; + if(APP < SCHAR_MIN) APP = SCHAR_MIN; + // write back to device global memory + dev_llr[iMCW *col*Zc + iCol] = APP; +} + + +__kernel void pack_decoded_bit(__global unsigned char * dev_llr, __global unsigned char * dev_tmp, int col, int Zc) +{ +// int iMCW = blockIdx.y; +// int btid = threadIdx.x; + unsigned char tmp[128]; + int iMCW = get_group_id(1); + int btid = get_local_id(0); + int tid = iMCW * col*Zc + get_group_id(0)*128 + btid; + tmp[btid] = 0; + + if(dev_llr[tid] < 0){ + tmp[btid] = 1 << (7-(btid&7)); + } +// __syncthreads(); + + if(btid < 16){ + dev_tmp[iMCW * col*Zc + get_group_id(0)*16+btid] = 0; + for(int i = 0; i < 8; i++){ + dev_tmp[iMCW * col*Zc + get_group_id(0)*16+btid] += tmp[btid*8+i]; + } + } +} + diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index e5b99246d5..99b6f75f93 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -70,6 +70,7 @@ typedef struct nrLDPC_dec_params { uint16_t Z; /**< Lifting size */ uint8_t R; /**< Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */ uint8_t numMaxIter; /**< Maximum number of iterations */ + int block_length; e_nrLDPC_outMode outMode; /**< Output format */ } t_nrLDPC_dec_params; diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu index 931d500338..72517edcdd 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu +++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu @@ -7,14 +7,14 @@ * \note * \warning */ - +#include #include #include #include #include #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h" - +#include "assertions.h" #include "bgs/BG1_I0" #include "bgs/BG1_I1" #include "bgs/BG1_I2" @@ -462,10 +462,11 @@ void read_BG(int BG, int *h, int row, int col) } extern "C" -void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length){ +void init_LLR_DMA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out){ uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; + int block_length = p_decParams->block_length; uint8_t row,col; if(BG == 1){ row = 46; @@ -483,14 +484,60 @@ void init_LLR_DMA_for_CUDA(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8 } +using namespace std ; + +/* from here: entry points in decoder shared lib */ extern "C" -int32_t nrLDPC_decoder_LYC(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out, int block_length, time_stats_t *time_decoder) +int ldpc_autoinit(void) { // called by the library loader +/*int devices = 0; + + cudaError_t err = cudaGetDeviceCount(&devices); + AssertFatal(devices>0,"\nNo cuda GPU found\n\n"); + + const int kb = 1024; + const int mb = kb * kb; + wcout << "NBody.GPU" << endl << "=========" << endl << endl; + + wcout << "CUDA version: v" << CUDART_VERSION << endl; + + + wcout << "CUDA Devices: " << endl << endl; + + for(int i = 0; i < devices; ++i) + { + cudaDeviceProp props; + cudaGetDeviceProperties(&props, i); + wcout << i << ": " << props.name << ": " << props.major << "." << props.minor << endl; + wcout << " Global memory: " << props.totalGlobalMem / mb << "mb" << endl; + wcout << " Shared memory: " << props.sharedMemPerBlock / kb << "kb" << endl; + wcout << " Constant memory: " << props.totalConstMem / kb << "kb" << endl; + wcout << " Block registers: " << props.regsPerBlock << endl << endl; + + wcout << " Warp size: " << props.warpSize << endl; + wcout << " Threads per block: " << props.maxThreadsPerBlock << endl; + wcout << " Max block dimensions: [ " << props.maxThreadsDim[0] << ", " << props.maxThreadsDim[1] << ", " << props.maxThreadsDim[2] << " ]" << endl; + wcout << " Max grid dimensions: [ " << props.maxGridSize[0] << ", " << props.maxGridSize[1] << ", " << props.maxGridSize[2] << " ]" << endl; + wcout << endl; + } +*/ + warmup_for_GPU(); + return 0; +} + +extern "C" +void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { + set_compact_BG(p_decParams->Z,p_decParams->BG); + init_LLR_DMA(p_decParams, p_llr, p_out); +} + + +extern "C" +int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder) { - - uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; uint8_t numMaxIter = p_decParams->numMaxIter; + int block_length = p_decParams->block_length; e_nrLDPC_outMode outMode = p_decParams->outMode; cudaError_t cudaStatus; uint8_t row,col; diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h index b96067f4b6..321ecaab7d 100644 --- a/openair1/PHY/CODING/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -45,6 +45,7 @@ typedef struct { time_stats_t *toutput; }encoder_implemparams_t; #define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL} +typedef void(*nrLDPC_initcallfunc_t)(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out); typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*); //============================================================================================================================ // decoder interface @@ -56,4 +57,4 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho \param p_profiler LDPC profiler statistics */ typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* ); -#endif \ No newline at end of file +#endif diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h index c0bfa0fdd8..b75b38fc76 100644 --- a/openair1/PHY/CODING/nrLDPC_extern.h +++ b/openair1/PHY/CODING/nrLDPC_extern.h @@ -23,13 +23,16 @@ #ifdef LDPC_LOADER nrLDPC_decoderfunc_t nrLDPC_decoder; nrLDPC_encoderfunc_t nrLDPC_encoder; +nrLDPC_initcallfunc_t nrLDPC_initcall; #else /* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */ -extern int load_nrLDPClib(void) ; +extern int load_nrLDPClib(char *version) ; extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest /* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */ +extern nrLDPC_initcallfunc_t nrLDPC_initcall; + extern nrLDPC_decoderfunc_t nrLDPC_decoder; extern nrLDPC_encoderfunc_t nrLDPC_encoder; // inline functions: #include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h" -#endif \ No newline at end of file +#endif diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c index a74bdf7bd1..23e5032bad 100644 --- a/openair1/PHY/CODING/nrLDPC_load.c +++ b/openair1/PHY/CODING/nrLDPC_load.c @@ -42,22 +42,32 @@ /* function description array, to be used when loading the encoding/decoding shared lib */ -static loader_shlibfunc_t shlib_fdesc[2]; +static loader_shlibfunc_t shlib_fdesc[3]; -char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0"}; +/* arguments used when called from phy simulators exec's which do not use the config module */ +/* arg is used to initialize the config module so that the loader works as expected */ +char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0",NULL,NULL}; -int load_nrLDPClib(void) { +int load_nrLDPClib(char *version) { char *ptr = (char*)config_get_if(); + char libname[64]="ldpc"; + if ( ptr==NULL ) {// phy simulators, config module possibly not loaded - load_configmodule(3,(char **)arg,CONFIG_ENABLECMDLINEONLY) ; + load_configmodule(0,(char **)NULL,CONFIG_ENABLECMDLINEONLY) ; logInit(); } shlib_fdesc[0].fname = "nrLDPC_decod"; shlib_fdesc[1].fname = "nrLDPC_encod"; - int ret=load_module_shlib("ldpc",shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); + shlib_fdesc[2].fname = "nrLDPC_initcall"; + int ret; + if (version) + ret=load_module_version_shlib(libname,version,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); + else + ret=load_module_shlib(libname,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL); AssertFatal( (ret >= 0),"Error loading ldpc decoder"); nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; + nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr; return 0; } @@ -65,10 +75,8 @@ int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_p loader_shlibfunc_t shlib_encoder_fdesc; shlib_encoder_fdesc.fname = "nrLDPC_encod"; - char libpath[64]; - sprintf(libpath,"ldpc%s",libversion); - int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL); - AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath); + int ret=load_module_version_shlib("ldpc",libversion,&shlib_encoder_fdesc,1,NULL); + AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",(libversion==NULL)?"":libversion); *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr; return 0; } diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index c0236f521f..cd4848ea8c 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -21,6 +21,7 @@ #include "executables/nr-softmodem-common.h" #include "common/utils/nr/nr_common.h" +#include "common/ran_context.h" #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -35,7 +36,6 @@ #include "MBSFN-SubframeConfigList.h"*/ #include "openair1/PHY/defs_RU.h" #include "openair1/PHY/CODING/nrLDPC_extern.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "assertions.h" #include @@ -108,7 +108,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, crcTableInit(); init_scrambling_luts(); init_pucch2_luts(); - load_nrLDPClib(); + load_nrLDPClib(NULL); // PBCH DMRS gold sequences generation nr_init_pbch_dmrs(gNB); //PDCCH DMRS init diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index f8c63c9deb..0920da667d 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -22,7 +22,6 @@ #include "phy_init.h" #include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" /// Subcarrier spacings in Hz indexed by numerology index uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 577a06ce5a..eb26dfc02b 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -129,18 +129,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, rxdata_ptr = (int16_t *)tmp_dft_in; } -#if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); -#endif dft(dftsize, rxdata_ptr, (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1); -#if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); -#endif int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset]; @@ -249,18 +245,14 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, } -#if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); -#endif dft(dftsize, rxdata_ptr, (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1); -#if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); -#endif int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index b58efb74f9..3dd44a7896 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -35,6 +35,7 @@ #include "nr_dlsch.h" #include "nr_sch_dmrs.h" #include "PHY/MODULATION/nr_modulation.h" +#include "common/utils/nr/nr_common.h" //#define DEBUG_PDCCH_DMRS //#define DEBUG_DCI diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index e3b53f9cf9..07baaf2728 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -59,6 +59,4 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *); -void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); - #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 57fbae4481..1675045443 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -31,6 +31,7 @@ */ #include "nr_dci.h" +#include "common/utils/nr/nr_common.h" //#define DEBUG_FILL_DCI diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index ecc2cded11..d75f97aa53 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -37,7 +37,7 @@ #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "common/utils/nr/nr_common.h" //#define DEBUG_DLSCH //#define DEBUG_DLSCH_MAPPING diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 9956e14701..acb59b0e40 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -39,10 +39,10 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "SCHED_NR/sched_nr.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/log.h" +#include "common/utils/nr/nr_common.h" #include #include diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c index a95c519d43..84118e8267 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c @@ -37,7 +37,6 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "T.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 1aef499189..4fed3a468f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -35,7 +35,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" #define NR_PBCH_PDU_BITS 24 @@ -315,6 +314,7 @@ int nr_find_pucch(uint16_t rnti, void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); void free_nr_ru_prach_entry(RU_t *ru, int prach_id); +uint8_t get_nr_prach_duration(uint8_t prach_format); void nr_generate_csi_rs(PHY_VARS_gNB *gNB, int16_t amp, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 96842426f5..cdc6825d4c 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -238,7 +238,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, // x_n contains the sequence r_u_v_alpha_delta(n) - int n,i,l; + int n,i; int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start}; nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,slot,&u[0],&v[0]); // calculating u and v value first hop @@ -266,14 +266,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, int64_t xrtmag=0,xrtmag_next=0; uint8_t maxpos=0; uint8_t index=0; - for (l=0; lnr_of_symbols; l++) { + for (int l=0; lnr_of_symbols; l++) { for (int aarx=0;aarxnb_antennas_rx;aarx++) { memset((void*)xr[aarx][l],0,24*sizeof(int16_t)); } } int n2; - for (l=0; lnr_of_symbols; l++) { + for (int l=0; lnr_of_symbols; l++) { l2 = l+pucch_pdu->start_symbol_index; re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset; if (re_offset[l]>= frame_parms->ofdm_symbol_size) @@ -300,11 +300,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, //int32_t no_corr = 0; int seq_index; int64_t temp; - int64_t av_corr=0; for(i=0;inr_of_symbols;l++) { + for (int l=0;lnr_of_symbols;l++) { seq_index = (pucch_pdu->initial_cyclic_shift+ mcs[i]+ gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12; @@ -322,26 +321,30 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, } } } - LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[0][0],corr_im[0][0],10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0])); - if (l>1) LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[0][1],corr_im[0][1],10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1])); - if (pucch_pdu->freq_hop_flag == 0 && l==1) {// non-coherent correlation - temp=0; - for (int aa=0;aanb_antennas_rx;aa++) - temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]; - } - - else if (pucch_pdu->freq_hop_flag == 0 && l==2) { - int64_t corr_re2=0; - int64_t corr_im2=0; - temp=0; - for (int aa=0;aanb_antennas_rx;aa++) { - corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1]; - corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1]; - // coherent combining of 2 symbols and then complex modulus for single-frequency case - temp+=corr_re2*corr_re2 + corr_im2*corr_im2; - } - } - else if (pucch_pdu->freq_hop_flag == 1) { + LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n", + mcs[i],seq_index,corr_re[0][0],corr_im[0][0], + 10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0])); + if (pucch_pdu->nr_of_symbols==2) + LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n", + mcs[i],seq_index,corr_re[0][1],corr_im[0][1], + 10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1])); + if (pucch_pdu->freq_hop_flag == 0) { + if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation + temp=0; + for (int aa=0;aanb_antennas_rx;aa++) + temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]; + } else { + int64_t corr_re2=0; + int64_t corr_im2=0; + temp=0; + for (int aa=0;aanb_antennas_rx;aa++) { + corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1]; + corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1]; + // coherent combining of 2 symbols and then complex modulus for single-frequency case + temp+=corr_re2*corr_re2 + corr_im2*corr_im2; + } + } + } else if (pucch_pdu->freq_hop_flag == 1) { // full non-coherent combining of 2 symbols for frequency-hopping case temp=0; for (int aa=0;aanb_antennas_rx;aa++) @@ -349,7 +352,6 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, } else AssertFatal(1==0,"shouldn't happen\n"); - av_corr+=temp; if (temp>xrtmag) { xrtmag_next = xrtmag; xrtmag=temp; @@ -359,19 +361,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, int64_t temp2=0,temp3=0;; for (int aa=0;aanb_antennas_rx;aa++) { temp2 += ((int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]); - if (l==2) temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]); + if (pucch_pdu->nr_of_symbols==2) + temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]); } uci_stats->current_pucch0_stat0= dB_fixed64(temp2); - if (l==2) uci_stats->current_pucch0_stat1= dB_fixed64(temp3); + if ( pucch_pdu->nr_of_symbols==2) + uci_stats->current_pucch0_stat1= dB_fixed64(temp3); } else if (temp>xrtmag_next) xrtmag_next = temp; } - av_corr/=nr_sequences/l; - - int xrtmag_dBtimes10 = 10*(int)dB_fixed64(xrtmag/(12*l)); - int xrtmag_next_dBtimes10 = 10*(int)dB_fixed64(xrtmag_next/(12*l)); + int xrtmag_dBtimes10 = 10*(int)dB_fixed64(xrtmag/(12*pucch_pdu->nr_of_symbols)); + int xrtmag_next_dBtimes10 = 10*(int)dB_fixed64(xrtmag_next/(12*pucch_pdu->nr_of_symbols)); #ifdef DEBUG_NR_PUCCH_RX printf("PUCCH 0 : maxpos %d\n",maxpos); #endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 44f1844ae9..7f6f0e8ef9 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -36,7 +36,6 @@ #include "PHY/phy_extern_nr_ue.h" #include "common/utils/LOG/log.h" #include "PHY/sse_intrin.h" -#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" //#define k1 1000 #define k1 ((long long int) 1000) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index a6dce88801..3afe27310f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -36,16 +36,14 @@ #include #endif -#include -#include -#include "executables/softmodem-common.h" +#include "executables/softmodem-common.h" #include "nr_transport_proto_ue.h" #include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h" #include "PHY/phy_extern_nr_ue.h" #include "PHY/CODING/coding_extern.h" #include "PHY/sse_intrin.h" -#include "PHY/NR_TRANSPORT/nr_dci.h" +#include "common/utils/nr/nr_common.h" #include "assertions.h" #include "T.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index fa09093306..8a4cafc6d7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -45,11 +45,6 @@ //#define DEBUG_HARQ -//#include "LAYER2/MAC/extern.h" -//#include "LAYER2/MAC/defs.h" -//#include "../openair2/LAYER2/MAC/extern.h" -//#include "../openair2/LAYER2/MAC/defs.h" - //#define DEBUG_DCI #define NR_PDCCH_DCI_TOOLS //#define NR_PDCCH_DCI_TOOLS_DEBUG diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 8ee5e13235..975d7077a0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -43,7 +43,7 @@ #include "SIMULATION/TOOLS/sim.h" #include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_extern.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "common/utils/nr/nr_common.h" //#define ENABLE_PHY_PAYLOAD_DEBUG 1 @@ -236,11 +236,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag) { -#if UE_TIMING_TRACE time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats; time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats; time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats; -#endif + uint32_t A,E; uint32_t G; uint32_t ret,offset; @@ -411,21 +410,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, for (r=0; rC; r++) { //printf("start rx segment %d\n",r); E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); -#if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN); nr_deinterleaving_ldpc(E, harq_process->Qm, harq_process->w[r], // [hna] w is e dlsch_llr+r_offset); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); -#endif -#if UE_TIMING_TRACE start_meas(dlsch_rate_unmatching_stats); -#endif LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,E %d, F %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G,E,harq_process->F, Kr*3, @@ -454,16 +447,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, E, harq_process->F, Kr-harq_process->F-2*(p_decParams->Z))==-1) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE - stop_meas(dlsch_rate_unmatching_stats); -#endif - LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); - return(dlsch->max_ldpc_iterations + 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); + stop_meas(dlsch_rate_unmatching_stats); + LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); + return(dlsch->max_ldpc_iterations + 1); } else { -#if UE_TIMING_TRACE - stop_meas(dlsch_rate_unmatching_stats); -#endif + stop_meas(dlsch_rate_unmatching_stats); } r_offset += E; @@ -492,9 +481,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } if (err_flag == 0) { -#if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); -#endif //set first 2*Z_c bits to zeros memset(&z[0],0,2*harq_process->Z*sizeof(int16_t)); //set Filler bits @@ -510,6 +497,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); + p_decParams->block_length=length_dec; + nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf); no_iteration_ldpc = nrLDPC_decoder(p_decParams, (int8_t *)&pl[0], llrProcBuf, @@ -545,13 +534,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) { for (int k=0; k>3; k++) LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); } -#if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); -#endif } if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; @@ -645,11 +631,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag) { -#if UE_TIMING_TRACE + time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats; time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats; time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats; -#endif uint32_t A,E; uint32_t G; uint32_t ret,offset; @@ -812,7 +797,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *res_dl; opp_enabled=1; - if (harq_process->C>1) { for (int nb_seg =1 ; nb_segC; nb_seg++) { if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) { @@ -867,9 +851,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, dlsch_llr+r_offset, &harq_process->w[r]); */ -#if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); -#endif nr_deinterleaving_ldpc(E, harq_process->Qm, harq_process->w[r], @@ -879,12 +861,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, for (int i =0; i<16; i++) LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); -#if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); -#endif -#if UE_TIMING_TRACE start_meas(dlsch_rate_unmatching_stats); -#endif if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", @@ -915,15 +893,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, E, harq_process->F, Kr-harq_process->F-2*(p_decParams->Z))==-1) { -#if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); -#endif LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); return(dlsch->max_ldpc_iterations); } else { -#if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); -#endif } if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) @@ -966,9 +940,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ -#if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); -#endif LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; @@ -986,7 +958,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } - + p_decParams->block_length=length_dec; + nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf); no_iteration_ldpc = nrLDPC_decoder(p_decParams, (int8_t *)&pl[0], llrProcBuf, @@ -1037,11 +1010,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, for (int k=0; k<32; k++) LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); -#if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); -#endif } + if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; @@ -1135,7 +1107,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } - void nr_dlsch_decoding_process(void *arg) { nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; @@ -1167,11 +1138,10 @@ void nr_dlsch_decoding_process(void *arg) { proc->instance_cnt_dlsch_td=-1; //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe; proc->decoder_thread_available = 1; -#if UE_TIMING_TRACE time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats; time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats; time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats; -#endif + uint32_t A,E; uint32_t G; uint32_t ret; @@ -1272,9 +1242,7 @@ void nr_dlsch_decoding_process(void *arg) { Kr_bytes = Kr>>3; K_bits_F = Kr-harq_process->F; E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); -#if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); -#endif nr_deinterleaving_ldpc(E, harq_process->Qm, harq_process->w[r], @@ -1284,13 +1252,8 @@ void nr_dlsch_decoding_process(void *arg) { for (int i =0; i<16; i++) LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); -#if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); -#endif -#if UE_TIMING_TRACE start_meas(dlsch_rate_unmatching_stats); -#endif - if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, @@ -1319,15 +1282,11 @@ void nr_dlsch_decoding_process(void *arg) { E, harq_process->F, Kr-harq_process->F-2*(p_decParams->Z))==-1) { -#if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); -#endif LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); //return(dlsch->max_ldpc_iterations); } else { -#if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); -#endif } if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) { @@ -1364,9 +1323,7 @@ void nr_dlsch_decoding_process(void *arg) { Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); } -#if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); -#endif // LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); /* for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ @@ -1386,7 +1343,8 @@ void nr_dlsch_decoding_process(void *arg) { for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } - + p_decParams->block_length=length_dec; + nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf); no_iteration_ldpc = nrLDPC_decoder(p_decParams, (int8_t *)&pl[0], llrProcBuf, @@ -1412,10 +1370,7 @@ void nr_dlsch_decoding_process(void *arg) { if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) for (int k=0; k<2; k++) LOG_D(PHY,"segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - -#if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); -#endif } if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index fb6e7bf6b5..031c08a72d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -41,6 +41,7 @@ #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_REFSIG/dmrs_nr.h" +#include "common/utils/nr/nr_common.h" #ifndef USER_MODE #define NOCYGWIN_STATIC static @@ -163,9 +164,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, // int avg_0[2]; // int avg_1[2]; -#if UE_TIMING_TRACE uint8_t slot = 0; -#endif unsigned char aatx=0,aarx=0; @@ -331,12 +330,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, DevAssert(dlsch1_harq); } -#if UE_TIMING_TRACE if(symbol > ue->frame_parms.symbols_per_slot>>1) { slot = 1; } -#endif #ifdef DEBUG_HARQ printf("Demod dlsch0_harq->pmi_alloc %d\n", dlsch0_harq->pmi_alloc); @@ -346,9 +343,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, uint8_t config_type = dlsch0_harq->dmrsConfigType; if (beamforming_mode==0) {//No beamforming -#if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif if (dlsch0_harq->Nl > 1)//More than or equal 2 layers nb_rb = nr_dlsch_extract_rbs_multiple(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[gNB_id]->dl_ch_estimates, @@ -389,7 +384,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12); -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n", @@ -398,11 +392,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n", frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif -#if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif n_tx = dlsch0_harq->Nl; n_rx = frame_parms->nb_antennas_rx; @@ -416,18 +407,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, len, nb_rb_pdsch); -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif - -#if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif if (first_symbol_flag==1) { if (beamforming_mode==0){ nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext, @@ -482,19 +468,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } #endif -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif - -#if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif // Now channel compensation if (dlsch0_harq->mimo_moderxdataF_ext, @@ -539,18 +520,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 0); } -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif -// MRC -#if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif if (frame_parms->nb_antennas_rx > 1) { if (dlsch0_harq->mimo_modegeneric_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif - -#if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); -#endif /* Store the valid DL RE's */ pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = len; @@ -692,14 +662,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif -#endif // Please keep it: useful for debugging #ifdef DEBUG_PDSCH_RX diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 7dfd765b76..ffe21b1f6d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -38,6 +38,7 @@ #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "SCHED_NR_UE/defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "common/utils/nr/nr_common.h" #include "common_lib.h" #include @@ -126,15 +127,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini // initialization of structure current_ssb = create_ssb_node(l,hf); -#if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); -#endif // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); -#endif current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im; @@ -150,15 +147,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini NR_UE_SSB *temp_ptr=best_ssb; while (ret!=0 && temp_ptr != NULL) { -#if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); -#endif // computing channel estimation for selected best ssb for(int i=pbch_initial_symbol; ii_ssb,temp_ptr->n_hf); -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); -#endif ret = nr_rx_pbch(ue, proc, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index ba5c65ceb7..f8e7ce317f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -39,7 +39,6 @@ #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include //#define DEBUG_ULSCH_CODING diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index b1addf740a..1c98c8c119 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -44,8 +44,6 @@ #include "PHY/TOOLS/tools_defs.h" #include "executables/nr-softmodem.h" #include "executables/softmodem-common.h" -#include "LAYER2/NR_MAC_UE/mac_proto.h" - #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" //#define DEBUG_PUSCH_MAPPING @@ -143,7 +141,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ulsch_ue->Nid_cell = Nid_cell; - get_num_re_dmrs(pusch_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols); + for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) { + if((ul_dmrs_symb_pos >> i) & 0x01) + number_dmrs_symbols += 1; + } + + nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n", rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 20a1595655..68d8735411 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -34,7 +34,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" //#include "PHY/extern.h" -//#include "LAYER2/MAC/extern.h" #include "PHY/NR_UE_TRANSPORT/pucch_nr.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h index dcf7fb4a37..078a95605f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -37,7 +37,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" //#include "PHY/extern.h" -//#include "LAYER2/MAC/extern.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index 8a15edc8f6..c62fbed106 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -18,17 +18,27 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - +#define _GNU_SOURCE #include #include "time_meas.h" #include #include - +#include +#include "assertions.h" +#ifndef PHYSIM + #include + #include "common/config/config_userapi.h" +#endif // global var for openair performance profiler int opp_enabled = 0; double cpu_freq_GHz __attribute__ ((aligned(32))); double cpu_freq_GHz __attribute__ ((aligned(32)))=0.0; +#ifndef PHYSIM +static uint32_t max_cpumeasur; +static time_stats_t **measur_table; +notifiedFIFO_t measur_fifo; +#endif double get_cpu_freq_GHz(void) { if (cpu_freq_GHz <1 ) { @@ -133,3 +143,112 @@ double get_time_meas_us(time_stats_t *ts) return 0; } + +#ifndef PHYSIM +/* function for the asynchronous measurment module: cpu stat are sent to a dedicated thread + * which is in charge of computing the cpu time spent in a given function/algorithm... + */ + +time_stats_t *register_meas(char *name) +{ + for (int i=0; imeas_name = strdup(name); + measur_table[i]->meas_index = i; + measur_table[i]->tpoolmsg =newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL); + measur_table[i]->tstatptr = (time_stats_msg_t *)NotifiedFifoData(measur_table[i]->tpoolmsg); + return measur_table[i]; + } + } + return NULL; +} + +void free_measurtbl(void) { + for (int i=0; imeas_name); + delNotifiedFIFO_elt(measur_table[i]->tpoolmsg); + free(measur_table[i]); + } + } + //free the fifo... +} + +void run_cpumeasur(void) { + struct sched_param schedp; + pthread_setname_np(pthread_self(), "measur"); + schedp.sched_priority=0; + int rt=pthread_setschedparam(pthread_self(), SCHED_IDLE, &schedp); + AssertFatal(rt==0, "couldn't set measur thread priority: %s\n",strerror(errno)); + initNotifiedFIFO(&measur_fifo); + while(1) { + notifiedFIFO_elt_t *msg = pullNotifiedFIFO(&measur_fifo); + time_stats_msg_t *tsm = (time_stats_msg_t *)NotifiedFifoData(msg); + switch(tsm->msgid) { + case TIMESTAT_MSGID_START: + measur_table[tsm->timestat_id]->in=tsm->ts; + (measur_table[tsm->timestat_id]->trials)++; + break; + case TIMESTAT_MSGID_STOP: + /// process duration is the difference between two clock points + measur_table[tsm->timestat_id]->p_time = (tsm->ts - measur_table[tsm->timestat_id]->in); + measur_table[tsm->timestat_id]->diff += measur_table[tsm->timestat_id]->p_time; + if ( measur_table[tsm->timestat_id]->p_time > measur_table[tsm->timestat_id]->max ) + measur_table[tsm->timestat_id]->max = measur_table[tsm->timestat_id]->p_time; + break; + case TIMESTAT_MSGID_DISPLAY: + { + char aline[256]; + int start, stop; + if (tsm->displayFunc != NULL) { + if(tsm->timestat_id >= 0) { + start=tsm->timestat_id ; + stop=start+1; + } + else { + start=0; + stop=max_cpumeasur ; + } + for (int i=start ; imeas_name, measur_table[i]->trials==0?0:( (measur_table[i]->trials/measur_table[i]->diff )/ cpu_freq_GHz /1000 )); + tsm->displayFunc(aline); + } + } + } + } + break; + case TIMESTAT_MSGID_END: + free_measurtbl(); + delNotifiedFIFO_elt(msg); + pthread_exit(NULL); + break; + default: + break; + } + delNotifiedFIFO_elt(msg); + } +} + + +void init_meas(void) { + pthread_t thid; + paramdef_t cpumeasur_params[] = CPUMEASUR_PARAMS_DESC; + int numparams=sizeof(cpumeasur_params)/sizeof(paramdef_t); + int rt = config_get( cpumeasur_params,numparams,CPUMEASUR_SECTION); + AssertFatal(rt >= 0, "cpumeasur configuration couldn't be performed"); + measur_table=calloc(max_cpumeasur,sizeof( time_stats_t *)); + AssertFatal(measur_table!=NULL, "couldn't allocate %u cpu measurements entries\n",max_cpumeasur); + rt=pthread_create(&thid,NULL, (void *(*)(void *))run_cpumeasur, NULL); + AssertFatal(rt==0, "couldn't create cpu measurment thread: %s\n",strerror(errno)); +} + +void end_meas(void) { + notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL); + time_stats_msg_t *msg = (time_stats_msg_t *)NotifiedFifoData(nfe); + msg->msgid = TIMESTAT_MSGID_END ; + pushNotifiedFIFO(&measur_fifo, nfe); +} +#endif diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index e2ceef8405..f78ea55530 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -31,31 +31,57 @@ #include #include #include +#ifndef PHYSIM + #include "common/utils/threadPool/thread-pool.h" +#endif // global var to enable openair performance profiler extern int opp_enabled; extern double cpu_freq_GHz __attribute__ ((aligned(32)));; - +// structure to store data to compute cpu measurment #if defined(__x86_64__) || defined(__i386__) -typedef struct { - long long in; - long long diff; - long long p_time; /*!< \brief absolute process duration */ - long long diff_square; /*!< \brief process duration square */ - long long max; - int trials; - int meas_flag; -} time_stats_t; + #define OAI_CPUTIME_TYPE long long #elif defined(__arm__) -typedef struct { - uint32_t in; - uint32_t diff; - uint32_t p_time; /*!< \brief absolute process duration */ - uint32_t diff_square; /*!< \brief process duration square */ - uint32_t max; - int trials; -} time_stats_t; + #define OAI_CPUTIME_TYPE uint32_t +#else + #error "building on unsupported CPU architecture" #endif +#define TIMESTAT_MSGID_START 0 /*!< \brief send time at measure starting point */ +#define TIMESTAT_MSGID_STOP 1 /*!< \brief send time at measure end point */ +#define TIMESTAT_MSGID_ENABLE 2 /*!< \brief enable measure point */ +#define TIMESTAT_MSGID_DISABLE 3 /*!< \brief disable measure point */ +#define TIMESTAT_MSGID_DISPLAY 10 /*!< \brief display measure */ +#define TIMESTAT_MSGID_END 11 /*!< \brief stops the measure threads and free assocated resources */ +typedef void(*meas_printfunc_t)(const char* format, ...); +typedef struct { + int msgid; /*!< \brief message id, as defined by TIMESTAT_MSGID_X macros */ + int timestat_id; /*!< \brief points to the time_stats_t entry in cpumeas table */ + OAI_CPUTIME_TYPE ts; /*!< \brief time stamp */ + meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/ +} time_stats_msg_t; + + +typedef struct { + OAI_CPUTIME_TYPE in; /*!< \brief time at measure starting point */ + OAI_CPUTIME_TYPE diff; /*!< \brief average difference between time at starting point and time at endpoint*/ + OAI_CPUTIME_TYPE p_time; /*!< \brief absolute process duration */ + OAI_CPUTIME_TYPE diff_square; /*!< \brief process duration square */ + OAI_CPUTIME_TYPE max; /*!< \brief maximum difference between time at starting point and time at endpoint*/ + int trials; /*!< \brief number of start point - end point iterations */ + int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */ + char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/ + int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/ + int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/ +#ifndef PHYSIM + notifiedFIFO_elt_t *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */ + time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/ +#endif +} time_stats_t; +#define MEASURE_ENABLED(X) (X->meas_enabled) + + + + static inline void start_meas(time_stats_t *ts) __attribute__((always_inline)); static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline)); @@ -137,4 +163,28 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) { dst_ts->max=src_ts->max; } } + +#ifndef PHYSIM +extern notifiedFIFO_t measur_fifo; +#define CPUMEASUR_SECTION "cpumeasur" + +#define CPUMEASUR_PARAMS_DESC { \ + {"max_cpumeasur", "Max number of cpu measur entries", 0, uptr:&max_cpumeasur, defintval:100, TYPE_UINT, 0},\ + } + + void init_meas(void); + time_stats_t *register_meas(char *name); + #define START_MEAS(X) send_meas(X, TIMESTAT_MSGID_START) + #define STOP_MEAS(X) send_meas(X, TIMESTAT_MSGID_STOP) + static inline void send_meas(time_stats_t *ts, int msgid) { + if (MEASURE_ENABLED(ts) ) { + ts->tstatptr->timestat_id=ts->meas_index; + ts->tstatptr->msgid = msgid ; + ts->tstatptr->ts = rdtsc_oai(); + pushNotifiedFIFO(&measur_fifo, ts->tpoolmsg); + } + } + void end_meas(void); + +#endif //ifndef PHYSIM #endif diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 3a7b630d09..8f315ba214 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -30,6 +30,7 @@ * \warning */ #include "fapi_nr_l1.h" +#include "common/ran_context.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" @@ -146,7 +147,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n"); AssertFatal(RC.gNB[Mod_id]!=NULL,"RC.gNB[%d] is null\n",Mod_id); - gNB = RC.gNB[Mod_id]; + gNB = RC.gNB[Mod_id]; notifiedFIFO_elt_t *res; res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index caa5f8ea78..1ea8dbdf3c 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -49,6 +49,59 @@ extern uint8_t nfapi_mode; +uint8_t get_nr_prach_duration(uint8_t prach_format){ + + switch(prach_format){ + + case 0: // format 0 + return 0; + + case 1: // format 1 + return 0; + + case 2: // format 2 + return 0; + + case 3: // format 3 + return 0; + + case 4: // format A1 + return 2; + + case 5: // format A2 + return 4; + + case 6: // format A3 + return 6; + + case 7: // format B1 + return 2; + + case 8: // format B4 + return 12; + + case 9: // format C0 + return 2; + + case 10: // format C2 + return 6; + + case 11: // format A1/B1 + return 2; + + case 12: // format A2/B2 + return 4; + + case 13: // format A3/B3 + return 6; + + default : + AssertFatal(1==0,"Invalid Prach format\n"); + break; + + } +} + void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0}; diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 7b4511e7f4..c98574ec42 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -340,8 +340,6 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue, */ UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_index); -uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id); - /*! \brief This function implements the power control mechanism for PUCCH from 36.213. @param phy_vars_ue PHY variables @param proc Pointer to proc descriptor diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index bf12fe4f39..93839008a6 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -52,7 +52,8 @@ #endif #include "executables/softmodem-common.h" #include "executables/nr-uesoftmodem.h" -#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "LAYER2/NR_MAC_UE/mac_proto.h" +#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h" //#define DEBUG_PHY_PROC #define NR_PDCCH_SCHED @@ -64,8 +65,6 @@ #define PUCCH #endif -#include "LAYER2/NR_MAC_UE/mac_defs.h" -#include "LAYER2/NR_MAC_UE/mac_proto.h" #include "common/utils/LOG/log.h" #ifdef EMOS @@ -215,12 +214,6 @@ UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]); } -uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){ - - return PHY_vars_UE_g[Mod_id][CC_id]->prach_resources[gNB_id]->ra_PreambleIndex; - -} - // convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second // 16 * 64 * T_c / (2^mu) * samples_per_second // = 16 * T_s / (2^mu) * samples_per_second @@ -282,9 +275,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); -#if UE_TIMING_TRACE + start_meas(&ue->phy_proc_tx); -#endif if (ue->UE_mode[gNB_id] <= PUSCH){ @@ -296,9 +288,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE stop_meas(&ue->phy_proc_tx); -#endif + } @@ -647,9 +638,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN); -#if UE_TIMING_TRACE - start_meas(&ue->dlsch_rx_pdcch_stats); -#endif + start_meas(&ue->dlsch_rx_pdcch_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); #ifdef NR_PDCCH_SCHED_DEBUG @@ -749,9 +738,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, // send to mac ue->if_inst->dl_indication(&dl_indication, NULL); -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_rx_pdcch_stats); -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT); return(dci_cnt); @@ -833,12 +820,10 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ else first_symbol_flag = 0; -#if UE_TIMING_TRACE uint8_t slot = 0; if(m >= ue->frame_parms.symbols_per_slot>>1) slot = 1; start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); -#endif // process DLSCH received symbols in the slot // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function) if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_PDSCH) { @@ -857,13 +842,11 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ return -1; } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n"); -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); -#if DISABLE_LOG_X +#if PHYSIM printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); -#endif #endif if(first_symbol_flag) { @@ -971,19 +954,17 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dmrs_len, dlsch0->harq_processes[harq_pid]->Qm, dlsch0->harq_processes[harq_pid]->Nl); -#if UE_TIMING_TRACE - start_meas(&ue->dlsch_unscrambling_stats); -#endif - nr_dlsch_unscrambling(pdsch_vars->llr[0], - dlsch0->harq_processes[harq_pid]->G, - 0, - ue->frame_parms.Nid_cell, - dlsch0->rnti); + + start_meas(&ue->dlsch_unscrambling_stats); + nr_dlsch_unscrambling(pdsch_vars->llr[0], + dlsch0->harq_processes[harq_pid]->G, + 0, + ue->frame_parms.Nid_cell, + dlsch0->rnti); -#if UE_TIMING_TRACE - stop_meas(&ue->dlsch_unscrambling_stats); -#endif + stop_meas(&ue->dlsch_unscrambling_stats); + #if 0 LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, nr_slot_rx, harq_pid); @@ -996,9 +977,8 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols); #endif -#if UE_TIMING_TRACE - start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); -#endif + + start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); if( dlsch_parallel) { ret = nr_dlsch_decoding_mthread(ue, @@ -1059,9 +1039,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, -#if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); -#if DISABLE_LOG_X + + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); +#if PHYSIM printf(" --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n", @@ -1073,7 +1053,6 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif -#endif if(is_cw1_active) { // start ldpc decode for CW 1 dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb, @@ -1082,17 +1061,13 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dmrs_len, dlsch1->harq_processes[harq_pid]->Qm, dlsch1->harq_processes[harq_pid]->Nl); -#if UE_TIMING_TRACE start_meas(&ue->dlsch_unscrambling_stats); -#endif nr_dlsch_unscrambling(pdsch_vars->llr[1], dlsch1->harq_processes[harq_pid]->G, 0, ue->frame_parms.Nid_cell, dlsch1->rnti); -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_unscrambling_stats); -#endif #if 0 LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); @@ -1104,9 +1079,8 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols); #endif -#if UE_TIMING_TRACE start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); -#endif + if(dlsch_parallel) { ret1 = nr_dlsch_decoding_mthread(ue, @@ -1141,9 +1115,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1); } -#if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); -#if DISABLE_LOG_X + + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); +#if PHYSIM printf(" --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", @@ -1155,7 +1129,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif -#endif + LOG_D(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); @@ -1372,9 +1346,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { } /**** Slot1 FE Processing ****/ -#if UE_TIMING_TRACE + start_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); -#endif + // I- start dl slot1 processing // do first symbol of next downlink nr_slot_rx for channel estimation /* @@ -1399,9 +1373,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { { //if( (l != pilot0) && (l != pilot1)) { -#if UE_TIMING_TRACE + start_meas(&ue->ofdm_demod_stats); -#endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l); front_end_fft(ue, @@ -1410,9 +1383,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { 0, 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE stop_meas(&ue->ofdm_demod_stats); -#endif } } // for l=1..l2 @@ -1465,14 +1436,13 @@ void *UE_thread_slot1_dl_processing(void *arg) { //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx); -#if UE_TIMING_TRACE + stop_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); -#if DISABLE_LOG_X +#if PHYSIM printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #endif -#endif //wait until pdcch is decoded @@ -1490,9 +1460,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_slot_rx); -#if UE_TIMING_TRACE start_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); -#endif + // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI uint8_t gNB_id = 0; @@ -1562,13 +1531,11 @@ void *UE_thread_slot1_dl_processing(void *arg) { proc->llr_slot1_available=1; //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx); -#if UE_TIMING_TRACE stop_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); -#if DISABLE_LOG_X +#if PHYSIM printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); -#endif #endif if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { @@ -1711,13 +1678,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, (ue->symbol_offset+i)%(fp->symbols_per_slot), nr_slot_rx); -#if UE_TIMING_TRACE + start_meas(&ue->dlsch_channel_estimation_stats); -#endif nr_pbch_channel_estimation(ue,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); -#endif } nr_ue_rsrp_measurements(ue, gNB_id, proc, nr_slot_rx, 0); @@ -1757,9 +1721,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, for (uint16_t l=0; lofdm_demod_stats); -#endif nr_slot_fep(ue, proc, l, @@ -1783,9 +1745,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12, coreset_nb_rb); -#if UE_TIMING_TRACE stop_meas(&ue->ofdm_demod_stats); -#endif + } dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, n_ss); } @@ -1835,10 +1796,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, curMsg->UE = ue; curMsg->ue_sched_mode = ONLY_PUSCH; pushTpool(&(get_nrUE_params()->Tpool), newElt); - -#if UE_TIMING_TRACE start_meas(&ue->generic_stat); -#endif // do procedures for C-RNTI int ret_pdsch = 0; if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { @@ -1935,9 +1893,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d \n \n", nr_slot_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); -#if UE_TIMING_TRACE start_meas(&ue->dlsch_procedures_stat[proc->thread_id]); -#endif if (ret_pdsch >= 0) nr_ue_dlsch_procedures(ue, @@ -1949,10 +1905,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, &ue->dlsch_errors[gNB_id], dlsch_parallel); - -#if UE_TIMING_TRACE stop_meas(&ue->dlsch_procedures_stat[proc->thread_id]); -#if DISABLE_LOG_X +#if PHYSIM printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #else @@ -1960,7 +1914,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #endif -#endif + // deactivate dlsch once dlsch proc is done ue->dlsch[proc->thread_id][gNB_id][0]->active = 0; @@ -1969,9 +1923,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } -#if UE_TIMING_TRACE start_meas(&ue->generic_stat); -#endif #if 0 @@ -2036,8 +1988,8 @@ if (nr_slot_rx==9) { } -#if UE_TIMING_TRACE stop_meas(&ue->generic_stat); +#if PHYSIM printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); #endif @@ -2048,14 +2000,12 @@ phy_procedures_emos_UE_RX(ue,slot,gNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE stop_meas(&ue->phy_proc_rx[proc->thread_id]); -#if DISABLE_LOG_X +#if PHYSIM printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #else LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #endif -#endif //#endif //pdsch diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 8ad45c97ad..77ac105e14 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -38,7 +38,6 @@ #include "PHY/defs_nr_UE.h" #include #include -#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h" #include #include @@ -58,115 +57,6 @@ uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); -/* TS 36.213 Table 9.2.5.2-1: Code rate corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */ -/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */ -/* add one additional element set to 0 for parsing the array until this end */ -/* stored values are code rates * 100 */ -//static const int code_rate_r_time_100[8] = { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 } ; - -static float RSRP_meas_mapping_nr[98] -= { - -140, - -139, - -138, - -137, - -136, - -135, - -134, - -133, - -132, - -131, - -130, - -129, - -128, - -127, - -126, - -125, - -124, - -123, - -122, - -121, - -120, - -119, - -118, - -117, - -116, - -115, - -114, - -113, - -112, - -111, - -110, - -109, - -108, - -107, - -106, - -105, - -104, - -103, - -102, - -101, - -100, - -99, - -98, - -97, - -96, - -95, - -94, - -93, - -92, - -91, - -90, - -89, - -88, - -87, - -86, - -85, - -84, - -83, - -82, - -81, - -80, - -79, - -78, - -77, - -76, - -75, - -74, - -73, - -72, - -71, - -70, - -69, - -68, - -67, - -66, - -65, - -64, - -63, - -62, - -61, - -60, - -59, - -58, - -57, - -56, - -55, - -54, - -53, - -52, - -51, - -50, - -49, - -48, - -47, - -46, - -45, - -44, - -43 - } - ; - long binary_search_float_nr( float elements[], @@ -394,187 +284,10 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, } -/******************************************************************* -* -* NAME : check_pucch_format -* -* PARAMETERS : ue context -* processing slots of reception/transmission -* gNB_id identifier -* -* RETURN : harq process identifier -* -* DESCRIPTION : return tx harq process identifier for given transmission slot -* YS 38.213 9.2.2 PUCCH Formats for UCI transmission -* -*********************************************************************/ - -boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx, int uci_size) -{ - pucch_format_nr_t selected_pucch_format; - pucch_format_nr_t selected_pucch_format_second; - /*NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL; - - switch (format_pucch) { - case pucch_format1_nr: - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL) - identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1; - break; - - case pucch_format2_nr: - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format2 != NULL) - identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format2; - break; - - case pucch_format3_nr: - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3 != NULL) - identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3; - break; - - case pucch_format4_nr: - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4 != NULL) - identified_format = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4; - break; - - default: - break; - }*/ - - /* if ((identified_format != NULL) && (identified_format->choice.setup->nrofSlots[0] != 1)) { - LOG_E(PHY,"PUCCH not implemented multislots transmission : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (FALSE); - }*/ - - if (nb_symbols_for_tx <= 2) { - if (uci_size <= 2) { - selected_pucch_format = pucch_format0_nr; - selected_pucch_format_second = selected_pucch_format; - } - else { - selected_pucch_format = pucch_format2_nr; - selected_pucch_format_second = selected_pucch_format; - } - } - else { - if (nb_symbols_for_tx >= 4) { - if (uci_size <= 2) { - selected_pucch_format = pucch_format1_nr; - selected_pucch_format_second = selected_pucch_format; - } - else { - selected_pucch_format = pucch_format3_nr; /* in this case choice can be done between two formats */ - selected_pucch_format_second = pucch_format4_nr; - } - } - else { - LOG_D(PHY,"PUCCH Undefined PUCCH format : set PUCCH to format 4 : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (FALSE); - } - } - - NR_TST_PHY_PRINTF("PUCCH format %d nb symbols total %d uci size %d selected format %d \n", format_pucch, nb_symbols_for_tx, uci_size, selected_pucch_format); - - if (format_pucch != selected_pucch_format) { - if (format_pucch != selected_pucch_format_second) { - NR_TST_PHY_PRINTF("PUCCH mismatched of selected format: at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - LOG_D(PHY,"PUCCH format mismatched of selected format: at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (FALSE); - } - else { - return (TRUE); - } - } - else { - return (TRUE); - } -} - - - -/******************************************************************* -* -* NAME : get_csi_nr -* PARAMETERS : ue context -* processing slots of reception/transmission -* gNB_id identifier -* -* RETURN : size of csi payload -* -* DESCRIPTION : CSI management is not already implemented -* so it has been simulated thank to two functions: -* - set_csi_nr -* - get_csi_nr -* -*********************************************************************/ int dummy_csi_status = 0; uint32_t dummy_csi_payload = 0; -/* FFS TODO_NR code that should be developed */ - -uint16_t get_nr_csi_bitlen(NR_UE_MAC_INST_t *mac) { - - uint16_t csi_bitlen =0; - uint16_t rsrp_bitlen = 0; - uint16_t diff_rsrp_bitlen = 0; - uint16_t nb_ssbri_cri = 0; - uint16_t cri_ssbri_bitlen = 0; - - NR_CSI_MeasConfig_t *csi_MeasConfig = mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; - struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[0]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB; - - uint16_t nb_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0; - - if (0 != nb_csi_ssb_report){ - uint8_t nb_ssb_resources =0; - - if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->groupBasedBeamReporting.choice.disabled->nrofReportedRS) - nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; - else - nb_ssbri_cri = 1; - - nb_ssb_resources = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[0]->csi_SSB_ResourceList.list.count; - - if (nb_ssb_resources){ - cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); - rsrp_bitlen = 7; - diff_rsrp_bitlen = 4; - } - else{ - cri_ssbri_bitlen =0; - rsrp_bitlen = 0; - diff_rsrp_bitlen = 0; - } - - csi_bitlen = ((cri_ssbri_bitlen * nb_ssbri_cri) + rsrp_bitlen +(diff_rsrp_bitlen *(nb_ssbri_cri -1 ))) *nb_csi_ssb_report; - - //printf("get csi bitlen %d nb_ssbri_cri %d nb_csi_report %d nb_resources %d\n", csi_bitlen,nb_ssbri_cri ,nb_csi_ssb_report, nb_ssb_resources); - } - return csi_bitlen; -} - -int get_csi_nr(NR_UE_MAC_INST_t *mac, PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload) -{ - VOID_PARAMETER ue; - VOID_PARAMETER gNB_id; - float rsrp_db[7]; - int nElem = 98; - int rsrp_offset = 17; - int csi_status = 0; - - csi_status = get_nr_csi_bitlen(mac); - rsrp_db[0] = get_nr_RSRP(0,0,0); - - - if (csi_status == 0) { - *csi_payload = 0; - } - else { - *csi_payload = binary_search_float_nr(RSRP_meas_mapping_nr,nElem, rsrp_db[0]) + rsrp_offset; - } - - return (csi_status); -} /* FFS TODO_NR code that should be removed */ diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h index 101b80fb8d..37e24f43bc 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h @@ -41,8 +41,6 @@ /************** INCLUDE *******************************************/ #include "PHY/defs_nr_UE.h" -#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" -#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "RRC/NR_UE/rrc_proto.h" #ifdef DEFINE_VARIABLES_PUCCH_UE_NR_H @@ -65,31 +63,6 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc); -/** \brief This function check pucch format - @param ue context - @param gNB_id identity - @param format_pucch pucch format - @param nb_symbols_for_tx number of symbols for pucch transmission - @param uci size number of uci bits - @returns TRUE pucch format matched uci size and constraints, FALSE invalid pucch format */ - -boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format_nr_t format_pucch, int nb_symbols_for_tx, - int uci_size); - -/** \brief This function reads current CSI - @param ue context - @param gNB_id identity - @param csi_payload is updated with CSI - @returns number of bits of CSI */ - -int get_csi_nr(NR_UE_MAC_INST_t *mac, PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload); - -/** \brief This dummy function sets current CSI for simulation - @param csi_status - @param csi_payload is updated with CSI - @returns none */ - -uint16_t get_nr_csi_bitlen(NR_UE_MAC_INST_t *mac); void set_csi_nr(int csi_status, uint32_t csi_payload); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 83d6625830..51fdfc917e 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -27,6 +27,7 @@ #include #include "common/ran_context.h" #include "common/config/config_userapi.h" +#include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "LAYER2/NR_MAC_UE/mac_defs.h" @@ -429,7 +430,9 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) { + + while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:D:e:m:w:T:U:q")) != -1) { + switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -595,7 +598,7 @@ int main(int argc, char **argv) case 'b': g_rbSize = atoi(optarg); break; - case 'd': + case 'D': dlsch_threads = atoi(optarg); break; case 'e': @@ -668,7 +671,7 @@ int main(int argc, char **argv) printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n"); printf("-P Print DLSCH performances\n"); printf("-w Write txdata to binary file (one frame)\n"); - printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); + printf("-D number of dlsch threads, 0: no dlsch parallelization\n"); exit (-1); break; } @@ -685,7 +688,7 @@ int main(int argc, char **argv) if (snr1set==0) snr1 = snr0+10; - init_dlsch_tpool(dlsch_threads); + RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); @@ -977,7 +980,11 @@ int main(int argc, char **argv) reset_meas(&msgDataTx->phy_proc_tx); gNB->phy_proc_tx_0 = &msgDataTx->phy_proc_tx; pushTpool(gNB->threadPool,msgL1Tx); - + if (dlsch_threads ) { + init_dlsch_tpool(dlsch_threads); + pthread_t dlsch0_threads; + threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1); + } for (SNR = snr0; SNR < snr1; SNR += .2) { varArray_t *table_tx=initVarArray(1000,sizeof(double)); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 8f4f227f6c..1169b8ecd8 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -28,6 +28,7 @@ #include "common/config/config_userapi.h" #include "common/utils/LOG/log.h" #include "common/ran_context.h" +#include "common/utils/nr/nr_common.h" #include "PHY/types.h" #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 6167c809ff..a33713234c 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -47,6 +47,7 @@ #include "nr_unitary_defs.h" #include "OCG_vars.h" #include +#include #include #include #include diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index 838a5db762..7858cd6c32 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -55,7 +55,7 @@ #define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" #define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" -#define CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY "ulsch_max_slots_inactivity" +#define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity" #define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10" #define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10" #define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres" @@ -83,7 +83,7 @@ {CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_ULSCH_MAX_SLOTS_INACTIVITY, "Maximum number of slots before a UE is scheduled ULSCH due to inactivity", 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ @@ -106,7 +106,7 @@ #define MACRLC_REMOTE_S_PORTC_IDX 14 #define MACRLC_LOCAL_S_PORTD_IDX 15 #define MACRLC_REMOTE_S_PORTD_IDX 16 -#define MACRLC_ULSCH_MAX_SLOTS_INACTIVITY 17 +#define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17 #define MACRLC_PUSCHTARGETSNRX10_IDX 18 #define MACRLC_PUCCHTARGETSNRX10_IDX 19 #define MACRLC_PUCCHFAILURETHRES_IDX 20 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index af21fd8b08..7c81a5ef49 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -754,7 +754,7 @@ void RCconfig_nr_macrlc() { }else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } - RC.nrmac[j]->ulsch_max_slots_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_SLOTS_INACTIVITY].uptr); + RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr); RC.nrmac[j]->num_ulprbbl = num_prbbl; LOG_I(NR_MAC,"Blacklisted PRBS %d\n",num_prbbl); memcpy(RC.nrmac[j]->ulprbbl,prbbl,275*sizeof(prbbl[0])); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 09fb08d7c4..4ef0a55c6b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -40,6 +40,9 @@ #include "NR_SubcarrierSpacing.h" +#define NR_SHORT_BSR_TABLE_SIZE 32 +#define NR_LONG_BSR_TABLE_SIZE 256 + #define TABLE_38213_13_1_NUM_INDEXES 15 #define TABLE_38213_13_2_NUM_INDEXES 14 #define TABLE_38213_13_3_NUM_INDEXES 9 @@ -65,6 +68,11 @@ typedef enum frequency_range_e { FR2 } frequency_range_t; +#define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */ +#define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */ +#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */ +#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */ + // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 3750bb156d..3f4be9dd58 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -48,6 +48,33 @@ void reverse_n_bits(uint8_t *value, uint16_t bitlen) { } } +//38.321 Table 6.1.3.1-1 +const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE] = { + 0, 10, 14, 20, 28, 38, 53, 74, + 102, 142, 198, 276, 384, 535, 745, 1038, + 1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726, +20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000 +}; + +//38.321 Table 6.1.3.1-2 +const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE] ={ + 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, + 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71, + 75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193, + 205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526, + 560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439, + 1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934, + 4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760, + 11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431, + 31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505, + 85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209, + 234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350, + 641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644, + 1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902, + 4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006, +13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553, +35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295 +}; // start symbols for SSB types A,B,C,D,E uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50}; @@ -359,7 +386,6 @@ void get_info_from_tda_tables(int default_abc, } const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"}; -const char *duplex_mode[]={"FDD","TDD"}; uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) { @@ -1573,60 +1599,6 @@ int get_nr_prach_occasion_info_from_index(uint8_t index, } -uint8_t get_nr_prach_duration(uint8_t prach_format){ - - switch(prach_format){ - - case 0: // format 0 - return 0; - - case 1: // format 1 - return 0; - - case 2: // format 2 - return 0; - - case 3: // format 3 - return 0; - - case 4: // format A1 - return 2; - - case 5: // format A2 - return 4; - - case 6: // format A3 - return 6; - - case 7: // format B1 - return 2; - - case 8: // format B4 - return 12; - - case 9: // format C0 - return 2; - - case 10: // format C2 - return 6; - - case 11: // format A1/B1 - return 2; - - case 12: // format A2/B2 - return 4; - - case 13: // format A3/B3 - return 6; - - default : - AssertFatal(1==0,"Invalid Prach format\n"); - break; - - } - -} - int get_nr_prach_info_from_index(uint8_t index, int frame, int slot, @@ -1981,170 +1953,6 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { {0, 3072, -1, -1, 3, 1539, -1, -1}, //14 // (DMRS l' position) }; -// Returns the corresponding row index of the NR table -int get_nr_table_idx(int nr_bandP, uint8_t scs_index) -{ - int i, j; - int scs_khz = 15 << scs_index; - int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; - size_t s = sizeof(supplementary_bands)/sizeof(supplementary_bands[0]); - - for(j = 0; j < s; j++){ - if (nr_bandP == supplementary_bands[j]) - AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); - } - - AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band); - for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++); - - // selection of correct Deltaf raster according to SCS - if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) - i++; - - LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); - - return i; -} - -// Computes the duplex spacing (either positive or negative) in KHz -int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) -{ - int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index); - - int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); - - LOG_I(NR_MAC, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); - - return delta_duplex; -} - -lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index) -{ - lte_frame_type_t current_type; - int32_t delta_duplex = get_delta_duplex(current_band, scs_index); - - if (delta_duplex == 0) - current_type = TDD; - else - current_type = FDD; - - LOG_I(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); - - return current_type; -} - -uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) -{ - - if (nr_band < 100) { //FR1 - switch(mu) { - case 0 : - if (nb_rb<=25) - return 5; - if (nb_rb<=52) - return 10; - if (nb_rb<=79) - return 15; - if (nb_rb<=106) - return 20; - if (nb_rb<=133) - return 25; - if (nb_rb<=160) - return 30; - if (nb_rb<=216) - return 40; - if (nb_rb<=270) - return 50; - AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); - break; - case 1 : - if (nb_rb<=11) - return 5; - if (nb_rb<=24) - return 10; - if (nb_rb<=38) - return 15; - if (nb_rb<=51) - return 20; - if (nb_rb<=65) - return 25; - if (nb_rb<=78) - return 30; - if (nb_rb<=106) - return 40; - if (nb_rb<=133) - return 50; - if (nb_rb<=162) - return 60; - if (nb_rb<=189) - return 70; - if (nb_rb<=217) - return 80; - if (nb_rb<=245) - return 90; - if (nb_rb<=273) - return 100; - AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); - break; - case 2 : - if (nb_rb<=11) - return 10; - if (nb_rb<=18) - return 15; - if (nb_rb<=24) - return 20; - if (nb_rb<=31) - return 25; - if (nb_rb<=38) - return 30; - if (nb_rb<=51) - return 40; - if (nb_rb<=65) - return 50; - if (nb_rb<=79) - return 60; - if (nb_rb<=93) - return 70; - if (nb_rb<=107) - return 80; - if (nb_rb<=121) - return 90; - if (nb_rb<=135) - return 100; - AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); - break; - default: - AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); - } - } - else { - switch(mu) { - case 2 : - if (nb_rb<=66) - return 50; - if (nb_rb<=132) - return 100; - if (nb_rb<=264) - return 200; - AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); - break; - case 3 : - if (nb_rb<=32) - return 50; - if (nb_rb<=66) - return 100; - if (nb_rb<=132) - return 200; - if (nb_rb<=264) - return 400; - AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d and band %d\n", nb_rb, mu, nr_band); - break; - default: - AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); - } - } - -} void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){ @@ -2516,13 +2324,7 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8 return 1; } -int get_num_dmrs(uint16_t dmrs_mask ) { - int num_dmrs=0; - - for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1); - return(num_dmrs); -} /* returns the total DMRS symbols in a slot*/ uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols, int startSymbol, int mappingtype){ return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols, startSymbol, mappingtype)); @@ -3606,13 +3408,23 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD uint16_t ssb_start_symbol, NR_SubcarrierSpacing_t scs_ssb, frequency_range_t frequency_range, + int nr_band, uint32_t ssb_index, uint32_t ssb_period, uint32_t ssb_offset_point_a) { NR_SubcarrierSpacing_t scs_pdcch; - channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104 + channel_bandwidth_t min_channel_bw; + + // according to Table 5.3.5-1 in 38.104 + // band 79 is the only one which minimum is 40 + // for all the other channels it is either 10 or 5 + // and there is no difference between the two for this implementation so it is set it to 10 + if (nr_band == 79) + min_channel_bw = bw_40MHz; + else + min_channel_bw = bw_10MHz; if (frequency_range == FR2) { if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e107553117..ced29f066f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -37,12 +37,6 @@ #include "nr_mac.h" #include "openair1/PHY/impl_defs_nr.h" -uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); - -lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); - -int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); - uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); @@ -97,8 +91,6 @@ int get_nr_prach_occasion_info_from_index(uint8_t index, uint16_t *N_RA_sfn, uint8_t *max_association_period); -uint8_t get_nr_prach_duration(uint8_t prach_format); - uint8_t get_pusch_mcs_table(long *mcs_Table, int is_tp, int dci_format, @@ -121,7 +113,6 @@ int64_t *get_prach_config_info(frequency_range_t freq_range, uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); -int get_num_dmrs(uint16_t dmrs_mask ); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength, uint8_t start_symbolt, uint8_t dmrs_typeA_position); @@ -136,6 +127,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD uint16_t ssb_start_symbol, NR_SubcarrierSpacing_t scs_ssb, frequency_range_t frequency_range, + int nr_band, uint32_t ssb_index, uint32_t ssb_period, uint32_t ssb_offset_point_a); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 5b4ebe2397..5def748d42 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -76,6 +76,9 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif*/ +extern const uint32_t NR_SHORT_BSR_TABLE[NR_SHORT_BSR_TABLE_SIZE]; +extern const uint32_t NR_LONG_BSR_TABLE[NR_LONG_BSR_TABLE_SIZE]; + // Type0-PDCCH search space extern const int32_t table_38213_13_1_c1[16]; extern const int32_t table_38213_13_1_c2[16]; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c old mode 100755 new mode 100644 index 1accbf30cb..cef13b87fb --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -615,6 +615,18 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ } } +// todo handle mac_LogicalChannelConfig +int nr_rrc_mac_config_req_ue_logicalChannelBearer( + module_id_t module_id, + int cc_idP, + uint8_t gNB_index, + long logicalChannelIdentity, + boolean_t status){ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + mac->logicalChannelBearer_exist[logicalChannelIdentity] = status; + return 0; +} + int nr_rrc_mac_config_req_ue( module_id_t module_id, int cc_idP, @@ -678,6 +690,17 @@ int nr_rrc_mac_config_req_ue( LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); mac->cg = cell_group_config; mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0; + + mac->scheduling_info.periodicBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->scheduling_info.retxBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->BSR_reporting_active = NR_BSR_TRIGGER_NONE; + LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", + module_id, + mac->scheduling_info.periodicBSR_SF, + mac->scheduling_info.retxBSR_SF); + config_control_ue(mac); //config_common_ue(mac,module_id,cc_idP); /* diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h old mode 100755 new mode 100644 index cef97615f3..d076f2c59e --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -182,9 +182,9 @@ typedef struct { uint16_t All_lcid_buffer_size_lastTTI; /// buffer status for each lcid uint8_t LCID_status[NR_MAX_NUM_LCID]; - /// SR pending as defined in 36.321 + /// SR pending as defined in 38.321 uint8_t SR_pending; - /// SR_COUNTER as defined in 36.321 + /// SR_COUNTER as defined in 38.321 uint16_t SR_COUNTER; /// logical channel group ide for each LCID uint8_t LCGID[NR_MAX_NUM_LCID]; @@ -328,15 +328,6 @@ typedef struct { } RAR_grant_t; -typedef struct { - - uint8_t phr_reporting; - uint16_t truncated_bsr; - uint16_t short_bsr; - uint16_t long_bsr; - -} NR_UE_MAC_CE_t; - typedef struct { int n_HARQ_ACK; uint32_t ack_payload; @@ -353,6 +344,7 @@ typedef struct { int8_t delta_pucch; } PUCCH_sched_t; + /*!\brief Top level UE MAC structure */ typedef struct { @@ -419,8 +411,15 @@ typedef struct { nr_ue_if_module_t *if_module; nr_phy_config_t phy_config; + /// BSR report flag management + uint8_t BSR_reporting_active; + + /// LogicalChannelConfig has bearer. + boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID]; NR_UE_SCHEDULING_INFO scheduling_info; - NR_UE_MAC_CE_t nr_ue_mac_ce; + + /// PHR + uint8_t PHR_reporting_active; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; NR_SearchSpace_t *search_space_zero; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h old mode 100755 new mode 100644 index 30b87a056e..a9632fb330 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -40,6 +40,10 @@ #define NR_DL_MAX_DAI (4) /* TS 38.213 table 9.1.3-1 Value of counter DAI for DCI format 1_0 and 1_1 */ #define NR_DL_MAX_NB_CW (2) /* number of downlink code word */ +/**\brief initialize the field in nr_mac instance + \param module_id module id */ +void nr_ue_init_mac(module_id_t module_idP); + /**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message \param module_id module id \param cc_id component carrier id @@ -74,6 +78,20 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint8_t *pduP, uint32_t pdu_len); +/**\brief primitive from RRC layer to MAC layer to set if bearer exists for a logical channel. todo handle mac_LogicalChannelConfig + \param module_id module id + \param cc_id component carrier id + \param gNB_index gNB index + \param long logicalChannelIdentity + \param boolean_t status*/ +int nr_rrc_mac_config_req_ue_logicalChannelBearer( + module_id_t module_id, + int cc_idP, + uint8_t gNB_index, + long logicalChannelIdentity, + boolean_t status +); + /**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config) \param module_id module id \param cc_id component carrier id @@ -125,7 +143,53 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, int slot, int thread_id); -int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP); +/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP); + \brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and DTCH and forms BSR elements and PHR in MAC header. CRNTI element is not supported yet. It computes transport block for up to 3 SDUs and generates header and forms the complete MAC SDU. +\param[in] Mod_id Instance id of UE in machine +\param[in] frameP subframe number +\param[in] slotP slot number +*/ +int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP); + +/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) + \brief get the rlc stats and update the bsr level for each lcid +\param[in] Mod_id instance of the UE +\param[in] frameP Frame index +\param[in] slot slotP number +\param[in] uint8_t gNB_index +*/ +boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index); + +/*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value) + \brief locate the BSR level in the table as defined in 38.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. +\param[in] *table Pointer to BSR table +\param[in] size Size of the table +\param[in] value Value of the buffer +\return the index in the BSR_LEVEL table +*/ +uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, + int value); + +/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer) + \brief get the number of subframe from the periodic BSR timer configured by the higher layers +\param[in] periodicBSR_Timer timer for periodic BSR +\return the number of subframe +*/ +int nr_get_sf_periodicBSRTimer(uint8_t bucketSize); + +/*! \fn int nr_get_ms_bucketsizeduration(uint8_t bucketSize) + \brief get the time in ms form the bucket size duration configured by the higher layer +\param[in] bucketSize the bucket size duration +\return the time in ms +*/ +int nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration); + +/*! \fn int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer) + \brief get the number of subframe form the bucket size duration configured by the higher layer +\param[in] retxBSR_Timer timer for regular BSR +\return the time in sf +*/ +int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer); int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind); int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); @@ -170,7 +234,13 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, int pdu_id); int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac); + NR_UE_MAC_INST_t *mac, + uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom, + uint16_t *crnti, + NR_BSR_SHORT *truncated_bsr, + NR_BSR_SHORT *short_bsr, + NR_BSR_LONG *long_bsr + ); void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); @@ -270,23 +340,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_pucch_pdu *pucch_pdu, int O_SR, int O_ACK, int O_CSI); -/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure. - @param Mod_id Module id of UE - @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE -*/ -int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t module_idP, uint8_t CC_id); - -/** \brief Function to compute DELTA_PREAMBLE from 38.321 subclause 7.3 - (for RA power ramping procedure and Msg3 PUSCH power control policy) - @param Mod_id Module id of UE - @returns DELTA_PREAMBLE -*/ -int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format); - -/** \brief Function to compute configured maximum output power according to clause 6.2.4 of 3GPP TS 38.101-1 version 16.5.0 Release 16 - @param Mod_id Module id of UE -*/ -long nr_get_Pcmax(module_id_t mod_id); /* Random Access */ @@ -347,7 +400,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot); If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for -andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321) +andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 38.321) @param mod_id Index of UE instance @param CC_id Component Carrier Index @param frame @@ -390,10 +443,6 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id); void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); -void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, - uint8_t *nb_dmrs_re_per_rb, - uint16_t *number_dmrs_symbols); - void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index b27837043f..af0c84dc4b 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -52,8 +52,9 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { //init mac here nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST); - for (int j=0;jscell_group_config) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c index 7f1011fb28..eaaa5f5f72 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -35,150 +35,9 @@ #include "mac_defs.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" +#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h" #include "NR_P-Max.h" -/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */ -int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc!=NULL) ? - mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: - mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; - int prach_sequence_length = (mac->scc!=NULL)?(mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1) : (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1); - uint8_t prachConfigIndex, mu; - - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - - // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211 - - switch (scs){ - case NR_SubcarrierSpacing_kHz15: - mu = 0; - break; - - case NR_SubcarrierSpacing_kHz30: - mu = 1; - break; - - case NR_SubcarrierSpacing_kHz60: - mu = 2; - break; - - case NR_SubcarrierSpacing_kHz120: - mu = 3; - break; - - case NR_SubcarrierSpacing_kHz240: - mu = 4; - break; - - case NR_SubcarrierSpacing_spare3: - mu = 5; - break; - - case NR_SubcarrierSpacing_spare2: - mu = 6; - break; - - case NR_SubcarrierSpacing_spare1: - mu = 7; - break; - - default: - AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %lu\n", scs); - } - - // Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211 - - prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; - - if (prach_sequence_length == 0) { - AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format); - switch (prach_format) { - - // long preamble formats - case 0: - case 3: - return 0; - - case 1: - return -3; - - case 2: - return -6; - } - } else { - switch (prach_format) { // short preamble formats - case 0: - case 3: - return 8 + 3*mu; - - case 1: - case 4: - case 8: - return 5 + 3*mu; - - case 2: - case 5: - return 3 + 3*mu; - - case 6: - return 3*mu; - - case 7: - return 5 + 3*mu; - - default: - AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex); - } - } - return 0; -} - -// TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration -// Measurement units: -// - preambleReceivedTargetPower dBm (-202..-60, 2 dBm granularity) -// - delta_preamble dB -// - RA_PREAMBLE_POWER_RAMPING_STEP dB -// - POWER_OFFSET_2STEP_RA dB -// returns receivedTargerPower in dBm -int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - int8_t receivedTargerPower; - int8_t delta_preamble; - - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc != NULL) ? mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; - delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); - - receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA; - - LOG_D(MAC, "In %s: receivedTargerPower is %d dBm \n", __FUNCTION__, receivedTargerPower); - - return receivedTargerPower; -} - -void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, - uint8_t *nb_dmrs_re_per_rb, - uint16_t *number_dmrs_symbols){ - - int start_symbol = pusch_pdu->start_symbol_index; - uint8_t number_of_symbols = pusch_pdu->nr_of_symbols; - uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos; - uint8_t dmrs_type = pusch_pdu->dmrs_config_type; - uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data; - - *number_dmrs_symbols = 0; - for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) { - if((ul_dmrs_symb_pos >> i) & 0x01) - *number_dmrs_symbols += 1; - } - - *nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; - -} // Implementation of 6.2.4 Configured ransmitted power // 3GPP TS 38.101-1 version 16.5.0 Release 16 diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h old mode 100644 new mode 100755 similarity index 55% rename from openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c rename to openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h index d26a52f157..8b3f00af43 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h @@ -19,44 +19,8 @@ * contact@openairinterface.org */ -/*! \file PHY/NR_TRANSPORT/nr_dci_tools_common.c - * \brief - * \author - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: - * \note - * \warning - */ - -#include "nr_dci.h" - -//#define DEBUG_FILL_DCI - -#include "nr_dlsch.h" - - -void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { - - uint8_t count=0, start=0, start_set=0; - - uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)| - (((uint64_t)FreqDomainResource[1])<<29)| - (((uint64_t)FreqDomainResource[2])<<21)| - (((uint64_t)FreqDomainResource[3])<<13)| - (((uint64_t)FreqDomainResource[4])<<5)| - (((uint64_t)FreqDomainResource[5])>>3); - - for (int i=0; i<45; i++) - if ((bitmap>>(44-i))&1) { - count++; - if (!start_set) { - start = i; - start_set = 1; - } - } - *rb_offset = 6*start; - *n_rb = 6*count; -} - +/** \brief Function to compute configured maximum output power according to clause 6.2.4 of 3GPP TS 38.101-1 version 16.5.0 Release 16 + @param Mod_id Module id of UE +*/ +long nr_get_Pcmax(module_id_t mod_id); +/** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 83784634fc..2d059783fe 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -30,23 +30,18 @@ * \warning */ -/* Tools */ -#include "SIMULATION/TOOLS/sim.h" // for taus - /* RRC */ #include "NR_RACH-ConfigCommon.h" #include "RRC/NR_UE/rrc_proto.h" /* PHY */ -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" -#include "PHY/defs_common.h" -#include "PHY/defs_nr_common.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" /* MAC */ #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "NR_MAC_COMMON/nr_mac.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" +#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h" #include @@ -198,6 +193,130 @@ void init_RA(module_id_t mod_id, } } + +/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */ +int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc!=NULL) ? + mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; + NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; + int prach_sequence_length = (mac->scc!=NULL)?(mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1) : (mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1); + uint8_t prachConfigIndex, mu; + + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + + // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211 + + switch (scs){ + case NR_SubcarrierSpacing_kHz15: + mu = 0; + break; + + case NR_SubcarrierSpacing_kHz30: + mu = 1; + break; + + case NR_SubcarrierSpacing_kHz60: + mu = 2; + break; + + case NR_SubcarrierSpacing_kHz120: + mu = 3; + break; + + case NR_SubcarrierSpacing_kHz240: + mu = 4; + break; + + case NR_SubcarrierSpacing_spare3: + mu = 5; + break; + + case NR_SubcarrierSpacing_spare2: + mu = 6; + break; + + case NR_SubcarrierSpacing_spare1: + mu = 7; + break; + + default: + AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %lu\n", scs); + } + + // Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211 + + prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + + if (prach_sequence_length == 0) { + AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format); + switch (prach_format) { + + // long preamble formats + case 0: + case 3: + return 0; + + case 1: + return -3; + + case 2: + return -6; + } + } else { + switch (prach_format) { // short preamble formats + case 0: + case 3: + return 8 + 3*mu; + + case 1: + case 4: + case 8: + return 5 + 3*mu; + + case 2: + case 5: + return 3 + 3*mu; + + case 6: + return 3*mu; + + case 7: + return 5 + 3*mu; + + default: + AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex); + } + } + return 0; +} + +// TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration +// Measurement units: +// - preambleReceivedTargetPower dBm (-202..-60, 2 dBm granularity) +// - delta_preamble dB +// - RA_PREAMBLE_POWER_RAMPING_STEP dB +// - POWER_OFFSET_2STEP_RA dB +// returns receivedTargerPower in dBm +int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + int8_t receivedTargerPower; + int8_t delta_preamble; + + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc != NULL) ? mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; + long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; + delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); + + receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA; + + LOG_D(MAC, "In %s: receivedTargerPower is %d dBm \n", __FUNCTION__, receivedTargerPower); + + return receivedTargerPower; +} + void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){ // Determine the SSB to RACH mapping ratio @@ -280,6 +399,10 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t int PLThreshold = 0; long deltaPreamble_Msg3 = 0; uint8_t noGroupB = 0; + // Random seed generation + long long tmp = rdtsc_oai(); + unsigned short int *seed = (unsigned short int*)&tmp; + RA_config_t *ra = &mac->ra; NR_RACH_ConfigCommon_t *setup; if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; @@ -378,28 +501,28 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) { if (noGroupB) { // use Group A preamble - ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + ra->ra_PreambleIndex = ra->starting_preamble_nb + (nrand48(seed) % ra->cb_preambles_per_ssb); ra->RA_usedGroupA = 1; } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) { // Group B is configured and RA preamble Group A is used // - todo add condition on CCCH_sdu_size for initiation by CCCH - ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + ra->ra_PreambleIndex = ra->starting_preamble_nb + (nrand48(seed) % sizeOfRA_PreamblesGroupA); ra->RA_usedGroupA = 1; } else { // Group B preamble is configured and used // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A // the remaining belong to RA Preambles Group B - ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (nrand48(seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); ra->RA_usedGroupA = 0; } } } else { // Msg3 is being retransmitted if (ra->RA_usedGroupA && noGroupB) { - ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + ra->ra_PreambleIndex = ra->starting_preamble_nb + (nrand48(seed) % ra->cb_preambles_per_ssb); } else if (ra->RA_usedGroupA && !noGroupB){ - ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + ra->ra_PreambleIndex = ra->starting_preamble_nb + (nrand48(seed) % sizeOfRA_PreamblesGroupA); } else { - ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (nrand48(seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); } } prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex; @@ -467,7 +590,8 @@ void nr_get_prach_resources(module_id_t mod_id, if (rach_ConfigDedicated) { if (rach_ConfigDedicated->cfra){ uint8_t cfra_ssb_resource_idx = 0; - prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex; + ra->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex; + prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex; LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx); } } else { @@ -616,7 +740,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } else { - size_sdu = nr_write_ce_ulsch_pdu(pdu, mac); + size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL); pdu += size_sdu; ra->Msg3_size = size_sdu; @@ -837,6 +961,9 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; + // Random seed generation + long long tmp = rdtsc_oai(); + unsigned short int *seed = (unsigned short int*)&tmp; ra->first_Msg3 = 1; ra->ra_PreambleIndex = -1; @@ -850,7 +977,7 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax); - ra->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1); + ra->RA_backoff_cnt = nrand48(seed) % (prach_resources->RA_PREAMBLE_BACKOFF + 1); prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f06d50be48..d555014bc8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -54,7 +54,6 @@ /* PHY */ #include "PHY/NR_TRANSPORT/nr_dci.h" #include "executables/softmodem-common.h" -#include "SCHED_NR_UE/defs.h" /* utils */ #include "assertions.h" @@ -135,6 +134,55 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { }; +void nr_ue_init_mac(module_id_t module_idP) { + int i; + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + // default values as deined in 38.331 sec 9.2.2 + LOG_I(NR_MAC, "[UE%d] Applying default macMainConfig\n", module_idP); + //mac->scheduling_info.macConfig=NULL; + mac->scheduling_info.retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf10240; + mac->scheduling_info.periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_infinity; +// mac->scheduling_info.periodicPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; +// mac->scheduling_info.prohibitPHR_Timer = NR_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; +// mac->scheduling_info.PathlossChange_db = NR_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; +// mac->PHR_state = NR_MAC_MainConfig__phr_Config_PR_setup; + mac->scheduling_info.SR_COUNTER = 0; + mac->scheduling_info.sr_ProhibitTimer = 0; + mac->scheduling_info.sr_ProhibitTimer_Running = 0; +// mac->scheduling_info.maxHARQ_Tx = NR_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; +// mac->scheduling_info.ttiBundling = 0; +// mac->scheduling_info.extendedBSR_Sizes_r10 = 0; +// mac->scheduling_info.extendedPHR_r10 = 0; +// mac->scheduling_info.drx_config = NULL; +// mac->scheduling_info.phr_config = NULL; + // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW. + mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; + mac->BSR_reporting_active = BSR_TRIGGER_NONE; +// mac->scheduling_info.periodicPHR_SF = nr_get_sf_perioidicPHR_Timer(mac->scheduling_info.periodicPHR_Timer); +// mac->scheduling_info.prohibitPHR_SF = nr_get_sf_prohibitPHR_Timer(mac->scheduling_info.prohibitPHR_Timer); +// mac->scheduling_info.PathlossChange_db = nr_get_db_dl_PathlossChange(mac->scheduling_info.PathlossChange); +// mac->PHR_reporting_active = 0; + + for (i = 0; i < NR_MAX_NUM_LCID; i++) { + LOG_D(NR_MAC, "[UE%d] Applying default logical channel config for LCGID %d\n", + module_idP, i); + mac->scheduling_info.Bj[i] = -1; + mac->scheduling_info.bucket_size[i] = -1; + + if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0 + mac->scheduling_info.LCGID[i] = 0; + } else { // initialize all the data channels lcgid to 1 + mac->scheduling_info.LCGID[i] = 1; + } + + mac->scheduling_info.LCID_status[i] = LCID_EMPTY; + mac->scheduling_info.LCID_buffer_remain[i] = 0; + for (int i=0;ifirst_ul_tx[i]=1; + } +} + void get_bwp_info(NR_UE_MAC_INST_t *mac, int dl_bwp_id, int ul_bwp_id, @@ -1396,7 +1444,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, mac->cg->physicalCellGroupConfig && (mac->cg->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH != NULL || mac->cg->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook != 1)) { - LOG_E(PHY,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); + LOG_E(MAC,"PUCCH Unsupported cell group configuration : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return; } else if (mac->cg && @@ -2203,9 +2251,54 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, return false; } +int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){ + // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti + DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_NR_UE_MAC_INST, 0); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + DSR_TRANSMAX_t dsr_TransMax = sr_n64; // todo + LOG_D(NR_MAC, "[UE %d] Frame %d slot %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", + module_idP, frameP, slot, + mac->scheduling_info.SR_COUNTER, + (1 << (2 + dsr_TransMax)), + mac->scheduling_info.SR_pending); // todo -int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, int slotP){ - return 0; + if ((mac->scheduling_info.SR_pending == 1) && + (mac->scheduling_info.SR_COUNTER < (1 << (2 + dsr_TransMax)))) { + LOG_D(NR_MAC, "[UE %d] Frame %d slot %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d, increment SR_COUNTER\n", + module_idP, frameP, slot, + mac->scheduling_info.SR_COUNTER, + (1 << (2 + dsr_TransMax)), + mac->scheduling_info.SR_pending); // todo + mac->scheduling_info.SR_COUNTER++; + + // start the sr-prohibittimer : rel 9 and above + if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured + mac->scheduling_info.sr_ProhibitTimer--; + mac->scheduling_info. + sr_ProhibitTimer_Running = 1; + } else { + mac->scheduling_info. + sr_ProhibitTimer_Running = 0; + } + //mac->ul_active =1; + return (1); //instruct phy to signal SR + } else { + // notify RRC to relase PUCCH/SRS + // clear any configured dl/ul + // initiate RA + if (mac->scheduling_info.SR_pending) { + // release all pucch resource + //mac->physicalConfigDedicated = NULL; // todo + //mac->ul_active = 0; // todo + mac->BSR_reporting_active = + NR_BSR_TRIGGER_NONE; + LOG_I(NR_MAC, "[UE %d] Release all SRs \n", module_idP); + } + + mac->scheduling_info.SR_pending = 0; + mac->scheduling_info.SR_COUNTER = 0; + return (0); + } } @@ -3467,13 +3560,17 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, * Return: number of written bytes */ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac) { + NR_UE_MAC_INST_t *mac, + uint8_t power_headroom, // todo: NR_POWER_HEADROOM_CMD *power_headroom, + uint16_t *crnti, + NR_BSR_SHORT *truncated_bsr, + NR_BSR_SHORT *short_bsr, + NR_BSR_LONG *long_bsr) { int mac_ce_len = 0; uint8_t mac_ce_size = 0; - NR_UE_MAC_CE_t *nr_ue_mac_ce = &mac->nr_ue_mac_ce; - - if (nr_ue_mac_ce->phr_reporting && mac->phr_Config != NULL) { + uint8_t *pdu = mac_ce; + if (power_headroom) { // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; @@ -3481,21 +3578,22 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, mac_ce++; // PHR MAC CE (1 octet) - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = 0; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom; ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = 0; // todo ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0; // update pointer and length mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); - + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n", + pdu, mac_ce); } - if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED) { + if (crnti && (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != RA_SUCCEEDED)) { - LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, mac->crnti); + LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti)); // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; @@ -3503,7 +3601,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, mac_ce++; // C-RNTI MAC CE (2 octets) - *(uint16_t *) mac_ce = mac->crnti; + *(uint16_t *) mac_ce = (*crnti); // update pointer and length mac_ce_size = sizeof(uint16_t); @@ -3512,55 +3610,110 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, } - if (nr_ue_mac_ce->truncated_bsr) { + if (truncated_bsr) { - LOG_D(NR_MAC, "In %s: generating short truncated BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->truncated_bsr); - - // MAC CE fixed subheader + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; mac_ce++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = 0; - ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = 0; + ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size; + ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;; // update pointer and length mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", + truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce); - } else if (nr_ue_mac_ce->short_bsr) { + } else if (short_bsr) { - LOG_D(NR_MAC, "In %s: generating short BSR MAC CE with command %x\n", __FUNCTION__, nr_ue_mac_ce->short_bsr); - - // MAC CE fixed subheader + // MAC CE fixed subheader ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR; mac_ce++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT *) mac_ce)->Buffer_size = nr_ue_mac_ce->short_bsr; - ((NR_BSR_SHORT *) mac_ce)->LcgID = 0; + ((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size; + ((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID; // update pointer and length mac_ce_size = sizeof(NR_BSR_SHORT); mac_ce += mac_ce_size; mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", + short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce); + } else if (long_bsr) { - } else if (nr_ue_mac_ce->long_bsr) { - // MAC CE variable subheader - // todo ch 6.1.3.1. TS 38.321 - // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; - // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; - // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR; - // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0; - // sh_size = 2; + // MAC CE variable subheader + // ch 6.1.3.1. TS 38.321 + ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR; - // Short truncated BSR MAC CE (1 octet) - // ((NR_BSR_LONG *) mac_ce)->Buffer_size0 = short_bsr; - // ((NR_BSR_LONG *) mac_ce)->LCGID0 = 0; - // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable + NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce; + mac_ce += 2; + + // Could move to nr_get_sdu() + uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1; + //int NR_BSR_LONG_SIZE = 1; + if (long_bsr->Buffer_size0 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID0 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID0 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size0; + } + if (long_bsr->Buffer_size1 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID1 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID1 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size1; + } + if (long_bsr->Buffer_size2 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID2 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID2 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size2; + } + if (long_bsr->Buffer_size3 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID3 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID3 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size3; + } + if (long_bsr->Buffer_size4 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID4 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID4 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size4; + } + if (long_bsr->Buffer_size5 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID5 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID5 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size5; + } + if (long_bsr->Buffer_size6 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID6 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID6 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size6; + } + if (long_bsr->Buffer_size7 == 0) { + ((NR_BSR_LONG *) mac_ce)->LcgID7 = 0; + } else { + ((NR_BSR_LONG *) mac_ce)->LcgID7 = 1; + *Buffer_size_ptr++ = long_bsr->Buffer_size7; + } + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = mac_ce_size = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce; + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce), + ((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3, + ((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7); + // update pointer and length + mac_ce = Buffer_size_ptr; + mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT); } return mac_ce_len; @@ -3612,8 +3765,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t return 0; } - int cc_id = dl_info->cc_id; - uint8_t gNB_id = dl_info->gNB_index; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; uint8_t n_subPDUs = 0; // number of RAR payloads @@ -3625,7 +3776,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t int ret = 0; NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer - uint8_t preamble_index = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex; + uint8_t preamble_index = ra->ra_PreambleIndex; LOG_D(NR_MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 145b24f00e..f813efad92 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -53,6 +53,8 @@ #include +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" + static prach_association_pattern_t prach_assoc_pattern; static ssb_list_info_t ssb_list; @@ -164,13 +166,26 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + NR_BWP_UplinkDedicated_t *ubwpd=NULL; + + if (mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) + ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; + + NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0] ? + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup : + (ubwpd? + ubwpd->pusch_Config->choice.setup: + NULL); long transformPrecoder; - if (pusch_Config->transformPrecoder) + if (pusch_Config && pusch_Config->transformPrecoder) transformPrecoder = *pusch_Config->transformPrecoder; else { - if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder) + if(scc && scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder) transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; else transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; @@ -840,7 +855,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, return -1; } - get_num_re_dmrs(pusch_config_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols); + int start_symbol = pusch_config_pdu->start_symbol_index; + int number_of_symbols = pusch_config_pdu->nr_of_symbols; + for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) { + if((pusch_config_pdu->ul_dmrs_symb_pos >> i) & 0x01) + number_dmrs_symbols += 1; + } + + nb_dmrs_re_per_rb = ((pusch_config_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6:4)*pusch_config_pdu->num_dmrs_cdm_grps_no_data; // Compute TBS pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order, @@ -997,10 +1019,324 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } } + if (dl_info) { + return (CONNECTION_OK); + } + module_id_t mod_id = ul_info->module_id; + frame_t txFrameP = ul_info->frame_tx; + slot_t txSlotP = ul_info->slot_tx; + + // Handle the SR/BSR procedures per subframe + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + uint8_t gNB_indexP=0; + + // Call BSR procedure as described in Section 5.4.5 in 38.321 + + // First check ReTxBSR Timer because it is always configured + // Decrement ReTxBSR Timer if it is running and not null + if ((mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.retxBSR_SF != 0)) { + mac->scheduling_info.retxBSR_SF--; + } + + // Decrement Periodic Timer if it is running and not null + if ((mac->scheduling_info.periodicBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) && (mac->scheduling_info.periodicBSR_SF != 0)) { + mac->scheduling_info.periodicBSR_SF--; + } + + //Check whether Regular BSR is triggered + if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == TRUE) { + // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures + // outlined in Sections 5.4.4 an 5.4.5 of 38.321 + mac->scheduling_info.SR_pending = 1; + // Regular BSR trigger + mac->BSR_reporting_active |= NR_BSR_TRIGGER_REGULAR; + LOG_D(NR_MAC, "[UE %d][BSR] Regular BSR Triggered Frame %d slot %d SR for PUSCH is pending\n", + mod_id, txFrameP, txSlotP); + } return UE_CONNECTION_OK; } +boolean_t +nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) { + mac_rlc_status_resp_t rlc_status; + boolean_t bsr_regular_triggered = FALSE; + uint8_t lcid; + uint8_t lcgid; + uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined + uint32_t lcgid_buffer_remain[NR_MAX_NUM_LCGID] = {0,0,0,0,0,0,0,0}; + int32_t lcid_bytes_in_buffer[NR_MAX_NUM_LCID]; + /* Array for ordering LCID with data per decreasing priority order */ + uint8_t lcid_reordered_array[NR_MAX_NUM_LCID]= + {NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID,NR_MAX_NUM_LCID, + }; + uint8_t pos_next = 0; + //uint8_t highest_priority = 16; + uint8_t array_index = 0; + // Reset All BSR Infos + lcid_bytes_in_buffer[0] = 0; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { + // Reset transmission status + lcid_bytes_in_buffer[lcid] = 0; + mac->scheduling_info.LCID_status[lcid]=LCID_EMPTY; + } + + for (lcgid=0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { + // Reset Buffer Info + mac->scheduling_info.BSR[lcgid]=0; + mac->scheduling_info.BSR_bytes[lcgid]=0; + } + + //Get Buffer Occupancy and fill lcid_reordered_array + for (lcid=DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { + //if (mac->logicalChannelConfig[lcid]) { + if (mac->logicalChannelBearer_exist[lcid] ) { // todo + lcgid = mac->scheduling_info.LCGID[lcid]; + + // Store already available data to transmit per Group + if (lcgid < NR_MAX_NUM_LCGID) { + lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid]; + } + + rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0); + + lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n", + module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP); + mac->scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; + + //Update BSR_bytes and position in lcid_reordered_array only if Group is defined + if (lcgid < NR_MAX_NUM_LCGID) { + num_lcid_with_data ++; + // sum lcid buffer which has same lcgid + mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer; + //Fill in the array + array_index = 0; + + do { + //if (mac->logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) { + if (1) { // todo + //Insert if priority is higher or equal (lower or equal in value) + for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) { + lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; + } + + lcid_reordered_array[array_index] = lcid; + break; + } + + array_index ++; + } while ((array_index < num_lcid_with_data) && (array_index < NR_MAX_NUM_LCID)); + } + } + } + } + + // Check whether a regular BSR can be triggered according to the first cases in 38.321 + if (num_lcid_with_data) { + LOG_D(NR_MAC, "[UE %d] PDCCH Tick at frame %d slot %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n", + module_idP, frameP, slotP, num_lcid_with_data, + lcid_reordered_array[0], lcid_reordered_array[1], + lcid_reordered_array[2]); + + for (array_index = 0; array_index < num_lcid_with_data; array_index++) { + lcid = lcid_reordered_array[array_index]; + + /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity + either the data belongs to a logical channel with higher priority than the priorities of the logical channels + which belong to any LCG and for which data is already available for transmission + */ + { + bsr_regular_triggered = TRUE; + LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", + module_idP, lcid, + mac->scheduling_info.LCGID[lcid], + frameP, slotP); + break; + } + } + + // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission + if (mac->scheduling_info.retxBSR_SF == 0) { + bsr_regular_triggered = TRUE; + + if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) { + LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n", + module_idP, frameP, slotP); + } + } + } + + //Store Buffer Occupancy in remain buffers for next TTI + for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { + mac->scheduling_info.LCID_buffer_remain[lcid] = lcid_bytes_in_buffer[lcid]; + } + + return bsr_regular_triggered; +} + +uint8_t +nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) { + uint8_t ju, jm, jl; + int ascend; + //DevAssert(size > 0); + //DevAssert(size <= 256); + + if (value == 0) { + return 0; //elseif (value > 150000) return 63; + } + + jl = 0; // lower bound + ju = size - 1; // upper bound + ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise + + while (ju - jl > 1) { //If we are not yet done, + jm = (ju + jl) >> 1; //compute a midpoint, + + if ((value >= table[jm]) == ascend) { + jl = jm; // replace the lower limit + } else { + ju = jm; //replace the upper limit + } + + LOG_T(NR_MAC, "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n", + jm, table[jm], value); + } + + if (value == table[jl]) { + return jl; + } else { + return jl + 1; //equally ju + } +} + +int nr_get_sf_periodicBSRTimer(uint8_t sf_offset) { + switch (sf_offset) { + case NR_BSR_Config__periodicBSR_Timer_sf1: + return 1; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf5: + return 5; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf10: + return 10; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf16: + return 16; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf20: + return 20; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf32: + return 32; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf40: + return 40; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf64: + return 64; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf80: + return 80; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf128: + return 128; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf160: + return 160; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf320: + return 320; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf640: + return 640; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf1280: + return 1280; + break; + + case NR_BSR_Config__periodicBSR_Timer_sf2560: + return 2560; + break; + + case NR_BSR_Config__periodicBSR_Timer_infinity: + default: + return 0xFFFF; + break; + } +} + +int nr_get_sf_retxBSRTimer(uint8_t sf_offset) { + switch (sf_offset) { + case NR_BSR_Config__retxBSR_Timer_sf10: + return 10; + break; + + case NR_BSR_Config__retxBSR_Timer_sf20: + return 20; + break; + + case NR_BSR_Config__retxBSR_Timer_sf40: + return 40; + break; + + case NR_BSR_Config__retxBSR_Timer_sf80: + return 80; + break; + + case NR_BSR_Config__retxBSR_Timer_sf160: + return 160; + break; + + case NR_BSR_Config__retxBSR_Timer_sf320: + return 320; + break; + + case NR_BSR_Config__retxBSR_Timer_sf640: + return 640; + break; + + case NR_BSR_Config__retxBSR_Timer_sf1280: + return 1280; + break; + + case NR_BSR_Config__retxBSR_Timer_sf2560: + return 2560; + break; + + case NR_BSR_Config__retxBSR_Timer_sf5120: + return 5120; + break; + + case NR_BSR_Config__retxBSR_Timer_sf10240: + return 10240; + break; + + default: + return -1; + break; + } +} + // PUSCH scheduler: // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, // - where K2 is the offset between the slot in which UL DCI is received and the slot @@ -1993,6 +2329,7 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, ssb_start_symbol, scs_ssb, frequency_range, + mac->nr_band, ssb_index, 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame ssb_offset_point_a); @@ -2033,6 +2370,261 @@ void nr_ue_sib1_scheduler(module_id_t module_idP, #define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID +typedef struct { + uint8_t bsr_len; + uint8_t bsr_ce_len; + uint8_t bsr_header_len; + uint8_t phr_len; + uint8_t phr_ce_len; + uint8_t phr_header_len; + uint16_t sdu_length_total; + NR_BSR_SHORT *bsr_s; + NR_BSR_LONG *bsr_l; + NR_BSR_SHORT *bsr_t; + //NR_POWER_HEADROOM_CMD *phr_pr; + int tot_mac_ce_len; + uint8_t total_mac_pdu_header_len; +} NR_UE_MAC_CE_INFO; + +/* +nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field +Need nothing from mac_ce_p: +Update the following in mac_ce_p: + bsr_len; + bsr_ce_len; + bsr_header_len; + phr_len; TBD + phr_ce_len; TBD + phr_header_len; TBD +*/ +int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen, + NR_UE_MAC_CE_INFO *mac_ce_p) { + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + + int num_lcg_id_with_data = 0; + // Preparing the MAC CEs sub-PDUs and get the total size + mac_ce_p->bsr_header_len = 0; + mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED); + int lcg_id = 0; + while (lcg_id < NR_MAX_NUM_LCGID) { + if (mac->scheduling_info.BSR_bytes[lcg_id]) { + num_lcg_id_with_data++; + } + + lcg_id++; + } + + //Restart ReTxBSR Timer at new grant indication (38.321) + if (mac->scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING) { + mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer); + } + + // periodicBSR-Timer expires, trigger BSR + if ((mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity) + && (mac->scheduling_info.periodicBSR_SF == 0)) { + // Trigger BSR Periodic + mac->BSR_reporting_active |= NR_BSR_TRIGGER_PERIODIC; + LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n", + module_idP, frameP, subframe, buflen); + } + + //Compute BSR Length if Regular or Periodic BSR is triggered + //WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx + if (mac->BSR_reporting_active) { + AssertFatal((mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING) == 0, + "Inconsistent BSR Trigger=%d !\n", + mac->BSR_reporting_active); + + //A Regular or Periodic BSR can only be sent if TBS is sufficient as transmitting only a BSR is not allowed if UE has data to transmit + if (num_lcg_id_with_data <= 1) { + if (buflen >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED)+1)) { + mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte + } + } else { + if (buflen >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT)+1)) { + mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes + } + } + } + + mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len; + return (mac_ce_p->bsr_len + mac_ce_p->phr_len); +} + +/* +nr_ue_get_sdu_mac_ce_post recalculates length and prepares the mac_ce field +Need the following from mac_ce_p: + bsr_ce_len + bsr_len + sdu_length_total + total_mac_pdu_header_len +Update the following in mac_ce_p: + bsr_ce_len + bsr_header_len + bsr_len + tot_mac_ce_len + total_mac_pdu_header_len + bsr_s + bsr_l + bsr_t +*/ +void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint16_t buflen, + NR_UE_MAC_CE_INFO *mac_ce_p) { + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + + // Compute BSR Values and update Nb LCGID with data after multiplexing + unsigned short padding_len = 0; + uint8_t lcid = 0; + int lcg_id = 0; + int num_lcg_id_with_data = 0; + int lcg_id_bsr_trunc = 0; + for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { + if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) { + mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); + } else { + mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]); + } + if (mac->scheduling_info.BSR_bytes[lcg_id]) { + num_lcg_id_with_data++; + lcg_id_bsr_trunc = lcg_id; + } + } + + // TS 38.321 Section 5.4.5 + // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order + // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 + /* For Padding BSR: + - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: + - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; + - else report Short BSR. + - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. + */ + if (mac_ce_p->sdu_length_total) { + padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); + } + + if ((padding_len) && (mac_ce_p->bsr_len == 0)) { + /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */ + if (padding_len >= (num_lcg_id_with_data+1+sizeof(NR_MAC_SUBHEADER_SHORT))) { + mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes + // Trigger BSR Padding + mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING; + } else if (padding_len >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED))) { + mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte + mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte + + if (num_lcg_id_with_data > 1) { + // REPORT SHORT TRUNCATED BSR + //Get LCGID of highest priority LCID with data (todo) + for (lcid = DCCH; lcid < NR_MAX_NUM_LCID; lcid++) { + lcg_id = mac->scheduling_info.LCGID[lcid]; + if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) { + lcg_id_bsr_trunc = lcg_id; + } + } + } else { + //Report SHORT BSR, clear bsr_t + mac_ce_p->bsr_t = NULL; + } + + // Trigger BSR Padding + mac->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING; + } + + mac_ce_p->bsr_len = mac_ce_p->bsr_header_len + mac_ce_p->bsr_ce_len; + mac_ce_p->tot_mac_ce_len += mac_ce_p->bsr_len; + mac_ce_p->total_mac_pdu_header_len += mac_ce_p->bsr_len; + } + + //Fill BSR Infos + if (mac_ce_p->bsr_ce_len == 0) { + mac_ce_p->bsr_s = NULL; + mac_ce_p->bsr_l = NULL; + mac_ce_p->bsr_t = NULL; + } else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) { + mac_ce_p->bsr_s = NULL; + mac_ce_p->bsr_t = NULL; + mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0]; + mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1]; + mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2]; + mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3]; + mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4]; + mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5]; + mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6]; + mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7]; + LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n", + module_idP, frameP, subframe, + mac->BSR_reporting_active, + mac->scheduling_info.BSR[0], + mac->scheduling_info.BSR[1], + mac->scheduling_info.BSR[2], + mac->scheduling_info.BSR[3], + mac->scheduling_info.BSR[4], + mac->scheduling_info.BSR[5], + mac->scheduling_info.BSR[6], + mac->scheduling_info.BSR[7]); + } else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) { + mac_ce_p->bsr_l = NULL; + + if ((mac_ce_p->bsr_t != NULL) && (mac->BSR_reporting_active & NR_BSR_TRIGGER_PADDING)) { + //Truncated BSR + mac_ce_p->bsr_s = NULL; + mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc; + mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc]; + LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n", + module_idP, frameP, subframe, + mac->BSR_reporting_active, + mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); + } else { + mac_ce_p->bsr_t = NULL; + mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc; + mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc]; + LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n", + module_idP, frameP, subframe, + mac->BSR_reporting_active, + mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); + } + } + + LOG_D(NR_MAC, "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP); + mac->scheduling_info.SR_pending = 0; + mac->scheduling_info.SR_COUNTER = 0; + + /* Actions when a BSR is sent */ + if (mac_ce_p->bsr_ce_len) { + LOG_D(NR_MAC, "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", + module_idP, mac_ce_p->bsr_ce_len, mac_ce_p->bsr_header_len, buflen); + // Reset ReTx BSR Timer + mac->scheduling_info.retxBSR_SF = nr_get_sf_retxBSRTimer(mac->scheduling_info.retxBSR_Timer); + LOG_D(NR_MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, mac->scheduling_info.retxBSR_SF); + + // Reset Periodic Timer except when BSR is truncated + if ((mac_ce_p->bsr_t == NULL) && (mac->scheduling_info.periodicBSR_Timer != NR_BSR_Config__periodicBSR_Timer_infinity)) { + mac->scheduling_info.periodicBSR_SF = nr_get_sf_periodicBSRTimer(mac->scheduling_info.periodicBSR_Timer); + LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", + module_idP, + mac->scheduling_info.periodicBSR_SF); + } + + // Reset BSR Trigger flags + mac->BSR_reporting_active = BSR_TRIGGER_NONE; + } +} /** * Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer @@ -2053,31 +2645,45 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, uint8_t gNB_index, uint8_t *ulsch_buffer, uint16_t buflen) { - + NR_UE_MAC_CE_INFO mac_ce_info; + NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info; int16_t buflen_remain = 0; + mac_ce_p->bsr_len = 0; + mac_ce_p->bsr_ce_len = 0; + mac_ce_p->bsr_header_len = 0; + mac_ce_p->phr_len = 0; + //mac_ce_p->phr_ce_len = 0; + //mac_ce_p->phr_header_len = 0; + uint8_t lcid = 0; uint16_t sdu_length = 0; uint16_t num_sdus = 0; - uint16_t sdu_length_total = 0; + mac_ce_p->sdu_length_total = 0; + NR_BSR_SHORT bsr_short, bsr_truncated; + NR_BSR_LONG bsr_long; + mac_ce_p->bsr_s = &bsr_short; + mac_ce_p->bsr_l = &bsr_long; + mac_ce_p->bsr_t = &bsr_truncated; + //NR_POWER_HEADROOM_CMD phr; + //mac_ce_p->phr_p = &phr; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + //int highest_priority = 16; const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); // Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer uint8_t *pdu = ulsch_buffer; - // Preparing the MAC CEs sub-PDUs and get the total size - unsigned char mac_header_control_elements[16] = {0}; - int tot_mac_ce_len = nr_write_ce_ulsch_pdu(&mac_header_control_elements[0], mac); - uint8_t total_mac_pdu_header_len = tot_mac_ce_len; + //nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length + mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p); + mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len; LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen); // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = UL_SCH_LCID_SRB1; - lcid < MAX_LCID; lcid++) { + for (lcid = UL_SCH_LCID_SRB1; lcid < MAX_LCID; lcid++) { - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size); + buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d bytes, buflen_remain %d bytes)\n", __FUNCTION__, @@ -2086,8 +2692,8 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, subframe, lcid, buflen, - sdu_length_total, - tot_mac_ce_len, + mac_ce_p->sdu_length_total, + mac_ce_p->tot_mac_ce_len, buflen_remain); while (buflen_remain > 0){ @@ -2117,7 +2723,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, if (sdu_length > 0) { - LOG_D(MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, + LOG_D(NR_MAC, "In %s: Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x (buflen (TBS) %d bytes)\n", __FUNCTION__, num_sdus + 1, sdu_length, lcid, @@ -2137,40 +2743,53 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP, #endif pdu += sdu_length; - sdu_length_total += sdu_length; - total_mac_pdu_header_len += sh_size; + mac_ce_p->sdu_length_total += sdu_length; + mac_ce_p->total_mac_pdu_header_len += sh_size; num_sdus++; } else { pdu -= sh_size; - LOG_D(MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); + LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n", __FUNCTION__, lcid); break; } - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total + sh_size); + buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); + //Update Buffer remain and BSR bytes after transmission + mac->scheduling_info.LCID_buffer_remain[lcid] -= sdu_length; + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] -= sdu_length; + LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n", + module_idP, frameP, subframe, mac->scheduling_info.LCGID[lcid], + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]]); + if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] < 0) + mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid]] = 0; } } - if (tot_mac_ce_len > 0) { + //nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req. + //Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total. + nr_ue_get_sdu_mac_ce_post(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p); - LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, tot_mac_ce_len); - memcpy((void *) pdu, (void *) mac_header_control_elements, tot_mac_ce_len); - pdu += (unsigned char) tot_mac_ce_len; + if (mac_ce_p->tot_mac_ce_len > 0) { + + LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len); + nr_write_ce_ulsch_pdu(pdu, mac, 0, NULL, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l); + pdu += (unsigned char) mac_ce_p->tot_mac_ce_len; #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, tot_mac_ce_len); - log_dump(NR_MAC, mac_header_control_elements, tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len); + log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); #endif } - buflen_remain = buflen - (total_mac_pdu_header_len + sdu_length_total); + buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); // Compute final offset for padding and fill remainder of ULSCH with 0 if (buflen_remain > 0) { + LOG_D(NR_MAC, "In %s filling remainder %d bytes to the UL PDU \n", __FUNCTION__, buflen_remain); ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index a2c130078e..cedd095794 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -33,7 +33,7 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" #include "common/ran_context.h" - +#include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 956a76ddbb..b62f8e0282 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -46,9 +46,6 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#include "openair1/PHY/defs_gNB.h" -#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" - #include "intertask_interface.h" #include "executables/softmodem-common.h" @@ -62,85 +59,6 @@ uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; uint8_t vnf_first_sched_entry = 1; -void clear_mac_stats(gNB_MAC_INST *gNB) { - memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); -} -#define MACSTATSSTRLEN 16384 -void dump_mac_stats(gNB_MAC_INST *gNB) -{ - NR_UE_info_t *UE_info = &gNB->UE_info; - int num = 1; - FILE *fd=fopen("nrMAC_stats.log","w"); - AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); - char output[MACSTATSSTRLEN]; - memset(output,0,MACSTATSSTRLEN); - int stroff=0; - for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { - - stroff+=sprintf(output+stroff,"UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n", - UE_id, - UE_info->rnti[UE_id], - num++, - UE_info->num_UEs, - UE_info->UE_sched_ctrl[UE_id].ph, - UE_info->UE_sched_ctrl[UE_id].pcmax); - - LOG_I(NR_MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n", - UE_id, - UE_info->rnti[UE_id], - num++, - UE_info->num_UEs, - UE_info->UE_sched_ctrl[UE_id].ph, - UE_info->UE_sched_ctrl[UE_id].pcmax); - - NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; - const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d average RSRP %d (%d meas)\n", - UE_id, - stats->dlsch_rounds[0], stats->dlsch_rounds[1], - stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors, - stats->pucch0_DTX, - avg_rsrp, stats->num_rsrp_meas); - LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d\n", - UE_id, stats->dlsch_rounds[0], stats->dlsch_rounds[1], stats->dlsch_rounds[2], stats->dlsch_rounds[3], - stats->dlsch_errors, stats->pucch0_DTX); - stats->num_rsrp_meas = 0; - stats->cumul_rsrp = 0 ; - stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); - stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", - UE_id, - stats->ulsch_rounds[0], stats->ulsch_rounds[1], - stats->ulsch_rounds[2], stats->ulsch_rounds[3], - stats->ulsch_DTX, - stats->ulsch_errors); - stroff+=sprintf(output+stroff, - "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", - UE_id, - stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); - LOG_I(NR_MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); - LOG_I(NR_MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d, ulsch_DTX %d\n", - UE_id, stats->ulsch_rounds[0], stats->ulsch_rounds[1], stats->ulsch_rounds[2], stats->ulsch_rounds[3], - stats->ulsch_errors, stats->ulsch_DTX); - LOG_I(NR_MAC, - "UE %d: ulsch_total_bytes (scheduled/received): %d / %d\n", - UE_id, - stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); - for (int lc_id = 0; lc_id < 63; lc_id++) { - if (stats->lc_bytes_tx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); - } - if (stats->lc_bytes_rx[lc_id] > 0) { - stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); - LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); - } - } - } - print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL); - if (stroff>0) fprintf(fd,"%s",output); - fclose(fd); -} - void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, @@ -359,6 +277,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); const int bwp_id = 1; + char stats_output[16384]; gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = gNB->common_channels; @@ -426,8 +345,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } - if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); - + if ((slot == 0) && (frame & 127) == 0) { + stats_output[0]='\0'; + dump_mac_stats(RC.nrmac[module_idP],stats_output,16384); + LOG_I(NR_MAC,"Frame.Slot %d.%d\n%s\n",frame,slot,stats_output); + } // This schedules MIB schedule_nr_mib(module_idP, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index c6752d37c2..71bab705ef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -261,6 +261,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP else mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + int bwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 if ( get_nr_prach_info_from_index(config_index, @@ -387,7 +389,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch); uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE]; for (int i = 0; i < N_RA_RB * fdm; ++i) - vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols + vrb_map_UL[bwp_start + rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols } } } @@ -772,7 +774,6 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t // generation of DCI 0_0 to schedule msg3 retransmission NR_SearchSpace_t *ss = ra->ra_ss; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = *ss->controlResourceSetId==0 ? &nr_mac->type0_PDCCH_CSS_config[ra->beam_id] : NULL; NR_ControlResourceSet_t *coreset = get_coreset(module_idP, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common); AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n"); @@ -787,7 +788,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config); + nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL); nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15; } @@ -917,10 +918,19 @@ void nr_get_Msg3alloc(module_id_t module_id, LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex); uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; - const uint16_t bwpSize = NRRIV2BW(ubwp ? - ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, - MAX_BWP_SIZE); + + int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + if (ra->CellGroup) { + AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; + int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (!((bwpStart >= act_bwp_start) && ((bwpStart+bwpSize) <= (act_bwp_start+act_bwp_size)))) + bwpStart = act_bwp_start; + } /* search msg3_nb_rb free RBs */ int rbSize = 0; @@ -928,16 +938,17 @@ void nr_get_Msg3alloc(module_id_t module_id, while (rbSize < msg3_nb_rb) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; - while (rbStart < bwpSize && vrb_map_UL[rbStart]) + while (rbStart < bwpSize && vrb_map_UL[rbStart + bwpStart]) rbStart++; AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n"); while (rbStart + rbSize < bwpSize - && !vrb_map_UL[rbStart + rbSize] + && !vrb_map_UL[rbStart + bwpStart + rbSize] && rbSize < msg3_nb_rb) rbSize++; } ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; + ra->msg3_bwp_start = bwpStart; } @@ -1023,12 +1034,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; for (int i = 0; i < ra->msg3_nb_rb; ++i) { - AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb], + AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start], "RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n", i + ra->msg3_first_rb, ra->Msg3_frame, ra->Msg3_slot); - vrb_map_UL[i + ra->msg3_first_rb] = 1; + vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] = 1; } LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); @@ -1047,9 +1058,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int abwp_size = ibwp_size; - int abwp_start = ibwp_start; int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; int fh = 0; int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; @@ -1062,8 +1070,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; - abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0; } @@ -1078,17 +1084,11 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t ra->msg3_round, ra->rnti); - int bwp_start; - if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) - bwp_start = abwp_start; - else - bwp_start = ibwp_start; - fill_msg3_pusch_pdu(pusch_pdu,scc, ra->msg3_round, startSymbolAndLength, ra->rnti, scs, - ibwp_size, bwp_start, + ibwp_size, ra->msg3_bwp_start, mappingtype, fh, ra->msg3_first_rb, ra->msg3_nb_rb); future_ul_tti_req->n_pdus += 1; @@ -1150,7 +1150,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint16_t *vrb_map = cc[CC_id].vrb_map; for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { - if (vrb_map[rbStart + i]) { + if (vrb_map[BWPStart + rbStart + i]) { rbStart += i; i = 0; } @@ -1204,7 +1204,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config); + nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL); nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15; } @@ -1364,7 +1364,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // Mark the corresponding RBs as used for (int rb = 0; rb < rbSize; rb++) { - vrb_map[rb + rbStart] = 1; + vrb_map[BWPStart + rb + rbStart] = 1; } ra->state = WAIT_Msg3; @@ -1547,7 +1547,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra int i = 0; while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { - if (vrb_map[rbStart + i]) { + if (vrb_map[BWPStart + rbStart + i]) { rbStart += i+1; i = 0; } else { @@ -1580,7 +1580,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, type0_PDCCH_CSS_config); + nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL); nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15; } @@ -1723,7 +1723,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // Mark the corresponding RBs as used for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) { - vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; + vrb_map[BWPStart + rb + pdsch_pdu_rel15->rbStart] = 1; } LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 28b7ea3c21..f35de9e28b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -219,6 +219,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol, scs, FR1, + band, i_ssb, ssb_frame_periodicity, offset_pointa); @@ -246,6 +247,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol, scs, FR1, + band, i_ssb, ssb_frame_periodicity, offset_pointa); @@ -281,6 +283,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol, scs, FR2, + band, i_ssb, ssb_frame_periodicity, offset_pointa); @@ -336,6 +339,8 @@ uint32_t schedule_control_sib1(module_id_t module_id, gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset)); fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,type0_PDCCH_CSS_config); fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config); + gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb; + gNB_mac->cset0_bwp_size = type0_PDCCH_CSS_config->num_rbs; } gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation; @@ -433,7 +438,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, + nr_configure_pdcch(NULL, + pdcch_pdu_rel15, gNB_mac->sched_ctrlCommon->search_space, gNB_mac->sched_ctrlCommon->coreset, scc, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index d32e45a379..e9487b4714 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -29,11 +29,7 @@ */ -/*PHY*/ -#include "PHY/CODING/coding_defs.h" -#include "PHY/defs_nr_common.h" #include "common/utils/nr/nr_common.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" /*MAC*/ #include "NR_MAC_COMMON/nr_mac.h" #include "NR_MAC_gNB/nr_mac_gNB.h" @@ -485,7 +481,7 @@ bool allocate_dl_retransmission(module_id_t module_id, &RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = 0; // start wrt BWPstart NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; const long f = (sched_ctrl->active_bwp ||bwpd) ? sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; @@ -569,12 +565,12 @@ bool allocate_dl_retransmission(module_id_t module_id, return false; } - sched_ctrl->sched_pdsch.pucch_allocation = alloc; - /* just reuse from previous scheduling opportunity, set new start RB */ sched_ctrl->sched_pdsch = *retInfo; sched_ctrl->sched_pdsch.rbStart = rbStart; + sched_ctrl->sched_pdsch.pucch_allocation = alloc; + /* retransmissions: directly allocate */ *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++) @@ -675,7 +671,7 @@ void pf_dl(module_id_t module_id, &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - int rbStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = 0; // start wrt BWPstart /* Find a free CCE */ bool freeCCE = find_free_CCE(module_id, slot, UE_id); @@ -764,6 +760,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth: scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp ? + sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth: + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, + MAX_BWP_SIZE); uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; uint8_t rballoc_mask[bwpSize]; @@ -771,7 +771,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t for (int i = 0; i < bwpSize; i++) { // calculate mask: init with "NOT" vrb_map: // if any RB in vrb_map is blocked (1), the current RBG will be 0 - rballoc_mask[i] = !vrb_map[i]; + rballoc_mask[i] = !vrb_map[i+BWPStart]; n_rb_sched += rballoc_mask[i]; } @@ -894,7 +894,7 @@ void nr_schedule_ue_spec(module_id_t module_id, UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; LOG_D(NR_MAC, - "%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) TPC %d\n", + "%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", frame, slot, UE_id, @@ -914,6 +914,7 @@ void nr_schedule_ue_spec(module_id_t module_id, pucch->timing_indicator, pucch->frame, pucch->ul_slot, + sched_pdsch->pucch_allocation, sched_ctrl->tpc1); NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; @@ -937,7 +938,7 @@ void nr_schedule_ue_spec(module_id_t module_id, LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwpid,coresetid); NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space:gNB_mac->sched_ctrlCommon->search_space; NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset; - nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL); + nr_configure_pdcch(gNB_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL); gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 2b1c26b82a..f1005cea70 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -29,11 +29,8 @@ */ #include "nr_mac_gNB.h" -#include "SCHED_NR/sched_nr.h" #include "NR_MAC_gNB/mac_proto.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "PHY/NR_TRANSPORT/nr_dci.h" #include "executables/nr-softmodem.h" #include "LAYER2/NR_MAC_COMMON/nr_mac.h" #include "executables/softmodem-common.h" @@ -283,6 +280,7 @@ void nr_preprocessor_phytest(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; /* find largest unallocated chunk */ const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int rbStart = 0; int rbSize = 0; if (target_dl_bw>bwpSize) @@ -291,11 +289,11 @@ void nr_preprocessor_phytest(module_id_t module_id, /* loop ensures that we allocate exactly target_dl_bw, or return */ while (true) { /* advance to first free RB */ - while (rbStart < bwpSize && vrb_map[rbStart]) + while (rbStart < bwpSize && vrb_map[rbStart + BWPStart]) rbStart++; rbSize = 1; /* iterate until we are at target_dl_bw or no available RBs */ - while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw) + while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize + BWPStart] && rbSize < target_dl_bw) rbSize++; /* found target_dl_bw? */ if (rbSize == target_dl_bw) @@ -376,14 +374,12 @@ void nr_preprocessor_phytest(module_id_t module_id, sched_pdsch->rbStart = rbStart; sched_pdsch->rbSize = rbSize; const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1; - const uint8_t num_dmrs_cdm_grps_no_data = 1; - const long f = 1; + const long f = sched_ctrl->active_bwp ? sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; ps->nrOfLayers = target_dl_Nl; - if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data) + if (ps->time_domain_allocation != tda) nr_set_pdsch_semi_static( scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, f, ps); - sched_pdsch->mcs = target_dl_mcs; sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); @@ -402,7 +398,7 @@ void nr_preprocessor_phytest(module_id_t module_id, /* mark the corresponding RBs as used */ for (int rb = 0; rb < sched_pdsch->rbSize; rb++) - vrb_map[rb + sched_pdsch->rbStart] = 1; + vrb_map[rb + sched_pdsch->rbStart + BWPStart] = 1; if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize); } @@ -464,8 +460,11 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ uint16_t rbSize; const int bw = NRRIV2BW(sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ? + sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); if (target_ul_bw>bw) rbSize = bw; @@ -476,7 +475,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; const uint16_t symb = ((1 << ps->nrOfSymbols) - 1) << ps->startSymbolIndex; for (int i = rbStart; i < rbStart + rbSize; ++i) { - if ((vrb_map_UL[i] & symb) != 0) { + if ((vrb_map_UL[i+BWPStart] & symb) != 0) { LOG_E(MAC, "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n", __func__, @@ -545,6 +544,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ /* mark the corresponding RBs as used */ for (int rb = rbStart; rb < rbStart + rbSize; rb++) - vrb_map_UL[rb] = 1; + vrb_map_UL[rb+BWPStart] = 1; return true; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 668a88d746..7387bfe698 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -723,7 +723,8 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { return(default_pucch_csset[pucch_ResourceCommon]); } -void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, +void nr_configure_pdcch(gNB_MAC_INST *gNB_mac, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, NR_ServingCellConfigCommon_t *scc, @@ -731,9 +732,19 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { int sps; - if (bwp && *ss->controlResourceSetId!=0) { // This is not for coreset0 - pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE); - pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE); + AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId, + "coreset id in SS %ld does not correspond to the one in coreset %ld", + *ss->controlResourceSetId, coreset->controlResourceSetId); + + if (bwp) { // This is not for SIB1 + if(coreset->controlResourceSetId == 0){ + pdcch_pdu->BWPSize = gNB_mac->cset0_bwp_size; + pdcch_pdu->BWPStart = gNB_mac->cset0_bwp_start; + } + else { + pdcch_pdu->BWPSize = NRRIV2BW(bwp->locationAndBandwidth, MAX_BWP_SIZE); + pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->locationAndBandwidth, MAX_BWP_SIZE); + } pdcch_pdu->SubcarrierSpacing = bwp->subcarrierSpacing; pdcch_pdu->CyclicPrefix = (bwp->cyclicPrefix==NULL) ? 0 : *bwp->cyclicPrefix; @@ -1334,28 +1345,28 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, pos = 1; // Freq domain assignment 0-16 bit fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); - LOG_D(PHY, "fsize = %i\n", fsize); + LOG_D(NR_MAC, "fsize = %i\n", fsize); for (int i = 0; i < fsize; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val >> (fsize - i - 1)) & 1) << (dci_size - pos++); - LOG_D(PHY, "dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(NR_MAC, "dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); // Time domain assignment 4 bit for (int i = 0; i < 4; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val >> (3 - i)) & 1) << (dci_size - pos++); - LOG_D(PHY, "dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(NR_MAC, "dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); // VRB to PRB mapping 1 bit *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 1) << (dci_size - pos++); - LOG_D(PHY, "dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(NR_MAC, "dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); // MCS 5bit //bit over 32, so dci_pdu ++ for (int i = 0; i < 5; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs >> (4 - i)) & 1) << (dci_size - pos++); - LOG_D(PHY, "dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(NR_MAC, "dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); // Redundancy version 2bit for (int i = 0; i < 2; i++) *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv >> (1 - i)) & 1) << (dci_size - pos++); - LOG_D(PHY, "dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(NR_MAC, "dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); // System information indicator 1bit *dci_pdu |= ((uint64_t)dci_pdu_rel15->system_info_indicator&1)<<(dci_size-pos++); - LOG_D(PHY, "dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); + LOG_D(NR_MAC, "dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); break; case NR_RNTI_TC: @@ -2257,20 +2268,20 @@ void nr_csirs_scheduling(int Mod_idP, csirs_pdu_rel15->row = 1; csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: csirs_pdu_rel15->row = 2; csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) | ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0)); for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: csirs_pdu_rel15->row = 4; csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); break; case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f; @@ -2281,18 +2292,18 @@ void nr_csirs_scheduling(int Mod_idP, case NR_CSI_RS_ResourceMapping__nrofPorts_p2: csirs_pdu_rel15->row = 3; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); break; case NR_CSI_RS_ResourceMapping__nrofPorts_p4: csirs_pdu_rel15->row = 5; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); break; case NR_CSI_RS_ResourceMapping__nrofPorts_p8: if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) { csirs_pdu_rel15->row = 8; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); } else{ int num_k = 0; @@ -2301,12 +2312,12 @@ void nr_csirs_scheduling(int Mod_idP, if(num_k==4) { csirs_pdu_rel15->row = 6; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); } else { csirs_pdu_rel15->row = 7; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); } } break; @@ -2314,12 +2325,12 @@ void nr_csirs_scheduling(int Mod_idP, if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) { csirs_pdu_rel15->row = 10; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); } else { csirs_pdu_rel15->row = 9; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (1 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (1 << csirs_pdu_rel15->symb_l0); } break; case NR_CSI_RS_ResourceMapping__nrofPorts_p16: @@ -2328,24 +2339,24 @@ void nr_csirs_scheduling(int Mod_idP, else csirs_pdu_rel15->row = 11; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((1 << csirs_pdu_rel15->symb_l0) | (2 << csirs_pdu_rel15->symb_l0)); break; case NR_CSI_RS_ResourceMapping__nrofPorts_p24: if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) { csirs_pdu_rel15->row = 14; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); } else{ if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) { csirs_pdu_rel15->row = 15; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0); } else { csirs_pdu_rel15->row = 13; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); } } break; @@ -2353,18 +2364,18 @@ void nr_csirs_scheduling(int Mod_idP, if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) { csirs_pdu_rel15->row = 17; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); } else{ if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) { csirs_pdu_rel15->row = 18; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= (7 << csirs_pdu_rel15->symb_l0); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (7 << csirs_pdu_rel15->symb_l0); } else { csirs_pdu_rel15->row = 16; for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++) - vrb_map[rb] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); + vrb_map[rb+csirs_pdu_rel15->bwp_start] |= ((3 << csirs_pdu_rel15->symb_l0) | (3 << csirs_pdu_rel15->symb_l1)); } } break; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f2ce8498fd..e226a2992d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -294,6 +294,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, } else AssertFatal(1==0,"Other configurations not yet implemented\n"); + return -1; } void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, @@ -520,6 +521,11 @@ void nr_csi_meas_reporting(int Mod_idP, curr_pucch->csi_bits += nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); + NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? + &sched_ctrl->active_ubwp->bwp_Common->genericParameters: + &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + // going through the list of PUCCH resources to find the one indexed by resource_id uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; const int m = pucch_Config->resourceToAddModList->list.count; @@ -550,7 +556,7 @@ void nr_csi_meas_reporting(int Mod_idP, } // verify resources are free for (int i = start; i < start + len; ++i) { - vrb_map_UL[i] |= mask; + vrb_map_UL[i+bwp_start] |= mask; } } } @@ -1390,18 +1396,32 @@ int nr_acknack_scheduling(int mod_id, pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; } + NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? + &sched_ctrl->active_ubwp->bwp_Common->genericParameters: + &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + /* verify that at that slot and symbol, resources are free. We only do this * for initialCyclicShift 0 (we assume it always has that one), so other * initialCyclicShifts can overlap with ICS 0!*/ if (pucch_Config) { const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator]; DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); + int second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0; + int nr_of_symbols = resource->format.choice.format0->nrofSymbols; if (resource->format.choice.format0->initialCyclicShift == 0) { uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; - const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex; - if ((vrb_map_UL[resource->startingPRB] & symb) != 0) - LOG_W(NR_MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot); - vrb_map_UL[resource->startingPRB] |= symb; + for (int l=0; lformat.choice.format0->startingSymbolIndex + l); + int prb; + if (l==1 && second_hop_prb != 0) + prb = second_hop_prb; + else + prb = resource->startingPRB; + if ((vrb_map_UL[bwp_start+prb] & symb) != 0) + LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot); + vrb_map_UL[bwp_start+prb] |= symb; + } } } return 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 51192b4d63..9a6fa32b5f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -34,34 +34,7 @@ #include "common/utils/nr/nr_common.h" #include - -//38.321 Table 6.1.3.1-1 -const uint32_t NR_SHORT_BSR_TABLE[32] = { - 0, 10, 14, 20, 28, 38, 53, 74, - 102, 142, 198, 276, 384, 535, 745, 1038, - 1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726, -20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000 -}; - -//38.321 Table 6.1.3.1-2 -const uint32_t NR_LONG_BSR_TABLE[256] ={ - 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, - 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71, - 75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193, - 205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526, - 560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439, - 1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934, - 4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760, - 11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431, - 31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505, - 85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209, - 234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350, - 641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644, - 1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902, - 4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006, -13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553, -35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295 -}; +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) { @@ -896,7 +869,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t * (2) there is a scheduling request * (3) or we did not schedule it in more than 10 frames */ const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes; - const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity; + const bool high_inactivity = diff >= nrmac->ulsch_max_frame_inactivity * n; LOG_D(NR_MAC, "%4d.%2d UL inactivity %d slots has_data %d SR %d\n", frame, @@ -930,7 +903,7 @@ bool allocate_ul_retransmission(module_id_t module_id, NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP:NULL; NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0; + int rbStart = 0; // wrt BWP start const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; @@ -1066,10 +1039,10 @@ void pf_ul(module_id_t module_id, LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + int rbStart = 0; // wrt BWP start NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_BWP_UplinkDedicated_t *ubwpd= cg ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0; const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; @@ -1320,6 +1293,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth: scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ? + sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth: + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, + MAX_BWP_SIZE); const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_ubwp ? sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; @@ -1333,10 +1310,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t if (RC.nrmac[module_id]->ulprbbl[i] == 1) vrb_map_UL[i]=symb; for (int i = 0; i < bwpSize; i++) { - while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize) + while ((vrb_map_UL[bwpStart + i] & symb) != 0 && i < bwpSize) i++; st = i; - while ((vrb_map_UL[i] & symb) == 0 && i < bwpSize) + while ((vrb_map_UL[bwpStart + i] & symb) == 0 && i < bwpSize) i++; if (i - st > len) { len = i - st; @@ -1659,7 +1636,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu, ss, coreset, scc, genericParameters, NULL); + nr_configure_pdcch(nr_mac, pdcch_pdu, ss, coreset, scc, genericParameters, NULL); pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d17448437d..3b275ca8a0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -31,8 +31,6 @@ #ifndef __LAYER2_NR_MAC_PROTO_H__ #define __LAYER2_NR_MAC_PROTO_H__ -#include "PHY/defs_gNB.h" - #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "NR_TAG-Id.h" @@ -250,7 +248,8 @@ void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, NR_SearchSpace_t *ss); -void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, +void nr_configure_pdcch(gNB_MAC_INST *gNB_mac, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, NR_ServingCellConfigCommon_t *scc, @@ -443,4 +442,5 @@ bool nr_find_nb_rb(uint16_t Qm, void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); +void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 117c18ae8d..6e13e4bcc6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -45,6 +45,86 @@ extern RAN_CONTEXT_t RC; +#define MACSTATSSTRLEN 16384 + +void *nrmac_stats_thread(void *arg) { + + gNB_MAC_INST *gNB = (gNB_MAC_INST *)arg; + + char output[MACSTATSSTRLEN]; + memset(output,0,MACSTATSSTRLEN); + FILE *fd=fopen("nrMAC_stats.log","w"); + AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); + + while (oai_exit == 0) { + dump_mac_stats(gNB,output,MACSTATSSTRLEN); + fprintf(fd,"%s\n",output); + fflush(fd); + usleep(200000); + fseek(fd,0,SEEK_SET); + } + fclose(fd); + return (void *)0; +} + +void clear_mac_stats(gNB_MAC_INST *gNB) { + memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); +} + +void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen) +{ + NR_UE_info_t *UE_info = &gNB->UE_info; + int num = 1; + + int stroff=0; + if (UE_info->num_UEs == 0) return; + + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + + stroff+=sprintf(output+stroff,"UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n", + UE_id, + UE_info->rnti[UE_id], + num++, + UE_info->num_UEs, + UE_info->UE_sched_ctrl[UE_id].ph, + UE_info->UE_sched_ctrl[UE_id].pcmax); + + NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; + const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; + stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, pucch0_DTX %d average RSRP %d (%d meas)\n", + UE_id, + stats->dlsch_rounds[0], stats->dlsch_rounds[1], + stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors, + stats->pucch0_DTX, + avg_rsrp, stats->num_rsrp_meas); + stats->num_rsrp_meas = 0; + stats->cumul_rsrp = 0 ; + stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); + stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", + UE_id, + stats->ulsch_rounds[0], stats->ulsch_rounds[1], + stats->ulsch_rounds[2], stats->ulsch_rounds[3], + stats->ulsch_DTX, + stats->ulsch_errors); + stroff+=sprintf(output+stroff, + "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", + UE_id, + stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); + for (int lc_id = 0; lc_id < 63; lc_id++) { + if (stats->lc_bytes_tx[lc_id] > 0) { + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + } + if (stats->lc_bytes_rx[lc_id] > 0) { + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); + } + } + } + print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL); +} + + void mac_top_init_gNB(void) { module_id_t i; @@ -90,6 +170,7 @@ void mac_top_init_gNB(void) RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0); RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0); } + pthread_create(&RC.nrmac[i]->stats_thread,NULL,nrmac_stats_thread,(void*)RC.nrmac[i]); }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) @@ -103,6 +184,7 @@ void mac_top_init_gNB(void) rrc_init_nr_global_param(); + } else { RC.nrmac = NULL; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e57e954008..699b92a831 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -145,6 +145,8 @@ typedef struct { uint8_t msg3_first_rb; /// Msg3 number of RB uint8_t msg3_nb_rb; + /// Msg3 BWP start + uint8_t msg3_bwp_start; /// Msg3 TPC command uint8_t msg3_TPC; /// Msg3 ULdelay command @@ -665,6 +667,7 @@ typedef struct gNB_MAC_INST_s { NR_TAG_t *tag; /// Pointer to IF module instance for PHY NR_IF_Module_t *if_inst; + pthread_t stats_thread; /// Pusch target SNR int pusch_target_snrx10; /// Pucch target SNR @@ -747,7 +750,7 @@ typedef struct gNB_MAC_INST_s { int *preferred_ul_tda[MAX_NUM_BWP]; /// maximum number of slots before a UE will be scheduled ULSCH automatically - uint32_t ulsch_max_slots_inactivity; + uint32_t ulsch_max_frame_inactivity; /// DL preprocessor for differentiated scheduling nr_pp_impl_dl pre_processor_dl; @@ -755,6 +758,8 @@ typedef struct gNB_MAC_INST_s { nr_pp_impl_ul pre_processor_ul; NR_UE_sched_ctrl_t *sched_ctrlCommon; + uint16_t cset0_bwp_start; + uint16_t cset0_bwp_size; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64]; bool first_MIB; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index cc44572abd..05e77a935d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -603,7 +603,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) //int optval; int bytes_received; sidelink_pc5s_element *sl_pc5s_msg_send = NULL; - pc5s_header_t *pc5s_header = NULL; + pc5s_header_t *pc5s_header = NULL; rb_id_t rab_id = 0; //TTN for D2D (PC5S) // receive a message from ProSe App @@ -704,6 +704,12 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) pc5s_header->rb_id, rab_id, pc5s_header->data_size); + /* pointers to pc5s_header fields possibly not aligned because pc5s_header points to a packed structure + * Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and + * gcc, from v9, now warns about it. fix these warnings by using local variables + */ + uint32_t sourceL2Id = pc5s_header->sourceL2Id; + uint32_t destinationL2Id = pc5s_header->destinationL2Id; pdcp_data_req( &ctxt, SRB_FLAG_NO, @@ -713,9 +719,11 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA, - &pc5s_header->sourceL2Id, - &pc5s_header->destinationL2Id + &sourceL2Id, + &destinationL2Id ); + pc5s_header->sourceL2Id = sourceL2Id; + pc5s_header->destinationL2Id=destinationL2Id; } else { /* else of h_rc == HASH_TABLE_OK */ MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, @@ -759,6 +767,12 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) pc5s_header->rb_id, DEFAULT_RAB_ID, pc5s_header->data_size); + /* pointers to pc5s_header fields possibly not aligned because pc5s_header points to a packed structure + * Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and + * gcc, from v9, now warns about it. fix these warnings by using local variables + */ + uint32_t sourceL2Id = pc5s_header->sourceL2Id; + uint32_t destinationL2Id = pc5s_header->destinationL2Id; pdcp_data_req ( &ctxt, SRB_FLAG_NO, @@ -768,9 +782,11 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA, - &pc5s_header->sourceL2Id, - &pc5s_header->destinationL2Id + &sourceL2Id, + &destinationL2Id ); + pc5s_header->sourceL2Id = sourceL2Id; + pc5s_header->destinationL2Id=destinationL2Id; } } /* end of !ctxt.enb_flag */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index f9076c50ae..bf9435346f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -36,6 +36,7 @@ #include "pdcp.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include +#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h" #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -447,10 +448,18 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){ LOG_D(PDCP, "IP packet received, to be sent to TUN interface"); - len = write(nas_sock_fd[0], buf, size); + + if(entity->has_sdapDLheader){ + size -= SDAP_HDR_LENGTH; + len = write(nas_sock_fd[0], &buf[SDAP_HDR_LENGTH], size); + } else { + len = write(nas_sock_fd[0], buf, size); + } + if (len != size) { LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); } + } else{ for (i = 0; i < 5; i++) { @@ -480,7 +489,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; GTPV1U_GNB_TUNNEL_DATA_REQ(message_p).pdusession_id = entity->pdusession_id; - if (offset==1) LOG_D(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]); + if (offset==1) { + LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]); + sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header + } LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset); itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p); } @@ -828,10 +840,6 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, has_sdap = 1; has_sdapULheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present ? 1 : 0; has_sdapDLheader = s->cnAssociation->choice.sdap_Config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present ? 1 : 0; - if (has_sdapDLheader==1) { - LOG_E(PDCP,"%s:%d:%s: fatal, no support for SDAP DL yet\n",__FILE__,__LINE__,__FUNCTION__); - exit(-1); - } } /* TODO(?): accept different UL and DL SN sizes? */ if (sn_size_ul != sn_size_dl) { @@ -903,9 +911,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( uint8_t *const kRRCint, uint8_t *const kUPenc, uint8_t *const kUPint -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 -#endif ,rb_id_t *const defaultDRB, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) //struct NR_RLC_Config *rlc_Config) @@ -975,9 +981,7 @@ boolean_t rrc_pdcp_config_asn1_req( uint8_t *const kRRCenc, uint8_t *const kRRCint, uint8_t *const kUPenc -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 -#endif ,rb_id_t *const defaultDRB) { return 0; @@ -1240,10 +1244,8 @@ boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_size, unsigned char *const sdu_buffer, const pdcp_transmission_mode_t mode -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t *const sourceL2Id ,const uint32_t *const destinationL2Id -#endif ) { if (srb_flagP) { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 8bf65835dc..046696d12f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -270,7 +270,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( + buf_stat.retx_size + buf_stat.tx_size; } else { - if (!(frameP%128)) //to supress this warning message + if (!(frameP%128)) //to suppress this warning message LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); ret.bytes_in_buffer = 0; } @@ -334,6 +334,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( + buf_stat.retx_size + buf_stat.tx_size; } else { + if (!(frameP%128)) //to suppress this warning message + LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); ret = 0; } @@ -953,16 +955,16 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt if ((drb2add_listP != NULL) && (rlc_bearer2add_list != NULL)) { for (i = 0; i < drb2add_listP->list.count; i++) { if (rlc_bearer2add_list != NULL) { - for(j = 0; j < rlc_bearer2add_list->list.count; j++){ - if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){ - if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){ - if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){ - add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]); + for(j = 0; j < rlc_bearer2add_list->list.count; j++){ + if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){ + if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){ + if(drb2add_listP->list.array[i]->drb_Identity == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){ + add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[j]); + } } - } + } } } - } } } diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index b2230df623..30fb20b727 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -2969,6 +2969,12 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize = siWindowLength_int[sib1->si_WindowLength]; LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); + /* pointers to SIperiod inthe Info struct points to a packed structure + * Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and + * gcc, from v9, now warns about it. fix these warnings by removing the indirection on data + * Not sure if SiPeriod can be modified, reassign after function call for security + */ + uint16_t Aligned_SIperiod = UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod; rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, @@ -2981,7 +2987,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, (LTE_MobilityControlInfo_t *) NULL, &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, - &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, + &Aligned_SIperiod, NULL, NULL, NULL, @@ -2995,6 +3001,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL, (LTE_MBSFN_AreaInfoList_r9_t *)NULL ); + UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod=Aligned_SIperiod; LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 1; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 1c02c3de46..f5b1db8b8c 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -364,7 +364,7 @@ typedef struct UE_RRC_INFO_s { uint8_t SIwindowsize_MBMS; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 uint8_t handoverTarget; HO_STATE_t ho_state; - uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 + uint16_t SIperiod ; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 uint16_t SIperiod_MBMS; //!< Corresponds to the SIB1-MBMS si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 TODO unsigned short UE_index; uint32_t T300_active; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index a03fb51749..2fcafec778 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3618,9 +3618,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t NULL, NULL, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL -#endif , NULL); /* Refresh SRBs/DRBs */ @@ -3629,11 +3627,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *SRB_configList2, // NULL, *DRB_configList, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0 -#endif ); } @@ -6331,9 +6327,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct NULL, NULL, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL -#endif , NULL); /* Refresh SRBs/DRBs */ @@ -6342,11 +6336,9 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct *SRB_configList2, // NULL, *DRB_configList, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0 -#endif ); } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index eb6f86fda6..c619f6181f 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1182,9 +1182,9 @@ void fill_initial_SpCellConfig(rnti_t rnti, AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, "SCS != 30kHz\n"); AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5, - "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8+(10*((rnti>>1)&3)) + (rnti&1); + "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); + + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8 + 10*((rnti>>1)&3) + (rnti&1); schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); *schedulingRequestResourceConfig->resource = 0; ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 655e6973a1..95852c8ccb 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -106,9 +106,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( uint8_t *const kRRCint, uint8_t *const kUPenc, uint8_t *const kUPint - #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - #endif ,rb_id_t *const defaultDRB, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); @@ -1010,7 +1008,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; - sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; + sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present; sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; sdap_config->defaultDRB = TRUE; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); @@ -1043,7 +1041,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( DRB_config->pdcp_Config->moreThanOneRLC = NULL; DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering)); - *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms750; + *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; DRB_config->pdcp_Config->ext1 = NULL; if (rrc->security.do_drb_integrity) { @@ -1305,51 +1303,22 @@ rrc_gNB_process_RRCReconfigurationComplete( ue_context_pP->ue_context.ue_reestablishment_timer = 0; -#ifndef PHYSIM - uint8_t *k_kdf = NULL; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - k_kdf = NULL; nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ - kUPenc = malloc(16); - if (kUPenc == NULL) exit(1); - memcpy(kUPenc, k_kdf+16, 16); - free(k_kdf); - - k_kdf = NULL; + &kUPenc); nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kUPint: last 128 bits of key derivation function which returns 256 bits */ - kUPint = malloc(16); - if (kUPint == NULL) exit(1); - memcpy(kUPint, k_kdf+16, 16); - free(k_kdf); + &kUPint); } - k_kdf = NULL; nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kRRCenc: last 128 bits of key derivation function which returns 256 bits */ - kRRCenc = malloc(16); - if (kRRCenc == NULL) exit(1); - memcpy(kRRCenc, k_kdf+16, 16); - free(k_kdf); - - k_kdf = NULL; + &kRRCenc); nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kRRCint: last 128 bits of key derivation function which returns 256 bits */ - kRRCint = malloc(16); - if (kRRCint == NULL) exit(1); - memcpy(kRRCint, k_kdf+16, 16); - free(k_kdf); -#endif + &kRRCint); /* Refresh SRBs/DRBs */ MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", MSC_AS_TIME_ARGS(ctxt_pP), diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 714db9da30..60ee99a172 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -308,43 +308,19 @@ nr_rrc_pdcp_config_security( uint8_t *kUPenc = NULL; static int print_keys= 1; -#ifndef PHYSIM - - uint8_t *k_kdf = NULL; - /* Derive the keys from kgnb */ if (SRB_configList != NULL) { - k_kdf = NULL; nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ - kUPenc = malloc(16); - if (kUPenc == NULL) exit(1); - memcpy(kUPenc, k_kdf+16, 16); - free(k_kdf); + &kUPenc); } - k_kdf = NULL; nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kRRCenc: last 128 bits of key derivation function which returns 256 bits */ - kRRCenc = malloc(16); - if (kRRCenc == NULL) exit(1); - memcpy(kRRCenc, k_kdf+16, 16); - free(k_kdf); - - k_kdf = NULL; + &kRRCenc); nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kgnb, - &k_kdf); - /* kRRCint: last 128 bits of key derivation function which returns 256 bits */ - kRRCint = malloc(16); - if (kRRCint == NULL) exit(1); - memcpy(kRRCint, k_kdf+16, 16); - free(k_kdf); -#endif + &kRRCint); if (!IS_SOFTMODEM_IQPLAYER) { SET_LOG_DUMP(DEBUG_SECURITY) ; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 52f451d7bb..f9fce48f41 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -52,9 +52,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( uint8_t *const kRRCint, uint8_t *const kUPenc, uint8_t *const kUPint - #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - #endif ,rb_id_t *const defaultDRB, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); @@ -215,25 +213,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); /* derive UP security key */ - unsigned char *kUPenc_kdf; nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, ue_context_p->ue_context.kgnb, - &kUPenc_kdf); - /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ - kUPenc = malloc(16); - if (kUPenc == NULL) exit(1); - memcpy(kUPenc, kUPenc_kdf+16, 16); - free(kUPenc_kdf); - - unsigned char *kUPint_kdf; + &kUPenc); nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm, ue_context_p->ue_context.kgnb, - &kUPint_kdf); - /* kUPint: last 128 bits of key derivation function which returns 256 bits */ - kUPint = malloc(16); - if (kUPint == NULL) exit(1); - memcpy(kUPint, kUPint_kdf+16, 16); - free(kUPint_kdf); + &kUPint); e_NR_CipheringAlgorithm cipher_algo; switch (ue_context_p->ue_context.ciphering_algorithm) { diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 7c664d292d..61f757ed53 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -187,9 +187,7 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( uint8_t *const kRRCint, uint8_t *const kUPenc, uint8_t *const kUPint - #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - #endif ,rb_id_t *const defaultDRB, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); @@ -1661,45 +1659,40 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB uint8_t *kRRCenc = NULL; uint8_t *kUPenc = NULL; uint8_t *kRRCint = NULL; - pdcp_t *pdcp_p = NULL; - hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; - hashtable_rc_t h_rc; - key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); - h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p); + nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + &kUPenc); + nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + &kRRCenc); + nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + &kRRCint); + LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x\n", + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]); - if (h_rc == HASH_TABLE_OK) { - LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key); - LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x" - "%02x%02x%02x%02x\n", - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27], - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]); - derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); - derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); - derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); - - if (securityMode != 0xff) { - pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, - NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm - | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), - kRRCenc, kRRCint, kUPenc); - } else { - LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); - } + if (securityMode != 0xff) { + pdcp_config_set_security(ctxt_pP, NULL, DCCH, DCCH+2, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm + | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + kRRCenc, kRRCint, kUPenc); } else { - LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key); + LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode); } if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) { @@ -2044,21 +2037,12 @@ nr_rrc_ue_establish_srb2( } } - uint8_t *k_kdf = NULL; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); - kRRCenc = malloc(16); - if (kRRCenc == NULL) exit(1); - memcpy(kRRCenc, k_kdf + 16, 16); - free(k_kdf); + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); - kRRCint = malloc(16); - if (kRRCint == NULL) exit(1); - memcpy(kRRCint, k_kdf + 16, 16); - free(k_kdf); + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); // Refresh SRBs nr_rrc_pdcp_config_asn1_req(ctxt_pP, @@ -2100,6 +2084,7 @@ nr_rrc_ue_establish_srb2( LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig // rrc_mac_config_req_ue } } else { @@ -2115,6 +2100,7 @@ nr_rrc_ue_establish_srb2( LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig // rrc_mac_config_req_ue } } // srb2 @@ -2135,28 +2121,33 @@ nr_rrc_ue_establish_srb2( memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); } else { - LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); + //LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; + int j; + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList; + if (rlc_bearer2add_list != NULL) { + for(j = 0; j < rlc_bearer2add_list->list.count; j++){ + if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){ + if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){ + if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){ + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id); + nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig + } + } + } + } + } } } - uint8_t *k_kdf = NULL; uint8_t *kUPenc = NULL; uint8_t *kUPint = NULL; nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); - kUPenc = malloc(16); - if (kUPenc == NULL) exit(1); - memcpy(kUPenc, k_kdf + 16, 16); - free(k_kdf); - + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf); - kUPint = malloc(16); - if (kUPint == NULL) exit(1); - memcpy(kUPint, k_kdf + 16, 16); - free(k_kdf); + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPint); MSC_LOG_TX_MESSAGE( MSC_RRC_UE, @@ -2199,6 +2190,15 @@ nr_rrc_ue_establish_srb2( } } + if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) { + for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) { + NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i]; + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id); + nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig + } + } + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED; LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); } @@ -2511,6 +2511,28 @@ nr_rrc_ue_establish_srb2( NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); break; + case NAS_KENB_REFRESH_REQ: + memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb)); + LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = " + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x\n", + ue_mod_id, ITTI_MSG_NAME (msg_p), + NR_UE_rrc_inst[ue_mod_id].kgnb[0], NR_UE_rrc_inst[ue_mod_id].kgnb[1], NR_UE_rrc_inst[ue_mod_id].kgnb[2], NR_UE_rrc_inst[ue_mod_id].kgnb[3], + NR_UE_rrc_inst[ue_mod_id].kgnb[4], NR_UE_rrc_inst[ue_mod_id].kgnb[5], NR_UE_rrc_inst[ue_mod_id].kgnb[6], NR_UE_rrc_inst[ue_mod_id].kgnb[7], + NR_UE_rrc_inst[ue_mod_id].kgnb[8], NR_UE_rrc_inst[ue_mod_id].kgnb[9], NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11], + NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15], + NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19], + NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23], + NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27], + NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]); + break; + case NAS_UPLINK_DATA_REQ: { uint32_t length; uint8_t *buffer; diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.c b/openair2/SDAP/nr_sdap/nr_sdap_gnb.c new file mode 100644 index 0000000000..5f0a2640e9 --- /dev/null +++ b/openair2/SDAP/nr_sdap/nr_sdap_gnb.c @@ -0,0 +1,87 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_sdap_gnb.h" +#include + +boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id + ) { + if(sdu_buffer == NULL) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if(sdu_buffer_size == 0) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - NULL or 0 sdu_buffer_size \n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + uint8_t *sdap_buf = (uint8_t *)malloc(sdu_buffer_size+SDAP_HDR_LENGTH); + nr_sdap_dl_hdr_t sdap_hdr; + sdap_hdr.RDI = 0; // SDAP_Hardcoded - + sdap_hdr.RQI = 0; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION + sdap_hdr.QFI = 1; // SDAP_Hardcoded - Should get this info from DL_PDU_SESSION_INFORMATION + memcpy(&sdap_buf[0], &sdap_hdr, 1); + memcpy(&sdap_buf[1], sdu_buffer, sdu_buffer_size); + rb_id_t sdap_drb_id = rb_id; // SDAP_Hardcoded - Should get this info from QFI to DRB mapping table + boolean_t ret = pdcp_data_req(ctxt_p, + srb_flag, + sdap_drb_id, + mui, + confirm, + sdu_buffer_size+1, + sdap_buf, + pt_mode, + sourceL2Id, + destinationL2Id); + + if(!ret) { + LOG_E(PDCP, "%s:%d:%s: SDAP Layer gNB - PDCP DL refused PDU\n", __FILE__, __LINE__, __FUNCTION__); + free(sdap_buf); + return 0; + } + + free(sdap_buf); + return 1; +} + +void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr) { + nr_sdap_ul_hdr_t *sdap_hdr_ul = (nr_sdap_ul_hdr_t *)&sdap_gnb_ul_hdr; + + switch (sdap_hdr_ul->DC) { + case SDAP_HDR_UL_DATA_PDU: + LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - UL Received SDAP Data PDU\n", __FILE__, __LINE__, __FUNCTION__); + break; + + case SDAP_HDR_UL_CTRL_PDU: + LOG_I(PDCP, "%s:%d:%s: SDAP Layer gNB - Received SDAP Control PDU\n", __FILE__, __LINE__, __FUNCTION__); + break; + } +} \ No newline at end of file diff --git a/openair2/SDAP/nr_sdap/nr_sdap_gnb.h b/openair2/SDAP/nr_sdap/nr_sdap_gnb.h new file mode 100644 index 0000000000..243aa89010 --- /dev/null +++ b/openair2/SDAP/nr_sdap/nr_sdap_gnb.h @@ -0,0 +1,61 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_SDAP_GNB_ +#define _NR_SDAP_GNB_ + +#include "openair2/COMMON/platform_types.h" +#include "common/utils/LOG/log.h" + +#define SDAP_BITMASK_DC (0x80) +#define SDAP_BITMASK_R (0x40) +#define SDAP_BITMASK_QFI (0x3F) +#define SDAP_HDR_UL_DATA_PDU (1) +#define SDAP_HDR_UL_CTRL_PDU (0) +#define SDAP_HDR_LENGTH (1) + +typedef struct nr_sdap_dl_hdr_s { + uint8_t QFI:6; + uint8_t RQI:1; + uint8_t RDI:1; +} __attribute__((packed)) nr_sdap_dl_hdr_t; + +typedef struct nr_sdap_ul_hdr_s { + uint8_t QFI:6; + uint8_t R:1; + uint8_t DC:1; +} __attribute__((packed)) nr_sdap_ul_hdr_t; + +boolean_t sdap_gnb_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id + ); + +void sdap_gnb_ul_header_handler(char sdap_gnb_ul_hdr); + +#endif \ No newline at end of file diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 159ee7f159..c02b999490 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -121,6 +121,8 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, string[6] = 0x01; kdf(string, 7, key, 32, out, 32); + // in NR, we use the last 16 bytes, ignoring the first 16 ones + memcpy(*out, *out+16, 16); return 0; } diff --git a/openair3/NAS/COMMON/API/NETWORK/as_message.c b/openair3/NAS/COMMON/API/NETWORK/as_message.c index fd3f15cb4c..4a2da21594 100644 --- a/openair3/NAS/COMMON/API/NETWORK/as_message.c +++ b/openair3/NAS/COMMON/API/NETWORK/as_message.c @@ -81,7 +81,12 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length) LOG_FUNC_IN; int bytes; - Byte_t** data = NULL; + /* pointers to msg fields possibly not aligned because msg points to a packed structure + * Using these possibly unaligned pointers in a function call may trigger alignment errors at run time and + * gcc, from v9, now warns about it. fix these warnings by removing the indirection on data + * (in fact i don't understand this code data seems to be useless...) + */ + Byte_t *data = NULL; /* Get the message type */ msg->msgID = *(uint16_t*)(buffer); @@ -91,49 +96,49 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length) case AS_NAS_ESTABLISH_REQ: /* NAS signalling connection establish request */ bytes += sizeof(nas_establish_req_t) - sizeof(Byte_t*); - data = &msg->msg.nas_establish_req.initialNasMsg.data; + data = msg->msg.nas_establish_req.initialNasMsg.data; break; case AS_NAS_ESTABLISH_IND: /* NAS signalling connection establishment indication */ bytes += sizeof(nas_establish_ind_t) - sizeof(Byte_t*); - data = &msg->msg.nas_establish_ind.initialNasMsg.data; + data = msg->msg.nas_establish_ind.initialNasMsg.data; break; case AS_NAS_ESTABLISH_RSP: /* NAS signalling connection establishment response */ bytes += sizeof(nas_establish_rsp_t) - sizeof(Byte_t*); - data = &msg->msg.nas_establish_rsp.nasMsg.data; + data = msg->msg.nas_establish_rsp.nasMsg.data; break; case AS_NAS_ESTABLISH_CNF: /* NAS signalling connection establishment confirm */ bytes += sizeof(nas_establish_cnf_t) - sizeof(Byte_t*); - data = &msg->msg.nas_establish_cnf.nasMsg.data; + data = msg->msg.nas_establish_cnf.nasMsg.data; break; case AS_UL_INFO_TRANSFER_REQ: /* Uplink L3 data transfer request */ bytes += sizeof(ul_info_transfer_req_t) - sizeof(Byte_t*); - data = &msg->msg.ul_info_transfer_req.nasMsg.data; + data = msg->msg.ul_info_transfer_req.nasMsg.data; break; case AS_UL_INFO_TRANSFER_IND: /* Uplink L3 data transfer indication */ bytes += sizeof(ul_info_transfer_ind_t) - sizeof(Byte_t*); - data = &msg->msg.ul_info_transfer_ind.nasMsg.data; + data = msg->msg.ul_info_transfer_ind.nasMsg.data; break; case AS_DL_INFO_TRANSFER_REQ: /* Downlink L3 data transfer request */ bytes += sizeof(dl_info_transfer_req_t) - sizeof(Byte_t*); - data = &msg->msg.dl_info_transfer_req.nasMsg.data; + data = msg->msg.dl_info_transfer_req.nasMsg.data; break; case AS_DL_INFO_TRANSFER_IND: /* Downlink L3 data transfer indication */ bytes += sizeof(dl_info_transfer_ind_t) - sizeof(Byte_t*); - data = &msg->msg.dl_info_transfer_ind.nasMsg.data; + data = msg->msg.dl_info_transfer_ind.nasMsg.data; break; case AS_BROADCAST_INFO_IND: @@ -166,7 +171,8 @@ int as_message_decode(const char* buffer, as_message_t* msg, int length) if (bytes > 0) { if (data) { /* Set the pointer to dedicated NAS information */ - *data = (Byte_t*)(buffer + bytes); + /* wasn't data already computed above for specific cases here we override ?? */ + data = (Byte_t *)buffer + bytes; } /* Decode the message */ @@ -201,8 +207,10 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) LOG_FUNC_IN; int bytes = sizeof(msg->msgID); - as_nas_info_t* nas_msg = NULL; - + as_nas_info_t nas_msg; + Byte_t *dataptr=NULL; + uint32_t len=0; + switch (msg->msgID) { case AS_BROADCAST_INFO_IND: /* Broadcast information */ @@ -237,25 +245,30 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) case AS_NAS_ESTABLISH_REQ: /* NAS signalling connection establish request */ bytes += sizeof(nas_establish_req_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.nas_establish_req.initialNasMsg; + nas_msg = msg->msg.nas_establish_req.initialNasMsg; break; case AS_NAS_ESTABLISH_IND: /* NAS signalling connection establish indication */ bytes += sizeof(nas_establish_ind_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.nas_establish_ind.initialNasMsg; + nas_msg = msg->msg.nas_establish_ind.initialNasMsg; + dataptr=(Byte_t *)&(msg->msg.nas_establish_ind.initialNasMsg.data); + len=msg->msg.nas_establish_ind.initialNasMsg.length; break; case AS_NAS_ESTABLISH_RSP: /* NAS signalling connection establish response */ bytes += sizeof(nas_establish_rsp_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.nas_establish_rsp.nasMsg; + nas_msg = msg->msg.nas_establish_rsp.nasMsg; + break; case AS_NAS_ESTABLISH_CNF: /* NAS signalling connection establish confirm */ bytes += sizeof(nas_establish_cnf_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.nas_establish_cnf.nasMsg; + nas_msg = msg->msg.nas_establish_cnf.nasMsg; + dataptr=(Byte_t *)&(msg->msg.nas_establish_cnf.nasMsg.data); + len=msg->msg.nas_establish_ind.initialNasMsg.length; break; case AS_NAS_RELEASE_REQ: @@ -271,7 +284,7 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) case AS_UL_INFO_TRANSFER_REQ: /* Uplink L3 data transfer request */ bytes += sizeof(ul_info_transfer_req_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.ul_info_transfer_req.nasMsg; + nas_msg = msg->msg.ul_info_transfer_req.nasMsg; break; case AS_UL_INFO_TRANSFER_CNF: @@ -282,13 +295,13 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) case AS_UL_INFO_TRANSFER_IND: /* Uplink L3 data transfer indication */ bytes += sizeof(ul_info_transfer_ind_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.ul_info_transfer_ind.nasMsg; + nas_msg = msg->msg.ul_info_transfer_ind.nasMsg; break; case AS_DL_INFO_TRANSFER_REQ: /* Downlink L3 data transfer */ bytes += sizeof(dl_info_transfer_req_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.dl_info_transfer_req.nasMsg; + nas_msg = msg->msg.dl_info_transfer_req.nasMsg; break; case AS_DL_INFO_TRANSFER_CNF: @@ -299,7 +312,8 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) case AS_DL_INFO_TRANSFER_IND: /* Downlink L3 data transfer indication */ bytes += sizeof(dl_info_transfer_ind_t) - sizeof(Byte_t*); - nas_msg = &msg->msg.dl_info_transfer_ind.nasMsg; + nas_msg = msg->msg.dl_info_transfer_ind.nasMsg; + break; case AS_RAB_ESTABLISH_REQ: @@ -343,14 +357,14 @@ int as_message_encode(char* buffer, as_message_t* msg, int length) /* Encode the AS message */ memcpy(buffer, (unsigned char*)msg, bytes); - if ( nas_msg && (nas_msg->length > 0) ) { + if ( (dataptr!=NULL) && (len > 0) ) { /* Copy the NAS message */ - memcpy(buffer + bytes, nas_msg->data, nas_msg->length); - bytes += nas_msg->length; + memcpy(buffer + bytes, nas_msg.data, nas_msg.length); + bytes += len; /* Release NAS message memory */ - free(nas_msg->data); - nas_msg->length = 0; - nas_msg->data = NULL; + free(nas_msg.data); + len=0; + dataptr = NULL; } LOG_FUNC_RETURN (bytes); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 77931cbb19..ad2f2c7c3c 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -47,6 +47,8 @@ uint8_t *registration_request_buf; uint32_t registration_request_len; extern char *baseNetAddress; +extern uint16_t NB_UE_INST; +static ue_sa_security_key_t ** ue_security_key; static int nas_protected_security_header_encode( char *buffer, @@ -251,6 +253,108 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t knas_int[i] = out[16 + i]; } +void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ + /* Compute the KDF input parameter + * S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01 + */ + uint8_t input[32]; + // uint16_t length = 4; + // int offset = 0; + uint8_t out[32] = { 0 }; + + LOG_TRACE(INFO, "%s with count= %d", __FUNCTION__, count); + memset(input, 0, 32); + input[0] = 0x6E; + // P0 + input[1] = count >> 24; + input[2] = (uint8_t)(count >> 16); + input[3] = (uint8_t)(count >> 8); + input[4] = (uint8_t)count; + // L0 + input[5] = 0; + input[6] = 4; + // P1 + input[7] = 0x01; + // L1 + input[8] = 0; + input[9] = 1; + + kdf(kamf, 32, input, 10, out, 32); + for (int i = 0; i < 32; i++) + kgnb[i] = out[i]; + printf("kgnb : "); + for(int pp=0;pp<32;pp++) + printf("%02x ",kgnb[pp]); + printf("\n"); +} + +void derive_ue_keys(int Mod_id, uint8_t *buf, uicc_t *uicc) { + uint8_t ak[6]; + uint8_t sqn[6]; + + AssertFatal (Mod_id < NB_UE_INST, "Failed, Mod_id %d is over NB_UE_INST!\n", Mod_id); + if(ue_security_key[Mod_id]){ + // clear old key + memset(ue_security_key[Mod_id],0,sizeof(ue_sa_security_key_t)); + }else{ + // Allocate new memory + ue_security_key[Mod_id]=(ue_sa_security_key_t *)calloc(1,sizeof(ue_sa_security_key_t)); + } + uint8_t *kausf = ue_security_key[Mod_id]->kausf; + uint8_t *kseaf = ue_security_key[Mod_id]->kseaf; + uint8_t *kamf = ue_security_key[Mod_id]->kamf; + uint8_t *knas_int = ue_security_key[Mod_id]->knas_int; + uint8_t *output = ue_security_key[Mod_id]->res; + uint8_t *rand = ue_security_key[Mod_id]->rand; + uint8_t *kgnb = ue_security_key[Mod_id]->kgnb; + + // get RAND for authentication request + for(int index = 0; index < 16;index++){ + rand[index] = buf[8+index]; + } + + uint8_t resTemp[16]; + uint8_t ck[16], ik[16]; + f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc); + + transferRES(ck, ik, resTemp, rand, output, uicc); + + for(int index = 0; index < 6; index++){ + sqn[index] = buf[26+index]; + } + + derive_kausf(ck, ik, sqn, kausf, uicc); + derive_kseaf(kausf, kseaf, uicc); + derive_kamf(kseaf, kamf, 0x0000, uicc); + derive_knas(0x02, 2, kamf, knas_int); + derive_kgnb(kamf,0,kgnb); + + printf("kausf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kausf[i]); + } + printf("\n"); + + printf("kseaf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kseaf[i]); + } + + printf("\n"); + + printf("kamf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kamf[i]); + } + printf("\n"); + + printf("knas_int:\n"); + for(int i = 0; i < 16; i++){ + printf("%x ", knas_int[i]); + } + printf("\n"); +} + void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) { int size = sizeof(mm_msg_header_t); fgs_nas_message_t nas_msg={0}; @@ -373,69 +477,13 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype } -OctetString knas_int; -static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){ +static void generateAuthenticationResp(int Mod_id,as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){ - uint8_t ak[6]; - - uint8_t kausf[32]; - uint8_t sqn[6]; - uint8_t kseaf[32]; - uint8_t kamf[32]; + derive_ue_keys(Mod_id,buf,uicc); OctetString res; - - // get RAND for authentication request - unsigned char rand[16]; - for(int index = 0; index < 16;index++){ - rand[index] = buf[8+index]; - } - - uint8_t resTemp[16]; - uint8_t ck[16], ik[16], output[16]; - f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc); - - transferRES(ck, ik, resTemp, rand, output, uicc); - - // get knas_int - knas_int.length = 16; - knas_int.value = malloc(knas_int.length); - for(int index = 0; index < 6; index++){ - sqn[index] = buf[26+index]; - } - - derive_kausf(ck, ik, sqn, kausf, uicc); - derive_kseaf(kausf, kseaf, uicc); - derive_kamf(kseaf, kamf, 0x0000, uicc); - derive_knas(0x02, 2, kamf, knas_int.value); - - printf("kausf:"); - for(int i = 0; i < 32; i++){ - printf("%x ", kausf[i]); - } - printf("\n"); - - printf("kseaf:"); - for(int i = 0; i < 32; i++){ - printf("%x ", kseaf[i]); - } - - printf("\n"); - - printf("kamf:"); - for(int i = 0; i < 32; i++){ - printf("%x ", kamf[i]); - } - printf("\n"); - - printf("knas_int:\n"); - for(int i = 0; i < 16; i++){ - printf("%x ", knas_int.value[i]); - } - printf("\n"); - - // set res res.length = 16; - res.value = output; + res.value = calloc(1,16); + memcpy(res.value,ue_security_key[Mod_id]->res,16); int size = sizeof(mm_msg_header_t); fgs_nas_message_t nas_msg; @@ -465,7 +513,14 @@ static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *bu initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); } -static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) +int nas_itti_kgnb_refresh_req(const uint8_t kgnb[32], int instance) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_KENB_REFRESH_REQ); + memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kgnb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb)); + return itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p); +} + +static void generateSecurityModeComplete(int Mod_id,as_nas_info_t *initialNasMsg) { int size = sizeof(mm_msg_header_t); fgs_nas_message_t nas_msg; @@ -512,7 +567,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); - stream_cipher.key = knas_int.value; + stream_cipher.key = ue_security_key[Mod_id]->knas_int; stream_cipher.key_length = 16; stream_cipher.count = 0; stream_cipher.bearer = 1; @@ -532,7 +587,7 @@ static void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) } } -static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) { +static void generateRegistrationComplete(int Mod_id, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) { //wait send RRCReconfigurationComplete and InitialContextSetupResponse sleep(1); int length = 0; @@ -592,7 +647,7 @@ static void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransp } initialNasMsg->length = length; - stream_cipher.key = knas_int.value; + stream_cipher.key = ue_security_key[Mod_id]->knas_int; stream_cipher.key_length = 16; stream_cipher.count = 1; stream_cipher.bearer = 1; @@ -625,7 +680,7 @@ void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buff } } -static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *initialNasMsg){ +static void generatePduSessionEstablishRequest(int Mod_id, uicc_t * uicc, as_nas_info_t *initialNasMsg){ //wait send RegistrationComplete usleep(100*150); int size = 0; @@ -699,7 +754,7 @@ static void generatePduSessionEstablishRequest(uicc_t * uicc, as_nas_info_t *ini initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); - stream_cipher.key = knas_int.value; + stream_cipher.key = ue_security_key[Mod_id]->knas_int; stream_cipher.key_length = 16; stream_cipher.count = 0; stream_cipher.bearer = 1; @@ -729,6 +784,8 @@ void *nas_nrue_task(void *args_p) uint8_t msg_type = 0; uint8_t *pdu_buffer = NULL; + + ue_security_key=(ue_sa_security_key_t **)calloc(1,sizeof(ue_sa_security_key_t*)*NB_UE_INST); itti_mark_task_ready (TASK_NAS_NRUE); MSC_START_USE(); @@ -813,7 +870,7 @@ void *nas_nrue_task(void *args_p) as_nas_info_t initialNasMsg; memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); - generateRegistrationComplete(&initialNasMsg, NULL); + generateRegistrationComplete(Mod_id,&initialNasMsg, NULL); if(initialNasMsg.length > 0){ MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); @@ -826,7 +883,7 @@ void *nas_nrue_task(void *args_p) as_nas_info_t pduEstablishMsg; memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); - generatePduSessionEstablishRequest(uicc, &pduEstablishMsg); + generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg); if(pduEstablishMsg.length > 0){ MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ); @@ -893,10 +950,11 @@ void *nas_nrue_task(void *args_p) generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc); break; case FGS_AUTHENTICATION_REQUEST: - generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc); + generateAuthenticationResp(Mod_id,&initialNasMsg, pdu_buffer, uicc); break; case FGS_SECURITY_MODE_COMMAND: - generateSecurityModeComplete(&initialNasMsg); + nas_itti_kgnb_refresh_req(ue_security_key[Mod_id]->kgnb, instance); + generateSecurityModeComplete(Mod_id,&initialNasMsg); break; case FGS_DOWNLINK_NAS_TRANSPORT: decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 753ebf1762..1b59366037 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -64,6 +64,16 @@ #define INITIAL_REGISTRATION 0b001 +/* Security Key for SA UE */ +typedef struct { + uint8_t kausf[32]; + uint8_t kseaf[32]; + uint8_t kamf[32]; + uint8_t knas_int[16]; + uint8_t res[16]; + uint8_t rand[16]; + uint8_t kgnb[32]; +} ue_sa_security_key_t; typedef enum fgs_protocol_discriminator_e { /* Protocol discriminator identifier for 5GS Mobility Management */ diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 10b118eac0..6b226be380 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -136,17 +136,25 @@ static int _emm_as_encrypt( static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg); -static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *, - ul_info_transfer_req_t *); -static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *, - nas_establish_req_t *); + + static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *); - -static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *); -static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, ul_info_transfer_req_t *); -static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); +/* prototyping of the following function modified: the last parameter turned to a void pointer + * instead of a ponter to the union field of the as_msg packed structure. This is to avoid new warnings introduced + * from gcc V9 which warns when accessing fields in a packed structure which may result in an alignment problem + * at run time. Modifications allow gcc to know at compile time that it cannot assume any alignment for those pointers. + * On X86 this is not fatal, as at run time the problem can be fixed (but it's better for perf to avoid). On other + * processor as Arm i think it can end in seg fault + */ +static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *, + void *ul_info_transfer_req_unaligned); +static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *, + void *nas_establish_req_unaligned); +static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, void *ul_info_transfer_req_unaligned); +static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, void *ul_info_transfer_req_unaligned); +static int _emm_as_release_req(const emm_as_release_t *, void *nas_release_req_unaligned); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -938,32 +946,32 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) case _EMMAS_DATA_REQ: as_msg.msgID = _emm_as_data_req(user->emm_data, &msg->u.data, - &as_msg.msg.ul_info_transfer_req); + (void *)(&as_msg.msg.ul_info_transfer_req)); break; case _EMMAS_STATUS_IND: as_msg.msgID = _emm_as_status_ind(user->emm_data, &msg->u.status, - &as_msg.msg.ul_info_transfer_req); + (void *)(&as_msg.msg.ul_info_transfer_req)); break; case _EMMAS_RELEASE_REQ: as_msg.msgID = _emm_as_release_req( &msg->u.release, - &as_msg.msg.nas_release_req); + (void *)(&as_msg.msg.nas_release_req)); break; case _EMMAS_SECURITY_RES: as_msg.msgID = _emm_as_security_res(user->emm_data, &msg->u.security, - &as_msg.msg.ul_info_transfer_req); + (void *)(&as_msg.msg.ul_info_transfer_req)); break; case _EMMAS_ESTABLISH_REQ: as_msg.msgID = _emm_as_establish_req(user->emm_data, &msg->u.establish, - &as_msg.msg.nas_establish_req); + (void *)(&as_msg.msg.nas_establish_req)); break; @@ -1069,10 +1077,10 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) ** ** ***************************************************************************/ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, - ul_info_transfer_req_t *as_msg) + void *ul_info_transfer_req_unaligned) { LOG_FUNC_IN; - + ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned; int size = 0; int is_encoded = FALSE; @@ -1165,12 +1173,12 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg ** ** ***************************************************************************/ static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *msg, - ul_info_transfer_req_t *as_msg) + void *ul_info_transfer_req_unaligned) { LOG_FUNC_IN; int size = 0; - + ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned; LOG_TRACE(INFO, "EMMAS-SAP - Send AS status indication (cause=%d)", msg->emm_cause); @@ -1239,12 +1247,12 @@ static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t ** ** ***************************************************************************/ static int _emm_as_release_req(const emm_as_release_t *msg, - nas_release_req_t *as_msg) + void *nas_release_req_unaligned) { LOG_FUNC_IN; LOG_TRACE(INFO, "EMMAS-SAP - Send AS release request"); - + nas_release_req_t *as_msg = (nas_release_req_t *)nas_release_req_unaligned; /* Setup the AS message */ if (msg->guti) { as_msg->s_tmsi.MMEcode = msg->guti->gummei.MMEcode; @@ -1279,10 +1287,10 @@ static int _emm_as_release_req(const emm_as_release_t *msg, ** ** ***************************************************************************/ static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *msg, - ul_info_transfer_req_t *as_msg) + void *ul_info_transfer_req_unaligned) { LOG_FUNC_IN; - + ul_info_transfer_req_t *as_msg=(ul_info_transfer_req_t *)ul_info_transfer_req_unaligned; int size = 0; LOG_TRACE(INFO, "EMMAS-SAP - Send AS security response"); @@ -1373,12 +1381,12 @@ static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_securit ** ** ***************************************************************************/ static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *msg, - nas_establish_req_t *as_msg) + void *nas_establish_req_unaligned) { LOG_FUNC_IN; int size = 0; - + nas_establish_req_t *as_msg = (nas_establish_req_t *)nas_establish_req_unaligned; LOG_TRACE(INFO, "EMMAS-SAP - Send AS connection establish request"); nas_message_t nas_msg; diff --git a/openair3/NAS/UE/nas_network.c b/openair3/NAS/UE/nas_network.c index f8abba4900..f6b291bb7b 100644 --- a/openair3/NAS/UE/nas_network.c +++ b/openair3/NAS/UE/nas_network.c @@ -141,11 +141,11 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) case AS_CELL_INFO_CNF: { /* Received cell information confirm */ - const cell_info_cnf_t *info = &msg->msg.cell_info_cnf; - int cell_found = (info->errCode == AS_SUCCESS); - rc = nas_proc_cell_info(user, cell_found, info->tac, - info->cellID, info->rat, - info->rsrp, info->rsrq); + /* remove using pointers to fiels of the packed structure msg as it + * triggers warnings with gcc version 9 */ + const cell_info_cnf_t info = msg->msg.cell_info_cnf; + int cell_found = (info.errCode == AS_SUCCESS); + rc = nas_proc_cell_info(user, cell_found, info.tac, info.cellID, info.rat, info.rsrp, info.rsrq); break; } @@ -157,12 +157,12 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) case AS_NAS_ESTABLISH_CNF: { /* Received NAS signalling connection establishment confirm */ - const nas_establish_cnf_t *confirm = &msg->msg.nas_establish_cnf; + const nas_establish_cnf_t confirm = msg->msg.nas_establish_cnf; - if ( (confirm->errCode == AS_SUCCESS) || - (confirm->errCode == AS_TERMINATED_NAS) ) { - rc = nas_proc_establish_cnf(user, confirm->nasMsg.data, - confirm->nasMsg.length); + if ( (confirm.errCode == AS_SUCCESS) || + (confirm.errCode == AS_TERMINATED_NAS) ) { + rc = nas_proc_establish_cnf(user, confirm.nasMsg.data, + confirm.nasMsg.length); } else { LOG_TRACE(WARNING, "NET-MAIN - " "Initial NAS message not delivered"); @@ -191,10 +191,10 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) break; case AS_DL_INFO_TRANSFER_IND: { - const dl_info_transfer_ind_t *info = &msg->msg.dl_info_transfer_ind; + const dl_info_transfer_ind_t info = msg->msg.dl_info_transfer_ind; /* Received downlink data transfer indication */ - rc = nas_proc_dl_transfer_ind(user, info->nasMsg.data, - info->nasMsg.length); + rc = nas_proc_dl_transfer_ind(user, info.nasMsg.data, + info.nasMsg.length); break; } diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index c367374436..a3eeb26540 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -17,6 +17,7 @@ extern "C" { #include #include #include +#include "openair2/SDAP/nr_sdap/nr_sdap_gnb.h" //#include #pragma pack(1) @@ -74,6 +75,12 @@ class gtpEndPoint { int ipVersion; map ue2te_mapping; map te2ue_mapping; + // we use the same port number for source and destination address + // this allow using non standard gtp port number (different from 2152) + // and so, for example tu run 4G and 5G cores on one system + tcp_udp_port_t get_dstport() { + return (tcp_udp_port_t)atol(addr.destinationService); + } }; class gtpEndPoints { @@ -99,6 +106,8 @@ int legacyInstanceMapping=0; #define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a) #define GTPV1U_HEADER_SIZE (8) + + static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, teid_t teid, uint8_t *Msg,int msgLen, bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { AssertFatal(extHdrFlag==false,"Not developped"); @@ -299,7 +308,6 @@ static int udpServerSocket(openAddr_s addr) { LOG_E(GTPU,"getaddrinfo error: %s\n", gai_strerror(status)); return -1; } - int sockfd=-1; // loop through all the results and bind to the first we can @@ -459,17 +467,18 @@ int ocp_gtpv1u_create_s1u_tunnel(instance_t instance, create_tunnel_req->rnti, create_tunnel_req->num_tunnels, create_tunnel_req->sgw_S1u_teid[0]); - + tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport(); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { AssertFatal(create_tunnel_req->eps_bearer_id[i] > 4, "From legacy code not clear, seems impossible (bearer=%d)\n", create_tunnel_req->eps_bearer_id[i]); int incoming_rb_id=create_tunnel_req->eps_bearer_id[i]-4; + teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, incoming_rb_id, create_tunnel_req->eps_bearer_id[i], create_tunnel_req->sgw_S1u_teid[i], - create_tunnel_req->sgw_addr[i], 2152, + create_tunnel_req->sgw_addr[i], dstport, pdcp_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; @@ -525,14 +534,14 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance, create_tunnel_req->rnti, create_tunnel_req->num_tunnels, create_tunnel_req->upf_NGu_teid[0]); - + tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport(); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, create_tunnel_req->incoming_rb_id[i], create_tunnel_req->pdusession_id[i], create_tunnel_req->upf_NGu_teid[i], - create_tunnel_req->upf_addr[i], 2152, - pdcp_data_req); + create_tunnel_req->upf_addr[i], dstport, + sdap_gnb_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; @@ -869,6 +878,7 @@ void *ocp_gtpv1uTask(void *args) { // to be dev: should be removed, to use API strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr); + strcpy(addr.destinationService,addr.originService); AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n"); break; @@ -876,6 +886,7 @@ void *ocp_gtpv1uTask(void *args) { // to be dev: should be removed, to use API strcpy(addr.originHost, GTPV1U_ENB_S1_REQ(message_p).addrStr); strcpy(addr.originService, GTPV1U_ENB_S1_REQ(message_p).portStr); + strcpy(addr.destinationService,addr.originService); AssertFatal((legacyInstanceMapping=ocp_gtpv1Init(addr))!=0,"Instance 0 reserved for legacy\n"); break; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 644981173b..62b89188f9 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -230,7 +230,6 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - ulsch_max_slots_inactivity = 10; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index 9c0427789d..ac8622fbc5 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -230,7 +230,6 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - ulsch_max_slots_inactivity = 10; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; }