diff --git a/CMakeLists.txt b/CMakeLists.txt index 8559320d51..81cc1edf76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2021,7 +2021,6 @@ set (MAC_NR_SRC_UE ${NR_UE_MAC_DIR}/nr_ue_procedures.c ${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c - ${NR_UE_MAC_DIR}/nr_l1_helpers.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c ) diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index b949584830..31ea662e3c 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -449,6 +449,10 @@ pipeline { def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")" if ("MERGE".equals(env.gitlabActionType)) { addGitLabMRComment comment: message + def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")" + sendSocialMediaMessage('ci-enb', 'good', message2) + } else { + sendSocialMediaMessage('ci-enb', 'good', message) } echo "Pipeline is SUCCESSFUL" } @@ -458,6 +462,10 @@ pipeline { def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")" if ("MERGE".equals(env.gitlabActionType)) { addGitLabMRComment comment: message + def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")" + sendSocialMediaMessage('ci-enb', 'danger', message2) + } else { + sendSocialMediaMessage('ci-enb', 'danger', message) } echo "Pipeline FAILED" } @@ -541,3 +549,9 @@ def finalizeSlaveJob(jobName) { } } } + +// Abstraction function to send social media messages: +// like on Slack or Mattermost +def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { + slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage +} diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 405bd0f4d6..cc35cb4625 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -20,16 +20,6 @@ * contact@openairinterface.org */ -// Abstraction function to send social media messages: -// like on Slack or Mattermost -def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { - if (params.pipelineUsesSlack != null) { - if (params.pipelineUsesSlack) { - slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage - } - } -} - // Location of the executor node def nodeExecutor = params.nodeExecutor @@ -389,10 +379,6 @@ OAI CI Team''', if ("MERGE".equals(env.gitlabActionType)) { echo "This is a MERGE event" addGitLabMRComment comment: message - def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")" - sendSocialMediaMessage('ci-enb', 'good', message2) - } else { - sendSocialMediaMessage('ci-enb', 'good', message) } } } @@ -402,10 +388,6 @@ OAI CI Team''', if ("MERGE".equals(env.gitlabActionType)) { echo "This is a MERGE event" addGitLabMRComment comment: message - def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")" - sendSocialMediaMessage('ci-enb', 'danger', message2) - } else { - sendSocialMediaMessage('ci-enb', 'danger', message) } } } diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry index dda0c5caa1..273b3876be 100644 --- a/ci-scripts/Jenkinsfile-push-registry +++ b/ci-scripts/Jenkinsfile-push-registry @@ -65,13 +65,20 @@ pipeline { WEEK_REF = WEEK_REF.trim() WEEK_TAG = sh returnStdout: true, script: 'python3 ./ci-scripts/provideUniqueImageTag.py --start_tag ' + WEEK_REF WEEK_TAG = WEEK_TAG.trim() + if ((params.forceTag != null) && (params.tagToUse != null)) { + if (params.forceTag) { + WEEK_TAG = params.tagToUse + echo "Forced Tag is ${WEEK_TAG}" + } + } WEEK_SHA = sh returnStdout: true, script: 'git log -n1 --pretty=format:"%h" origin/develop | cut -c 1-8' WEEK_SHA = WEEK_SHA.trim() withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password'] ]) { - def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "proxy"] + def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"] + // Logging in on both registries sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1" sh "docker login -u oaicicd -p oaicicd porcepix.sboai.cs.eurecom.fr > /dev/null 2>&1" listOfImages.eachWithIndex { item, iindex -> @@ -82,6 +89,13 @@ pipeline { sh "docker push --quiet ${DH_Account}/${item}:develop" sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop porcepix.sboai.cs.eurecom.fr/${item}:develop-${WEEK_SHA}" } + // Proxy is not following the same pattern. + sh "docker image tag proxy:develop ${DH_Account}/proxy:develop" + sh "docker image tag proxy:develop ${DH_Account}/proxy:${WEEK_TAG}" + sh "docker push --quiet ${DH_Account}/proxy:develop" + sh "docker push --quiet ${DH_Account}/proxy:${WEEK_TAG}" + sh "docker rmi ${DH_Account}/proxy:develop ${DH_Account}/proxy:${WEEK_TAG}" + // Logging out on both registries sh "docker logout porcepix.sboai.cs.eurecom.fr > /dev/null 2>&1" sh "docker logout > /dev/null 2>&1" } diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index d933c1e143..184bb7bdb3 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -773,22 +773,19 @@ class Containerize(): mySSH.command(f'sed -i -e "s#image: {image}:latest#image: {imageToUse}#" ci-docker-compose.yml', '\$', 2) localMmeIpAddr = EPC.MmeIPAddress mySSH.command('sed -i -e "s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/" ci-docker-compose.yml', '\$', 2) -# if self.flexranCtrlDeployed: -# mySSH.command('sed -i -e "s/FLEXRAN_ENABLED:.*/FLEXRAN_ENABLED: \'yes\'/" ci-docker-compose.yml', '\$', 2) -# mySSH.command('sed -i -e "s/CI_FLEXRAN_CTL_IP_ADDR/' + self.flexranCtrlIpAddress + '/" ci-docker-compose.yml', '\$', 2) -# else: -# mySSH.command('sed -i -e "s/FLEXRAN_ENABLED:.*$/FLEXRAN_ENABLED: \'no\'/" ci-docker-compose.yml', '\$', 2) -# mySSH.command('sed -i -e "s/CI_FLEXRAN_CTL_IP_ADDR/127.0.0.1/" ci-docker-compose.yml', '\$', 2) + # Currently support only one mySSH.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 15) - mySSH.command('docker-compose --file ci-docker-compose.yml config --services | sed -e "s@^@service=@" 2>&1', '\$', 10) - result = re.search('service=(?P[a-zA-Z0-9\_]+)', mySSH.getBefore()) - if result is not None: - svcName = result.group('svc_name') - mySSH.command('docker-compose --file ci-docker-compose.yml up -d ' + svcName, '\$', 15) + svcName = self.services[self.eNB_instance] + if svcName == '': + logging.warning('no service name given: starting all services in ci-docker-compose.yml!') + + mySSH.command(f'docker-compose --file ci-docker-compose.yml up -d -- {svcName}', '\$', 30) # Checking Status - mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5) + grep = '' + if svcName != '': grep = f' | grep -A3 {svcName}' + mySSH.command(f'docker-compose --file ci-docker-compose.yml config {grep}', '\$', 5) result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) unhealthyNb = 0 healthyNb = 0 @@ -848,8 +845,8 @@ class Containerize(): else: # containers are unhealthy, so we won't start. However, logs are stored at the end # in UndeployObject so we here store the logs of the unhealthy container to report it - logfilename = f'{lSourcePath}/cmake_targets/{self.eNB_logFile[self.eNB_instance]}' - mySSH.command('docker logs {containerName} > {logfilename}', '\$', 30) + logfilename = f'{lSourcePath}/cmake_targets/log/{self.eNB_logFile[self.eNB_instance]}' + mySSH.command(f'docker logs {containerName} > {logfilename}', '\$', 30) mySSH.copyin(lIpAddr, lUserName, lPassWord, logfilename, '.') mySSH.close() @@ -896,58 +893,67 @@ class Containerize(): mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) - # Currently support only one - mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5) - containerName = '' - containerToKill = False - result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) - if self.eNB_logFile[self.eNB_instance] == '': - self.eNB_logFile[self.eNB_instance] = 'enb_' + HTML.testCase_id + '.log' - if result is not None: - containerName = result.group('container_name') - containerToKill = True - if containerToKill: - mySSH.command('docker inspect ' + containerName, '\$', 30) - result = re.search('Error: No such object: ' + containerName, mySSH.getBefore()) - if result is not None: - containerToKill = False - if containerToKill: - mySSH.command('docker kill --signal INT ' + containerName, '\$', 30) - time.sleep(5) - mySSH.command('docker kill --signal KILL ' + containerName, '\$', 30) - time.sleep(5) - mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30) - mySSH.command('docker rm -f ' + containerName, '\$', 30) - # Forcing the down now to remove the networks and any artifacts - mySSH.command('docker-compose --file ci-docker-compose.yml down', '\$', 5) + + svcName = self.services[self.eNB_instance] + forceDown = False + if svcName != '': + logging.warning(f'service name given, but will stop all services in ci-docker-compose.yml!') + svcName = '' + + mySSH.command(f'docker-compose -f ci-docker-compose.yml config --services', '\$', 5) + # first line has command, last line has next command prompt + allServices = mySSH.getBefore().split('\r\n')[1:-1] + services = [] + for s in allServices: + mySSH.command(f'docker-compose -f ci-docker-compose.yml ps --all -- {s}', '\$', 5, silent=False) + running = mySSH.getBefore().split('\r\n')[3:-1] + #logging.debug(f'running services: {running}') + if len(running) > 0: # something is running for that service + services.append(s) + logging.info(f'stopping services {services}') + + mySSH.command(f'docker-compose -f ci-docker-compose.yml stop', '\$', 30) + time.sleep(5) # give some time to running containers to stop + for svcName in services: + # head -n -1 suppresses the final "X exited with status code Y" + filename = f'{svcName}-{HTML.testCase_id}.log' + #mySSH.command(f'docker-compose -f ci-docker-compose.yml logs --no-log-prefix -- {svcName} | head -n -1 &> {lSourcePath}/cmake_targets/log/{filename}', '\$', 30) + mySSH.command(f'docker-compose -f ci-docker-compose.yml logs --no-log-prefix -- {svcName} &> {lSourcePath}/cmake_targets/log/{filename}', '\$', 30) + + mySSH.command('docker-compose -f ci-docker-compose.yml down', '\$', 5) # Cleaning any created tmp volume - mySSH.command('docker volume prune --force || true', '\$', 20) + mySSH.command('docker volume prune --force', '\$', 20) mySSH.close() # Analyzing log file! - if containerToKill: - copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '.') - else: - copyin_res = 0 - nodeB_prefix = 'e' - if (copyin_res == -1): - HTML.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' + files = ','.join([f'{s}-{HTML.testCase_id}' for s in services]) + if len(services) > 1: + files = '{' + files + '}' + copyin_res = 0 + if len(services) > 0: + copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, f'{lSourcePath}/cmake_targets/log/{files}.log', '.') + if copyin_res == -1: + HTML.htmleNBFailureMsg='Could not copy logfile to analyze it!' HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) + self.exitStatus = 1 else: - if containerToKill: - logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + self.eNB_logFile[self.eNB_instance]) - logStatus = RAN.AnalyzeLogFile_eNB(self.eNB_logFile[self.eNB_instance], HTML, self.ran_checkers) - else: - logStatus = 0 - if (logStatus < 0): - HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) - else: - HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + for svcName in services: + filename = f'{svcName}-{HTML.testCase_id}.log' + logging.debug(f'\u001B[1m Analyzing logfile {filename}\u001B[0m') + logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers) + if (logStatus < 0): + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) + self.exitStatus = 1 + else: + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) # all the xNB run logs shall be on the server 0 for logCollecting - if containerToKill and self.eNB_serverId[self.eNB_instance] != '0': - mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + self.eNB_logFile[self.eNB_instance], self.eNBSourceCodePath + '/cmake_targets/') - logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m') + if self.eNB_serverId[self.eNB_instance] != '0': + mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, f'./{files}.log', f'{self.eNBSourceCodePath}/cmake_targets/') + if self.exitStatus == 0: + logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m') + else: + logging.error('\u001B[1m Undeploying OAI Object Failed\u001B[0m') def DeployGenObject(self, HTML, RAN, UE): self.exitStatus = 0 diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index 81635f7eb2..a5036e354d 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -19,6 +19,7 @@ gNBs = nr_cellid = 12345678L; + force_256qam_off = 1; tr_s_preference = "f1"; diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf index 2a2524cb87..ca5aba10c0 100644 --- a/ci-scripts/conf_files/gNB_SA_DU.conf +++ b/ci-scripts/conf_files/gNB_SA_DU.conf @@ -22,6 +22,7 @@ gNBs = ////////// Physical parameters: min_rxtxtime = 6; + force_256qam_off = 1; pdcch_ConfigSIB1 = ( { @@ -57,7 +58,7 @@ gNBs = # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPcontrolResourceSetZero = 12; initialDLBWPsearchSpaceZero = 0; #uplinkConfigCommon @@ -181,7 +182,8 @@ MACRLCs = ( local_n_portd = 2152; remote_n_portc = 501; remote_n_portd = 2152; - + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; } ); diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf similarity index 79% rename from ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf rename to ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf index b82944805a..6080ac58aa 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.51PRB.usrpb210.conf @@ -17,9 +17,8 @@ gNBs = ////////// Physical parameters: - min_rxtxtime = 2; - do_CSIRS = 1; - do_SRS = 1; + do_CSIRS = 0; + do_SRS = 0; pdcch_ConfigSIB1 = ( { @@ -36,21 +35,21 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 641280; + # this is 3300.30 MHz + (19 PRBs + 10 SCs)@30kHz SCS (GSCN: 7715) + absoluteFrequencySSB = 620736; dl_frequencyBand = 78; - # this is 3600 MHz - dl_absoluteFrequencyPointA = 640008; + # this is 3300.30 MHz + dl_absoluteFrequencyPointA = 620020; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 dl_subcarrierSpacing = 1; - dl_carrierBandwidth = 106; + dl_carrierBandwidth = 51; #initialDownlinkBWP #genericParameters # this is RBstart=27,L=48 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 + initialDLBWPlocationAndBandwidth = 13750; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -66,11 +65,11 @@ gNBs = # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 ul_subcarrierSpacing = 1; - ul_carrierBandwidth = 106; + ul_carrierBandwidth = 51; pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 28875; + initialULBWPlocationAndBandwidth = 13750; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -156,65 +155,6 @@ gNBs = ); -# Dedicated Serving Cell Configuration -servingCellConfigDedicated = ({ - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - dl_bwp-Id_2 = 2; - dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - dl_bwp-Id_3 = 3; - dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp3_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - ul_bwp-Id_2 = 2; - ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - ul_bwp-Id_3 = 3; - ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp3_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } -); - # ------- SCTP definitions SCTP : { @@ -252,6 +192,7 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; + ul_prbblack_SNR_threshold = 10; ulsch_max_frame_inactivity = 0; } ); @@ -271,8 +212,8 @@ RUs = ( local_rf = "yes" nb_tx = 1 nb_rx = 1 - att_tx = 10; - att_rx = 10; + att_tx = 14; + att_rx = 14; bands = [78]; max_pdschReferenceSignalPower = -27; max_rxgain = 114; diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d60477427e..f1ec41a1e7 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -423,6 +423,9 @@ def GetParametersFromXML(action): string_field=test.findtext('u_retx_th') if (string_field is not None): CONTAINERS.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] + string_field = test.findtext('services') + if string_field is not None: + CONTAINERS.services[CONTAINERS.eNB_instance] = string_field elif action == 'DeployGenObject' or action == 'UndeployGenObject' or action == 'StatsFromGenObject': string_field=test.findtext('yaml_path') @@ -986,6 +989,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re RAN.prematureExit = True elif action == 'Undeploy_Object': CONTAINERS.UndeployObject(HTML, RAN) + if CONTAINERS.exitStatus == 1: + CiTestObj.AutoTerminateeNB(HTML,RAN,EPC,CONTAINERS) + RAN.prematureExit = True elif action == 'Cppcheck_Analysis': SCA.CppCheckAnalysis(HTML) elif action == 'LicenceAndFormattingCheck': diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index da2ac9a401..c758e620b7 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -748,7 +748,7 @@ class RANManagement(): mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20) mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20) mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 60) + mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip *.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 60) result = re.search('core.\d+', mySSH.getBefore()) if result is not None: mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip core* ran_build/build/{lte,nr}-softmodem', '\$', 60) # add core and executable to zip @@ -771,13 +771,13 @@ class RANManagement(): #case where numerator > denumerator with denum ==0 is disregarded, cannot hapen in principle, will lead to 0% perc[i] = 0 if (retx_data[i] == 0) else 100 * retx_data[i + 1] / retx_data[i] #treating % > 100 , % > requirement - stats[i] = perc[i] < 100 and perc[i] <= checkers[i] + stats[i] = perc[i] <= 100 and perc[i] <= checkers[i] return stats def AnalyzeLogFile_eNB(self, eNBlogFile, HTML, checkers={}): - if (not os.path.isfile('./' + eNBlogFile)): + if (not os.path.isfile(eNBlogFile)): return -1 - enb_log_file = open('./' + eNBlogFile, 'r') + enb_log_file = open(eNBlogFile, 'r') exitSignalReceived = False foundAssertion = False msgAssertion = '' @@ -1048,10 +1048,7 @@ class RANManagement(): gnb_markers[k].append(line_cnt) # check whether e/gNB log finishes with "Bye." message - # Note that it is "=" not "|=" so not only is the regex - # asking for EOF (\Z) but we also only retain the last - # line's result - showedByeMsg = re.search(r'^Bye.\n\Z', str(line), re.MULTILINE) is not None + showedByeMsg |= re.search(r'^Bye.\n', str(line), re.MULTILINE) is not None enb_log_file.close() diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 016a3f34ec..53cfbf80cb 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -22,7 +22,7 @@ --> TEST-SA-FR1-B200 - SA SanityCheck with QUECTEL + 40 MHz TDD SA tasks 1 @@ -34,13 +34,13 @@ 000001 050000 050001 + 070001 + 070000 010002 000001 030201 TEST-SA-FR1-B200-terminate - SA tear-down in case of problem + Tear-down tasks 1 030201 - 222222 @@ -35,15 +34,8 @@ Undeploy_Object Undeploy gNB ci-scripts/yaml_files/sa_b200_gnb - 1 - 1 - sa-test - - - - Clean_Test_Server_Images - Clean Test Images on Test Server - 0 + 0 + 0 diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml new file mode 100644 index 0000000000..16081f906a --- /dev/null +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -0,0 +1,172 @@ + + + TEST-SA-FR1-F1-B200 + 40 MHz TDD F1 SA + tasks + 1 + + 110002 + 130101 + 130102 + 100001 + 110000 + 100001 + 150000 + 150001 + 110002 + 100001 + 130201 + + + + + + Initialize_UE + Initialize Quectel + idefix + + + + + Terminate_UE + Terminate Quectel + idefix + + + + Deploy_Object + Deploy gNB-CU in a container + ci-scripts/yaml_files/sa_f1_b200_gnb + 0 + 0 + gnb_cu + + + + Deploy_Object + Deploy gNB-DU (TDD/Band78/40MHz/B200) in a container + ci-scripts/yaml_files/sa_f1_b200_gnb + 0 + 0 + gnb_du_tdd + + + + IdleSleep + Sleep + 5 + + + + IdleSleep + Sleep + 20 + + + + + Ping + Ping: 20pings in 20sec + idefix + -c 20 + 1 + 25 + + + + Ping + Ping: 100pings in 20sec + idefix + -c 100 -i 0.2 + 1 + 110 + + + + Ping + Ping: 20pings in 20sec + idefix + -c 20 + 1 + 110 + + + + Ping + Ping: 100pings in 20sec + idefix + -c 100 -i 0.2 + 1 + 110 + + + + Iperf + iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile) + -u -b 125M -t 60 -i 1 -fm + DL + idefix + 25 + 80 + single-ue + + + + Iperf + iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) + -u -b 8M -t 60 -i 1 -fm + UL + idefix + 1 + 95 + single-ue + + + + Iperf + iperf (BIDIR TCP)(10 sec)(single-ue profile) + -t 10 --bidir + BIDIR + idefix + single-ue + + + + Undeploy_Object + Undeploy CU-DU + ci-scripts/yaml_files/sa_f1_b200_gnb + 0 + 0 + 1,100,100,100 + 1,100,100,100 + + + + diff --git a/ci-scripts/xml_files/container_sa_f1_b200_terminate.xml b/ci-scripts/xml_files/container_sa_f1_b200_terminate.xml new file mode 100644 index 0000000000..cd8445f9ce --- /dev/null +++ b/ci-scripts/xml_files/container_sa_f1_b200_terminate.xml @@ -0,0 +1,48 @@ + + + TEST-SA-FR1-F1-B200-terminate + Tear-down + tasks + 1 + + 230201 + 222222 + + + + + Undeploy_Object + Undeploy CU-DU + ci-scripts/yaml_files/sa_f1_b200_gnb + 0 + 0 + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + + diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index 952732f22d..5765a33351 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -270,7 +270,7 @@ services: container_name: rfsim5g-oai-du environment: RFSIMULATOR: server - USE_SA_TDD_CU: 'yes' + USE_SA_TDD_DU: 'yes' GNB_NAME: du-rfsim TAC: 1 MCC: '208' diff --git a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml index 9ea52c1247..32655ffe77 100644 --- a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml @@ -20,7 +20,7 @@ services: GNB_NGA_IP_ADDRESS: 192.168.68.194 GNB_NGU_IF_NAME: eth0 GNB_NGU_IP_ADDRESS: 192.168.68.194 - USE_ADDITIONAL_OPTIONS: --sa -E -q --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function volumes: - /dev:/dev networks: diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml new file mode 100644 index 0000000000..05b6ee03bc --- /dev/null +++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml @@ -0,0 +1,89 @@ +version: '3.8' + +services: + gnb_cu: + image: oai-gnb:latest + privileged: true + container_name: sa-cu-gnb + environment: + USE_SA_CU: 'yes' + USE_B2XX: 'yes' + GNB_NAME: gNB-CU-in-docker + MCC: '222' + MNC: '01' + MNC_LENGTH: 2 + TAC: 1 + NSSAI_SST: 1 + NSSAI_SD0: 1 + NSSAI_SD1: 2 + AMF_IP_ADDRESS: 172.21.16.136 + GNB_NGA_IF_NAME: eth0 + GNB_NGA_IP_ADDRESS: 192.168.68.194 + GNB_NGU_IF_NAME: eth0 + GNB_NGU_IP_ADDRESS: 192.168.68.194 + F1_IF_NAME: eth0 + F1_CU_IP_ADDRESS: 192.168.68.194 + F1_DU_IP_ADDRESS: 192.168.68.195 + F1_CU_D_PORT: 2153 + F1_DU_D_PORT: 2153 + USE_ADDITIONAL_OPTIONS: --sa --log_config.global_log_options level,nocolor,time,line_num,function + volumes: + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.68.194 + #entrypoint: /bin/bash -c "sleep infinity" + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + + gnb_du_tdd: + image: oai-gnb:latest + privileged: true + container_name: sa-du-b200-gnb + environment: + USE_SA_TDD_DU: 'yes' + USE_B2XX: 'yes' + GNB_NAME: gNB-DU-in-docker + MCC: '222' + MNC: '01' + MNC_LENGTH: 2 + TAC: 1 + NSSAI_SST: 1 + NSSAI_SD0: 1 + NSSAI_SD1: 2 + AMF_IP_ADDRESS: 172.21.16.136 + GNB_NGA_IF_NAME: eth0 + GNB_NGA_IP_ADDRESS: 192.168.68.194 + GNB_NGU_IF_NAME: eth0 + GNB_NGU_IP_ADDRESS: 192.168.68.194 + F1_IF_NAME: eth0 + F1_CU_IP_ADDRESS: 192.168.68.194 + F1_DU_IP_ADDRESS: 192.168.68.195 + F1_CU_D_PORT: 2153 + F1_DU_D_PORT: 2153 + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx -E --log_config.global_log_options level,nocolor,time,line_num,function --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 + volumes: + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.68.195 + #entrypoint: /bin/bash -c "sleep infinity" + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + public_net: + name: sa-b200-gnb-net + ipam: + config: + - subnet: 192.168.68.192/26 + driver_opts: + com.docker.network.bridge.name: "sa-gnb-net" diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py index 1d5dbb5cb5..9ad4f3c5e6 100644 --- a/docker/scripts/generateTemplate.py +++ b/docker/scripts/generateTemplate.py @@ -60,7 +60,7 @@ def main(): "rcc.band40.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.tm1.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', - "gnb.sa.band78.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "gnb.sa.band78.fr1.51PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.sa.band66.fr1.106PRB.usrpn300.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_CU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_DU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index c3c4ef0b2d..bb1bd50555 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -13,7 +13,7 @@ if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb if [[ -v USE_SA_TDD_MONO_B2XX ]]; then cp $PREFIX/etc/gnb.sa.tdd.b2xx.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_FDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.fdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_CU ]]; then cp $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi -if [[ -v USE_SA_TDD_CU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi +if [[ -v USE_SA_TDD_DU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_NFAPI_VNF ]]; then cp $PREFIX/etc/gnb.sa.nfapi.vnf.conf $PREFIX/etc/gnb.conf; fi # Sometimes, the templates are not enough. We mount a conf file on $PREFIX/etc. It can be a template itself. if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/gnb.conf; fi diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml index 524c6fbb42..0d1a02974b 100644 --- a/docker/scripts/gnb_parameters.yaml +++ b/docker/scripts/gnb_parameters.yaml @@ -109,7 +109,7 @@ - key: parallel_config env: "@THREAD_PARALLEL_CONFIG@" - - filePrefix: gnb.sa.band78.fr1.106PRB.usrpb210.conf + - filePrefix: gnb.sa.band78.fr1.51PRB.usrpb210.conf outputfilename: "gnb.sa.tdd.b2xx.conf" config: - key: gNB_ID diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 3fdb18eaae..5c41ebf43b 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -162,10 +162,8 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, ue->dci_thres = 0; // Setting UE mode to NOT_SYNCHED by default - for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ + for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++) ue->UE_mode[gNB_id] = NOT_SYNCHED; - ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t)); - } // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -268,7 +266,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) } free_and_zero(rach_ind->pdu_list); free_and_zero(rach_ind); - nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0); + nr_Msg1_transmitted(0); } if (dl_tti_request) { @@ -300,7 +298,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) } } -static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources) +static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) { fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); if (!ul_config) @@ -313,8 +311,7 @@ static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_inf AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - uint8_t nr_prach = nr_ue_get_rach(prach_resources, - prach_pdu, + uint8_t nr_prach = nr_ue_get_rach(prach_pdu, ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, @@ -349,8 +346,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) reset_queue(&nr_ul_dci_req_queue); reset_queue(&nr_ul_tti_req_queue); - NR_PRACH_RESOURCES_t prach_resources; - memset(&prach_resources, 0, sizeof(prach_resources)); NR_UL_TIME_ALIGNMENT_t ul_time_alignment; memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); int last_sfn_slot = -1; @@ -462,7 +457,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) nr_ue_scheduler(NULL, &ul_info); nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx); nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL); - check_nr_prach(mac, &ul_info, &prach_resources); + check_nr_prach(mac, &ul_info); } if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) { NR_UE_MAC_INST_t *mac = get_mac_inst(0); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 656399df97..091fc813e9 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -24,7 +24,7 @@ #include "PHY/impl_defs_nr.h" #define NFAPI_UE_MAX_NUM_CB 8 -#define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_UL_PDU 255 /* typedef unsigned int uint32_t; @@ -191,7 +191,10 @@ typedef struct { uint16_t freq_msg1; // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble uint8_t ssb_nb_in_ro; - // nfapi_nr_ul_beamforming_t beamforming; + /// Preamble index for PRACH (0-63) + uint8_t ra_PreambleIndex; + /// PRACH TX power (TODO possibly modify to uint) + int16_t prach_tx_power; } fapi_nr_ul_config_prach_pdu; typedef struct { diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index cf17d6cdd4..d2cd9d7a9f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -19,7 +19,7 @@ #define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 #define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6 -#define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_UL_PDU 255 #define NFAPI_MAX_NUM_UCI_INDICATION 8 #define NFAPI_MAX_NUM_GROUPS 8 #define NFAPI_MAX_NUM_CB 8 diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index d8cf2fdc1b..710856d0b7 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -35,6 +35,8 @@ #include "PHY/phy_extern.h" #include "nr_ul_estimation.h" +#define I0_SKIP_DC 1 + extern openair0_config_t openair0_cfg[MAX_CARDS]; int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) @@ -155,43 +157,43 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power)); for (int s=first_symb;s<(first_symb+num_symb);s++) { + int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; for (rb=0; rbN_RB_UL; rb++) { - if (s==first_symb /*&& ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0)*/) { - nb_symb[rb]=0; - for (int aarx=0; aarxnb_antennas_rx;aarx++) - measurements->n0_subband_power[aarx][rb]=0; - } - int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; - if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0) { // check that rb was not used in this subframe - nb_symb[rb]++; + if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe + !(I0_SKIP_DC && rb == frame_parms->N_RB_UL>>1)) { // skip middle PRB because of artificial noise possibly created by FFT + int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; + nb_symb[rb]++; for (int aarx=0; aarxnb_antennas_rx; aarx++) { - int offset = offset0 + (s*frame_parms->ofdm_symbol_size); - int32_t *ul_ch = &common_vars->rxdataF[aarx][offset]; - int len = 12; + int32_t *ul_ch = &common_vars->rxdataF[aarx][offset]; + int32_t signal_energy; if (((frame_parms->N_RB_UL&1) == 1) && (rb==(frame_parms->N_RB_UL>>1))) { - len=6; + signal_energy = signal_energy_nodc(ul_ch, 6); + ul_ch = &common_vars->rxdataF[aarx][offset0]; + signal_energy += signal_energy_nodc(ul_ch, 6); + } else { + signal_energy = signal_energy_nodc(ul_ch, 12); } - AssertFatal(ul_ch, "RX signal buffer (freq) problem\n"); - measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len); + measurements->n0_subband_power[aarx][rb] += signal_energy; + LOG_D(PHY,"slot %d symbol %d RB %d aarx %d n0_subband_power %d\n", slot, s, rb, aarx, signal_energy); } //antenna } } //rb } // symb int nb_rb=0; int32_t n0_subband_tot=0; - int32_t n0_subband_tot_perPRB=0; - int32_t n0_subband_tot_perANT[1+frame_parms->nb_antennas_rx]; + int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx]; + + memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT)); for (int rb = 0 ; rbN_RB_UL;rb++) { - n0_subband_tot_perPRB=0; + int32_t n0_subband_tot_perPRB=0; if (nb_symb[rb] > 0) { for (int aarx=0;aarxnb_antennas_rx;aarx++) { measurements->n0_subband_power[aarx][rb]/=nb_symb[rb]; measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]); n0_subband_tot_perPRB+=measurements->n0_subband_power[aarx][rb]; - if (rb==0) n0_subband_tot_perANT[aarx]=measurements->n0_subband_power[aarx][rb]; - else n0_subband_tot_perANT[aarx]+=measurements->n0_subband_power[aarx][rb]; + n0_subband_tot_perANT[aarx]+=measurements->n0_subband_power[aarx][rb]; } n0_subband_tot_perPRB/=frame_parms->nb_antennas_rx; measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_subband_tot_perPRB); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index eb012532ce..b3d492d025 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -413,14 +413,13 @@ void rx_nr_prach_ru(RU_t *ru, } void rx_nr_prach(PHY_VARS_gNB *gNB, - nfapi_nr_prach_pdu_t *prach_pdu, - int prachOccasion, - int frame, - int subframe, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay - ) + nfapi_nr_prach_pdu_t *prach_pdu, + int prachOccasion, + int frame, + int slot, + uint16_t *max_preamble, + uint16_t *max_preamble_energy, + uint16_t *max_preamble_delay) { AssertFatal(gNB!=NULL,"Can only be called from gNB\n"); @@ -481,7 +480,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, prach_ifft = gNB->prach_vars.prach_ifft; prachF = gNB->prach_vars.prachF; if (LOG_DEBUGFLAG(PRACH)){ - if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, rootSequenceIndex %d\n", subframe,msg1_frequencystart,rootSequenceIndex); + if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex); } start_meas(&gNB->rx_prach); @@ -506,7 +505,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (LOG_DEBUGFLAG(PRACH)){ int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140)); - if (en>60) LOG_D(PHY,"frame %d, subframe %d : Trying preamble %d \n",frame,subframe,preamble_index); + if (en>60) LOG_D(PHY,"frame %d, slot %d : Trying preamble %d \n",frame,slot,preamble_index); } if (restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index @@ -585,8 +584,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(PRACH)) { int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", - frame,subframe,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en); + if (en>60) LOG_D(PHY,"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", + frame,slot,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en); } LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); @@ -605,8 +604,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, memset(prachF, 0, sizeof(int16_t)*2*1024 ); if (LOG_DUMPFLAG(PRACH)) { - LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); - LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); + LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); + LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); } for (aa=0;aa*max_preamble_energy) { - LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); - *max_preamble_energy = levdB; - *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate - *max_preamble = preamble_index; + LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); + *max_preamble_energy = levdB; + *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate + *max_preamble = preamble_index; } } }// preamble_index diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index e8b535d3bd..7940b481de 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1515,31 +1515,50 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, #endif prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1 +#ifdef DEBUG_NR_PUCCH_RX + printf("0.prod_re[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",aa, + ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3], + ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7], + ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11], + ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]); +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 +#ifdef DEBUG_NR_PUCCH_RX + printf("1.prod_re[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",aa, + ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3], + ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7], + ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11], + ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]); +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7 - prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); - prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15 +#ifdef DEBUG_NR_PUCCH_RX + printf("2.prod_re[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",aa, + ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3], + ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7], + ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11], + ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]); +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); } int64_t corr_re=0,corr_im=0; for (int aa=0;aa corr) { corr = corr_tmp; cw_ML=cw; +#ifdef DEBUG_NR_PUCCH_RX + printf("slot %d PUCCH2 cw_ML %d, corr %llu\n",slot,cw_ML,corr); +#endif } } // cw loop corr_dB = dB_fixed64((uint64_t)corr); #ifdef DEBUG_NR_PUCCH_RX - LOG_I(PHY,"slot %d PUCCH2 cw_ML %d, metric %d dB\n",slot,cw_ML,corr_dB); + printf("slot %d PUCCH2 cw_ML %d, metric %d \n",slot,cw_ML,corr_dB); #endif decodedPayload[0]=(uint64_t)cw_ML; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index c387c7f38b..983366e35e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -110,8 +110,6 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, //mac_resynch(); //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); ue->UE_mode[0] = PRACH; - ue->prach_resources[gNB_id]->sync_frame = frame; - ue->prach_resources[gNB_id]->init_msg1 = 0; } else { ue->UE_mode[0] = PUSCH; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index d1cab858c7..c8ae045e1b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -123,8 +123,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t gNB_id); -int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); - void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_UE_PDSCH **pdsch_vars, NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 69a1a88916..1b5689f335 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -46,42 +46,6 @@ //#define DEBUG_MEAS_UE //#define DEBUG_RANK_EST -// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission -// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 -// Assumptions: -// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE -// Measurement units: -// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) -int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){ - - PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - int16_t pathloss; - - if (get_softmodem_params()->do_ra){ - - long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power; - - pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]); - - LOG_D(MAC, "In %s: pathloss %d dB, UE RX total gain %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", - __FUNCTION__, - pathloss, - ue->rx_total_gain_dB, - referenceSignalPower, - pow(10, referenceSignalPower/10), - ue->measurements.rsrp_dBm[gNB_index], - pow(10, ue->measurements.rsrp_dBm[gNB_index]/10)); - - } else { - - pathloss = ((int16_t)(((10*ue->rx_total_gain_dB) - dB_fixed_times10(ue->measurements.rsrp[gNB_index]))/10)); - - } - - return pathloss; - -} - uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index f56f01f764..e5e0e44b6b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -61,7 +61,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t NR_DL_FRAME_PARMS *fp=&ue->frame_parms; fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config; - NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id]; fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; @@ -73,7 +72,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; int32_t Xu_re, Xu_im; int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot; - //int restricted_Type; fd_occasion = 0; prach_len = 0; @@ -91,12 +89,13 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1; NCS = prach_pdu->num_cs; prach_fmt_id = prach_pdu->prach_format; - preamble_index = prach_resources->ra_PreambleIndex; + preamble_index = prach_pdu->ra_PreambleIndex; kbar = 1; K = 24; k = 12*n_ra_prb - 6*fp->N_RB_UL; prachStartSymbol = prach_pdu->prach_start_symbol; - //restricted_Type = 0; + + LOG_D(PHY,"Generate NR PRACH %d.%d\n", frame, slot); compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length, nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences, diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index b551a259af..fca93b29c7 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -647,9 +647,9 @@ typedef struct { //! estimated avg noise power (dB) unsigned int n0_power_tot_dB; //! estimated avg noise power per RB per RX ant (lin) - unsigned int n0_subband_power[MAX_NUM_RU_PER_gNB][275]; + unsigned int n0_subband_power[NB_ANTENNAS_RX][275]; //! estimated avg noise power per RB per RX ant (dB) - unsigned int n0_subband_power_dB[MAX_NUM_RU_PER_gNB][275]; + unsigned int n0_subband_power_dB[NB_ANTENNAS_RX][275]; //! estimated avg subband noise power (dB) unsigned int n0_subband_power_avg_dB; //! estimated avg subband noise power per antenna (dB) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 8a73a4fb86..1d37d0e85c 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -590,11 +590,9 @@ typedef struct { // when off, defaults to frequency domain interpolation int chest_freq; int chest_time; - int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX]; UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX]; - NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX]; /// \brief ?. /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) uint32_t total_TBS[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 10c4c9df6d..fe0397970b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -93,7 +93,6 @@ #define NR_MAX_NB_HARQ_PROCESSES 16 #define NR_MAX_PDSCH_TBS 3824 -#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits. #define MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER 36 @@ -203,39 +202,6 @@ typedef struct NR_BWP_PARMS { nr_prg_parms_t prg_parms; } NR_BWP_PARMS; -typedef struct { - /// PRACH format retrieved from prach_ConfigIndex - uint16_t prach_format; - /// Preamble index for PRACH (0-63) - uint8_t ra_PreambleIndex; - /// Preamble Tx Counter - uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; - /// Preamble Power Ramping Counter - uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; - /// 2-step RA power offset - int POWER_OFFSET_2STEP_RA; - /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step. - int ra_PREAMBLE_RECEIVED_TARGET_POWER; - /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex - uint8_t ra_TDD_map_index; - /// RA Preamble Power Ramping Step in dB - uint32_t RA_PREAMBLE_POWER_RAMPING_STEP; - /// - uint8_t RA_PREAMBLE_BACKOFF; - /// - uint8_t RA_SCALING_FACTOR_BI; - /// Indicating whether it is 2-step or 4-step RA - nr_ra_type_e RA_TYPE; - /// UE configured maximum output power - int RA_PCMAX; - /// Corresponding RA-RNTI for UL-grant - uint16_t ra_RNTI; - /// Frame of last completed synch - uint16_t sync_frame; - /// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync - uint8_t init_msg1; -} NR_PRACH_RESOURCES_t; - typedef struct { uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS]; uint8_t srs_generated_signal_bits; diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index b0f59d5f47..2708cbd161 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -121,30 +121,12 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { ru=gNB->RU_list[0]; int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST); - + if (prach_id>=0) { nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu; uint8_t prachStartSymbol; uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format); - - /* - uint16_t format,RA_sfn_index; - uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period; - get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value, - frame,slot, - gNB->gNB_config.carrier_config.dl_frequency.value, - gNB->frame_parms.numerology_index, - gNB->frame_parms.frame_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur, - &RA_sfn_index, - &N_RA_slot, - &config_period); - */ - for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { for (ru_aa=0,aa=0;ru_aanb_rx;ru_aa++,aa++) { gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; @@ -152,7 +134,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. - + rx_nr_prach(gNB, prach_pdu, prach_oc, @@ -160,8 +142,8 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { slot, &max_preamble[0], &max_preamble_energy[0], - &max_preamble_delay[0] - ); + &max_preamble_delay[0]); + free_nr_prach_entry(gNB,prach_id); LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n", frame,slot,prach_oc,prachStartSymbol, diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 2938c991ee..88a95573f5 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -696,8 +696,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { else num_symb=NR_NUMBER_OF_SYMBOLS_PER_SLOT; gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb); + const int soffset = (slot_rx&3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; - int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset+(47*12)],12*18); + int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset+offset+(47*12)],12*18); LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); start_meas(&gNB->phy_proc_rx); @@ -726,7 +727,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1; offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12); - power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12); + power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset+offset],12); LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n",frame_rx,slot_rx,power_rxF); nr_decode_pucch0(gNB, diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 54ad012718..5b81753128 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -411,7 +411,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; /* PRACH */ - //NR_PRACH_RESOURCES_t *prach_resources; fapi_nr_ul_config_prach_pdu *prach_config_pdu; /* PUSCH */ nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index fb4a737da1..31be395df8 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -52,7 +52,6 @@ #include "executables/softmodem-common.h" #include "executables/nr-uesoftmodem.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 @@ -391,8 +390,6 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id, if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){ if (get_softmodem_params()->do_ra) { ue->UE_mode[gNB_id] = PRACH; - ue->prach_resources[gNB_id]->sync_frame = frame_rx; - ue->prach_resources[gNB_id]->init_msg1 = 0; } else { ue->UE_mode[gNB_id] = PUSCH; } @@ -1302,44 +1299,25 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp uint8_t mod_id = ue->Mod_id; - NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id]; - AssertFatal(prach_resources != NULL, "ue->prach_resources[%u] == NULL\n", gNB_id); uint8_t nr_prach = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); - if (ue->mac_enabled == 0){ - - prach_resources->ra_TDD_map_index = 0; - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; - prach_resources->ra_RNTI = 0x1234; - nr_prach = 1; - prach_resources->init_msg1 = 1; - - } else { - - nr_prach = nr_ue_get_rach(prach_resources, &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx); - LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach); - } + nr_prach = nr_ue_get_rach(&ue->prach_vars[gNB_id]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx); + LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach); if (nr_prach == GENERATE_PREAMBLE) { - if (ue->mac_enabled == 1) { - int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); - int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); - ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); + fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; + ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power; - LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", - __FUNCTION__, - mod_id, - frame_tx, - nr_slot_tx, - prach_resources->ra_PreambleIndex, - pathloss, - ue->tx_power_dBm[nr_slot_tx], - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER, - prach_resources->ra_RNTI); - } + LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, P0_PRACH %d)\n", + __FUNCTION__, + mod_id, + frame_tx, + nr_slot_tx, + prach_pdu->ra_PreambleIndex, + ue->tx_power_dBm[nr_slot_tx]); ue->prach_vars[gNB_id]->amp = AMP; @@ -1358,9 +1336,6 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t dB_fixed(prach_power), ue->prach_vars[gNB_id]->amp); - if (ue->mac_enabled == 1) - nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id); - } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) { LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id); ue->UE_mode[gNB_id] = RA_WAIT_CR; diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 163a828003..4f45250016 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -213,12 +213,8 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, pucch_pdu = &pucch_vars->pucch_pdu[i]; uint16_t nb_of_prbs = pucch_pdu->prb_size; /* Generate PUCCH signal according to its format and parameters */ - ue->generate_ul_signal[gNB_id] = 1; - int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ - int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs))); - - int16_t pucch_tx_power = pucch_pdu->pucch_tx_power + contributor + PL; + int16_t pucch_tx_power = pucch_pdu->pucch_tx_power; if (pucch_tx_power > ue->tx_power_max_dBm) pucch_tx_power = ue->tx_power_max_dBm; diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c index 76f4e826ee..71e2577ec3 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c @@ -16,338 +16,5 @@ int32_t get_uldl_offset(int nr_bandP) { re NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } -/* - * 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 - */ - -/*! \file ra_procedures.c - * \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15) - * \author R. Knopp, Navid Nikaein, Guido Casati - * \date 2019 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de - * \note - * \warning - */ - - -/* -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "PHY_INTERFACE/phy_interface_extern.h" -#include "SCHED_UE/sched_UE.h" -#include "COMMON/mac_rrc_primitives.h" -#include "RRC/LTE/rrc_extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "common/utils/LOG/log.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" -#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/ - -/* Tools */ -#include "SIMULATION/TOOLS/sim.h" // for taus - -/* RRC */ -#include "NR_RACH-ConfigCommon.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/MAC/mac.h" - -extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9]; -extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; - -//extern uint8_t nfapi_mode; - -// WIP -// This routine implements Section 5.1.2 (UE Random Access Resource Selection) -// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321 -void nr_get_prach_resources(module_id_t mod_id, - int CC_id, - uint8_t gNB_id, - uint8_t t_id, - NR_PRACH_RESOURCES_t *prach_resources, - NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; - // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo - - int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0; - uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size; - - // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo - - /////////////////////////////////////////////////////////// - //////////* UE Random Access Resource Selection *////////// - /////////////////////////////////////////////////////////// - - // todo: - // - switch initialisation cases - // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) - // --- SSB selection, set prach_resources->ra_PreambleIndex - // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 - // --- set PREAMBLE_INDEX to ra_preamble_index - // --- select the SSB signalled by PDCCH - // -- RA initiated for SI request: - // --- SSB selection, set prach_resources->ra_PreambleIndex - - // if (rach_ConfigDedicated) { // This is for network controlled Mobility - // // operation for contention-free RA resources when: - // // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection - // // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection - // prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex; - // return; - // } - - //////////* Contention-based RA preamble selection *////////// - // todo: - // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB - // - todo determine next available PRACH occasion - - // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; - - AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); - - nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; - - Msg3_size = mac->RA_Msg3_size; - numberOfRA_Preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles; - - if (!nr_rach_ConfigCommon->groupBconfigured) { - noGroupB = 1; - } else { - // RA preambles group B is configured - // - Defining the number of RA preambles in RA Preamble Group A for each SSB */ - sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA; - switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){ - /* - Threshold to determine the groups of RA preambles */ - case 0: - messageSizeGroupA = 56; - break; - case 1: - messageSizeGroupA = 144; - break; - case 2: - messageSizeGroupA = 208; - break; - case 3: - messageSizeGroupA = 256; - break; - case 4: - messageSizeGroupA = 282; - break; - case 5: - messageSizeGroupA = 480; - break; - case 6: - messageSizeGroupA = 640; - break; - case 7: - messageSizeGroupA = 800; - break; - case 8: - messageSizeGroupA = 1000; - break; - case 9: - messageSizeGroupA = 72; - break; - default: - AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); - /* todo cases 10 -15*/ - } - - /* Power offset for preamble selection in dB */ - messagePowerOffsetGroupB = -9999; - switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){ - case 0: - messagePowerOffsetGroupB = -9999; - break; - case 1: - messagePowerOffsetGroupB = 0; - break; - case 2: - messagePowerOffsetGroupB = 5; - break; - case 3: - messagePowerOffsetGroupB = 8; - break; - case 4: - messagePowerOffsetGroupB = 10; - break; - case 5: - messagePowerOffsetGroupB = 12; - break; - case 6: - messagePowerOffsetGroupB = 15; - break; - case 7: - messagePowerOffsetGroupB = 18; - break; - default: - AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); - } - - } - - PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; - - /* Msg3 has not been transmitted yet */ - if (first_Msg3 == 1) { - if (noGroupB == 1) { - // use Group A preamble - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - mac->RA_usedGroupA = 1; - } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) { - // Group B is configured and RA preamble Group A is used - // - todo add condition on CCCH_sdu_size for initiation by CCCH - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - mac->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 - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - mac->RA_usedGroupA = 0; - } - } else { // Msg3 is being retransmitted - if (mac->RA_usedGroupA == 1 && noGroupB == 1) { - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){ - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - } else { - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - } - } - - // todo determine next available PRACH occasion - // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured - // - else if SSB is selected above - // - else if CSI-RS is selected above - - ///////////////////////////////////////////////////////////////////////////// - //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *////////// - ///////////////////////////////////////////////////////////////////////////// - // todo: - // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) - // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission - // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded) - - if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) - mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; - - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); - - // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) - // 1) this does not apply to contention-free RA Preamble for beam failure recovery request - // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) - - switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used - case 0: - msg1_FDM = 1; - break; - case 1: - msg1_FDM = 2; - break; - case 2: - msg1_FDM = 4; - break; - case 3: - msg1_FDM = 8; - break; - default: - AssertFatal(1 == 0,"Unknown msg1_FDM %lu\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); - } - - prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; - - // ra_RNTI computation - // - todo: this is for TDD FR1 only - // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier - // - f_id: index of the PRACH occasion in the frequency domain - // - s_id is starting symbol of the PRACH occasion [0...14] - // - t_id is the first slot of the PRACH occasion in a system frame [0...80] - - ul_carrier_id = 0; // NUL - f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; - SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]; - s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; - - // Pick the first slot of the PRACH occasion in a system frame - for (i = 0; i < 10; i++){ - if (((SFN_nbr & (1 << i)) >> i) == 1){ - t_id = 2*i; - break; - } - } - prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; - mac->ra_rnti = prach_resources->ra_RNTI; - - LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); -} - -// TbD: RA_attempt_number not used -void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - mac->ra_state = WAIT_RAR; - // Start contention resolution timer - mac->RA_attempt_number++; -} - -void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id){ - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP); - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - // start contention resolution timer - mac->RA_contention_resolution_cnt = 0; - mac->RA_contention_resolution_timer_active = 1; -} - -///////////////////////////////////////////////////////////////////////// -///////* Random Access Preamble Initialization (5.1.1 TS 38.321) */////// -///////////////////////////////////////////////////////////////////////// -/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300) -/// Only one RA procedure is ongoing at any point in time in a MAC entity -/// the RA procedure on a SCell shall only be initiated by PDCCH order - -// WIP -// todo TS 38.321: -// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX -// - BWP operation (subclause 5.15 TS 38.321) -// - handle initialization by beam failure recovery -// - handle initialization by handover -// - handle transmission on DCCH using PRACH (during handover, or sending SR for example) -// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader) -// - fix rrc data req logic -// - retrieve TBS -// - add mac_rrc_nr_data_req_ue, etc ... -// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 7adb0d4b93..982e5b4136 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -264,7 +264,6 @@ int main(int argc, char **argv){ int n_bytes=0; NR_DL_FRAME_PARMS *frame_parms; - NR_PRACH_RESOURCES_t prach_resources; nfapi_nr_prach_config_t *prach_config; nfapi_nr_prach_pdu_t *prach_pdu; fapi_nr_prach_config_t *ue_prach_config; @@ -694,7 +693,6 @@ int main(int argc, char **argv){ ue_prach_pdu = &UE->prach_vars[0]->prach_pdu; ue_prach_config = &UE->nrUE_config.prach_config; - UE->prach_resources[0] = &prach_resources; txdata = UE->common_vars.txdata; UE->prach_vars[0]->amp = AMP; @@ -717,8 +715,7 @@ int main(int argc, char **argv){ if (n_frames == 1) printf("raPreamble %d\n",preamble_tx); - UE->prach_resources[0]->ra_PreambleIndex = preamble_tx; - UE->prach_resources[0]->init_msg1 = 1; + ue_prach_pdu->ra_PreambleIndex = preamble_tx; // Configure channel bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index); @@ -769,14 +766,7 @@ int main(int argc, char **argv){ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, UE->X_u); - /*tx_lev = generate_nr_prach(UE, - 0, //gNB_id, - subframe); */ //commented for testing purpose - - UE_nr_rxtx_proc_t proc={0}; - proc.frame_tx = frame; - proc.nr_slot_tx = slot; - nr_ue_prach_procedures(UE, &proc, 0); + generate_nr_prach(UE, 0, frame, slot); /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); @@ -842,31 +832,31 @@ int main(int argc, char **argv){ for (trial=0; trialsamples_per_frame, 0); - } + if (awgn_flag == 0) { + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0); + } - if (n_frames==1) { - printf("rx_level data symbol %f, tx_lev %f\n", - 10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0)), - 10*log10(tx_lev)); - } + if (n_frames==1) { + printf("rx_level data symbol %f, tx_lev %f\n", + 10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0)), + 10*log10(tx_lev)); + } - for (i = 0; i< frame_parms->samples_per_subframe; i++) { - for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + for (i = 0; i< frame_parms->samples_per_subframe; i++) { + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + } } - } } else { n_bytes = fread(&ru->common.rxdata[0][rx_prach_start],sizeof(int32_t),frame_parms->samples_per_subframe,input_fd); printf("fread %d bytes from file %s\n",n_bytes,input_file); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 7dc5ccdeff..d3f7ef5c7b 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -104,6 +104,7 @@ int main(int argc, char **argv) int nr_slot_tx=0; int nr_frame_tx=0; uint64_t actual_payload=0,payload_received; + bool random_payload = true; int nr_bit=1; // maximum value possible is 2 uint8_t m0=0;// higher layer paramater initial cyclic shift uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 @@ -317,6 +318,7 @@ int main(int argc, char **argv) break; case 'B': actual_payload=atoi(optarg); + random_payload = false; break; case 'T': //nacktoack_flag=(uint8_t)atoi(optarg); @@ -379,6 +381,10 @@ int main(int argc, char **argv) int do_DTX=0; if ((format < 2) && (actual_payload == 4)) do_DTX=1; + if (random_payload) { + srand(time(NULL)); // Initialization, should only be called once. + actual_payload = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX. + } actual_payload &= ((1<>1)^(!harq_list[1].harq_value))); + ack_nack_errors+=(((actual_payload&1)^(!harq_list[1].harq_value))+((actual_payload>>1)^(!harq_list[0].harq_value))); else if ((!confidence_lvl && !harq_list[0].harq_value) || (!confidence_lvl && nr_bit == 2 && !harq_list[1].harq_value)) ack_nack_errors++; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 367b71fed5..0a19c953f8 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -37,6 +37,8 @@ #include "f1ap_du_interface_management.h" #include "assertions.h" +#include "GNB_APP/gnb_paramdef.h" + int to_NRNRB(int nrb) { for (int i=0; iextensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; - asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, SliceSupport_item); - INT8_TO_OCTET_STRING(1,&SliceSupport_item->sNSSAI.sST); - asn1cCalloc(SliceSupport_item->sNSSAI.sD, tmp); - INT24_TO_OCTET_STRING(10203,tmp); - //INT24_TO_OCTET_STRING(1,tmp); - + /* get list of sst/sd from configuration file */ + paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC; + paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0}; + char sstr[100]; + /* TODO: be sure that %d in the line below is at the right place */ + sprintf(sstr, "%s.[%d].%s.[0]", GNB_CONFIG_STRING_GNB_LIST, i, GNB_CONFIG_STRING_PLMN_LIST); + config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), sstr); + AssertFatal(SNSSAIParamList.numelt > 0, "no slice configuration found (snssaiList in the configuration file)\n"); + AssertFatal(SNSSAIParamList.numelt <= 1024, "maximum size for slice support list is 1024, see F1AP 38.473 9.3.1.37\n"); + for (int s = 0; s < SNSSAIParamList.numelt; s++) { + uint32_t sst; + uint32_t sd; + bool has_sd; + sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + has_sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0xffffff; + asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice); + INT8_TO_OCTET_STRING(sst, &slice->sNSSAI.sST); + if (has_sd) { + sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + asn1cCalloc(slice->sNSSAI.sD, tmp); + INT24_TO_OCTET_STRING(sd, tmp); + } + } + if (f1ap_req(false, instance)->fdd_flag) { // FDD nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index f8cf216220..ac952e0498 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -96,15 +96,6 @@ void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_dat AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) { - openAddr_t tmp= {0}; - strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); - strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); - sprintf(tmp.originService, "%d", DUport); - sprintf(tmp.destinationService, "%d", CUport); - return gtpv1Init(tmp); -} - void *F1AP_DU_task(void *arg) { //sctp_cu_init(); LOG_I(F1AP, "Starting F1AP at DU\n"); @@ -126,15 +117,6 @@ void *F1AP_DU_task(void *arg) { LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg); createF1inst(false, myInstance, msgSetup); - getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, //"172.21.6.9", //"172.21.10.9",//"172.21.9.5", //msgSetup->CU_f1_ip_address.ipv4_address, //"192.168.18.91" - msgSetup->CUport, - msgSetup->DU_f1_ip_address.ipv4_address, - msgSetup->DUport); - AssertFatal(getCxt(DUtype, myInstance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - extern instance_t legacyInstanceMapping; - legacyInstanceMapping = DUuniqInstance = getCxt(DUtype, myInstance)->gtpInst; du_task_send_sctp_association_req(myInstance,msgSetup); break; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index cb15862921..c37e2cfdc6 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -1078,6 +1078,17 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_remove_ue(DUtype, instance, cplt->rnti); return 0; } + +static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) +{ + openAddr_t tmp; + strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); + strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); + sprintf(tmp.originService, "%d", DUport); + sprintf(tmp.destinationService, "%d", CUport); + return gtpv1Init(tmp); +} + int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, @@ -1160,6 +1171,26 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; + extern instance_t DUuniqInstance; + if (DUuniqInstance == 0) { + char gtp_tunnel_ip_address[128]; + sprintf(gtp_tunnel_ip_address, "%d.%d.%d.%d", + drb_p->up_ul_tnl[0].tl_address & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 8) & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 16) & 0xff, + (drb_p->up_ul_tnl[0].tl_address >> 24) & 0xff); + getCxt(DUtype, instance)->gtpInst=du_create_gtpu_instance_to_cu( + gtp_tunnel_ip_address, + getCxt(false,instance)->setupReq.CUport, + getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + getCxt(false,instance)->setupReq.DUport); + AssertFatal(getCxt(DUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); + // Fixme: fully inconsistent instances management + // dirty global var is a bad fix + extern instance_t legacyInstanceMapping; + legacyInstanceMapping = DUuniqInstance = getCxt(DUtype, instance)->gtpInst; + } + switch (drbs_tobesetupmod_item_p->rLCMode) { case F1AP_RLCMode_rlc_am: drb_p->rlc_mode = RLC_MODE_AM; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a85840a38b..92255f065a 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -83,6 +83,7 @@ #include "NR_EUTRA-MBSFN-SubframeConfig.h" #include "RRC/NR/MESSAGES/asn1_msg.h" +#include "RRC/NR/nr_rrc_extern.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" extern uint16_t sf_ahead; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c index 4d7335713a..b4bb72dd31 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c @@ -27,7 +27,6 @@ #include "common/utils/nr/nr_common.h" #include -#include "PHY/defs_nr_common.h" //Table 5.1.2.2-2 uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824}; @@ -48,7 +47,8 @@ uint32_t nr_compute_tbs(uint16_t Qm, LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl); - const uint32_t nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; + const int nb_subcarrier_per_rb = 12; + const uint32_t nbp_re = nb_subcarrier_per_rb * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; const uint32_t nb_re = min(156, nbp_re) * nb_rb; // Intermediate number of information bits // Rx1024 is tabulated as 10 times the actual code rate diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 253b85cfce..d0ad07721c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1386,7 +1386,7 @@ int64_t *get_prach_config_info(frequency_range_t freq_range, void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, - NR_SearchSpace_t *ss, + const NR_SearchSpace_t *ss, int L) { AssertFatal(L>=1 && L<=16,"L %d not ok\n",L); *nr_of_candidates = 0; @@ -3931,7 +3931,7 @@ uint8_t get_BG(uint32_t A, uint16_t R) { return 1; } -uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti) { +uint32_t get_Y(const NR_SearchSpace_t *ss, int slot, rnti_t rnti) { if(ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) return 0; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e3ad29b43f..507d4469a5 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -50,7 +50,7 @@ typedef enum { typeB = 1 } mappingType_t; -uint32_t get_Y(NR_SearchSpace_t *ss, int slot, rnti_t rnti); +uint32_t get_Y(const NR_SearchSpace_t *ss, int slot, rnti_t rnti); uint8_t get_BG(uint32_t A, uint16_t R); @@ -90,7 +90,7 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP, void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, - NR_SearchSpace_t *ss, + const NR_SearchSpace_t *ss, int maxL); void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2804a9ec1e..909a0428d4 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -632,7 +632,6 @@ int nr_rrc_mac_config_req_ue( build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); if (!get_softmodem_params()->emulate_l1) mac->if_module->phy_config_request(&mac->phy_config); - mac->common_configuration_complete = 1; } if(scell_group_config != NULL ){ mac->cg = scell_group_config; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 51711e70f0..e5fe2e377f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -38,9 +38,6 @@ #include #include "platform_types.h" -/* PHY */ -#include "PHY/defs_nr_common.h" - /* IF */ #include "NR_IF_Module.h" #include "fapi_nr_ue_interface.h" @@ -64,10 +61,7 @@ #include "NR_CellGroupConfig.h" #include "NR_ServingCellConfig.h" #include "NR_MeasConfig.h" -#include "fapi_nr_ue_interface.h" -#include "NR_IF_Module.h" -#include "PHY/defs_nr_common.h" -#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" + // ========== // NR UE defs @@ -242,6 +236,31 @@ typedef enum { RA_FAILED = 5 } RA_state_t; +typedef struct { + /// PRACH format retrieved from prach_ConfigIndex + uint16_t prach_format; + /// Preamble Tx Counter + uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; + /// Preamble Power Ramping Counter + uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; + /// 2-step RA power offset + int POWER_OFFSET_2STEP_RA; + /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step. + int ra_PREAMBLE_RECEIVED_TARGET_POWER; + /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex + uint8_t ra_TDD_map_index; + /// RA Preamble Power Ramping Step in dB + uint32_t RA_PREAMBLE_POWER_RAMPING_STEP; + /// + uint8_t RA_PREAMBLE_BACKOFF; + /// + uint8_t RA_SCALING_FACTOR_BI; + /// Indicating whether it is 2-step or 4-step RA + nr_ra_type_e RA_TYPE; + /// UE configured maximum output power + int RA_PCMAX; +} NR_PRACH_RESOURCES_t; + typedef struct { // pointer to RACH config dedicated @@ -302,6 +321,8 @@ typedef struct { /// RA SearchSpace NR_SearchSpace_t *ss; + + NR_PRACH_RESOURCES_t prach_resources; } RA_config_t; typedef struct { @@ -344,6 +365,14 @@ typedef struct { int8_t delta_pucch; } PUCCH_sched_t; +typedef struct { + + uint32_t ssb_index; + /// SSB RSRP in dBm + short ssb_rsrp_dBm; + +} NR_PHY_meas_t; + /*!\brief Top level UE MAC structure */ typedef struct { @@ -355,7 +384,7 @@ typedef struct { NR_CSI_ReportConfig_t *csirc; long physCellId; //// MAC config - int common_configuration_complete; + int first_sync_frame; NR_DRX_Config_t *drx_Config; NR_SchedulingRequestConfig_t *schedulingRequestConfig; NR_BSR_Config_t *bsr_Config; @@ -396,8 +425,6 @@ typedef struct { RA_config_t ra; /// SSB index from MIB decoding uint8_t mib_ssb; - /// measured SSB RSRP in dBm - short ssb_rsrp_dBm; nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; @@ -433,6 +460,8 @@ typedef struct { uint16_t nr_band; uint8_t ssb_subcarrier_offset; + NR_PHY_meas_t phy_measurements; + dci_pdu_rel15_t def_dci_pdu_rel15[8]; // Defined for abstracted mode diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6d7eeb4b38..97deda6d81 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -309,6 +309,7 @@ void select_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch); int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, + int scs, NR_PUCCH_Config_t *pucch_Config, PUCCH_sched_t *pucch, uint8_t format_type, @@ -392,6 +393,8 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot); +void nr_get_RA_window(NR_UE_MAC_INST_t *mac); + /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. 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 @@ -403,8 +406,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 @param gNB_id gNB index @param nr_slot_tx slot for PRACH transmission @returns indication to generate PRACH to phy */ -uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, - fapi_nr_ul_config_prach_pdu *prach_pdu, +uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, frame_t frame, @@ -424,7 +426,17 @@ void nr_get_prach_resources(module_id_t mod_id, fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); -void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); +void init_RA(module_id_t mod_id, + NR_PRACH_RESOURCES_t *prach_resources, + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric, + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated); + +int16_t get_prach_tx_power(module_id_t mod_id); + +void set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu); + +void nr_Msg1_transmitted(module_id_t mod_id); void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); @@ -451,6 +463,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); +int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm); + // 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 diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 524c3b3fcd..d7162d9bf1 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -35,8 +35,6 @@ #include "radio/COMMON/common_lib.h" //#undef MALLOC #include "assertions.h" -#include "PHY/types.h" -#include "PHY/defs_UE.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "executables/softmodem-common.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" @@ -52,12 +50,12 @@ 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); + nr_ue_mac_inst->first_sync_frame = -1; for (int j=0;jscell_group_config) { nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c deleted file mode 100644 index 2d704b5c81..0000000000 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 - */ - -/*! \file nr_l1_helper.c -* \brief PHY/MAC helper functions -* \author Guido Casati -* \date 2019 -* \version 2.0 -* \email guido.casati@iis.fraunhofer.de -* @ingroup _mac - -*/ - -#include "PHY/defs_nr_common.h" -//#include "PHY/impl_defs_top.h" - -#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" - -// Implementation of 6.2.4 Configured ransmitted power -// 3GPP TS 38.101-1 version 16.5.0 Release 16 -// - -// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot. -// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c -// - -// Measurement units: -// - p_max: dBm -// - delta_TC_c: dB -// - P_powerclass: dBm -// - delta_P_powerclass: dB -// - MPR_c: dB -// - delta_MPR_c: dB -// - delta_T_IB_c dB -// - delta_rx_SRS dB -// note: -// - Assuming: -// -- Powerclass 3 capable UE (which is default power class unless otherwise stated) -// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations -// -- no additional MPR (A_MPR_c) -// todo: -// - in current implementation delta_P_powerclass is not handling power classes different from 3 -long nr_get_Pcmax(module_id_t mod_id){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] : - *mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; - NR_P_Max_t p_max = 0; - uint8_t P_powerclass = 23; - uint8_t delta_P_powerclass = 0; - uint8_t MPR_c = 1.5; - uint8_t delta_MPR_c = 0; - uint8_t A_MPR_c = 0; - uint8_t delta_T_IB_c = 0; - uint8_t delta_TC_c = 0; - uint8_t delta_rx_SRS = 0; - uint8_t P_MPR_c = 0; - long P_cmax_l = 0; - long P_cmax_h = 0; - long P_cmax = 0; - - if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){ - delta_MPR_c = 0.5; - } - - if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){ - if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){ - // TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation - delta_P_powerclass = -3; - p_max += 3; - } - } - - NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max; - if (p_Max){ - - p_max += *p_Max; - - LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max); - - P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c)); - - P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass); - - } else { - - P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c); - - P_cmax_h = P_powerclass - delta_P_powerclass; - - } - - P_cmax = (P_cmax_h + P_cmax_l) / 2; - - LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h); - - return P_cmax; - -} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h deleted file mode 100644 index 3bfeb29e2e..0000000000 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 - */ - -/** \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 00117ec4ad..84d917e366 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -34,18 +34,102 @@ #include "NR_RACH-ConfigCommon.h" #include "RRC/NR_UE/rrc_proto.h" -/* PHY */ -#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 -void nr_get_RA_window(NR_UE_MAC_INST_t *mac); +// Implementation of 6.2.4 Configured ransmitted power +// 3GPP TS 38.101-1 version 16.5.0 Release 16 +// - +// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot. +// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c +// - +// Measurement units: +// - p_max: dBm +// - delta_TC_c: dB +// - P_powerclass: dBm +// - delta_P_powerclass: dB +// - MPR_c: dB +// - delta_MPR_c: dB +// - delta_T_IB_c dB +// - delta_rx_SRS dB +// note: +// - Assuming: +// -- Powerclass 3 capable UE (which is default power class unless otherwise stated) +// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations +// -- no additional MPR (A_MPR_c) +// todo: +// - in current implementation delta_P_powerclass is not handling power classes different from 3 +long nr_get_Pcmax(module_id_t mod_id){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] : + *mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR; + NR_P_Max_t p_max = 0; + uint8_t P_powerclass = 23; + uint8_t delta_P_powerclass = 0; + uint8_t MPR_c = 1.5; + uint8_t delta_MPR_c = 0; + uint8_t A_MPR_c = 0; + uint8_t delta_T_IB_c = 0; + uint8_t delta_TC_c = 0; + uint8_t delta_rx_SRS = 0; + uint8_t P_MPR_c = 0; + long P_cmax_l = 0; + long P_cmax_h = 0; + long P_cmax = 0; + + if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){ + delta_MPR_c = 0.5; + } + + if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){ + if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){ + // TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation + delta_P_powerclass = -3; + p_max += 3; + } + } + + NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max; + if (p_Max){ + + p_max += *p_Max; + + LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max); + + P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c)); + + P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass); + + } else { + + P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c); + + P_cmax_h = P_powerclass - delta_P_powerclass; + + } + + P_cmax = (P_cmax_h + P_cmax_l) / 2; + + LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h); + + return P_cmax; + +} + +int16_t get_prach_tx_power(module_id_t mod_id) { + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm); + int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); + return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); + +} // Random Access procedure initialization as per 5.1.1 and initialization of variables specific // to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16) @@ -527,7 +611,6 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r((unsigned int *)seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); } } - prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex; } // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) @@ -537,7 +620,7 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t // - f_id: index of the PRACH occasion in the frequency domain // - s_id is starting symbol of the PRACH occasion [0...14] // - t_id is the first slot of the PRACH occasion in a system frame [0...80] -uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu){ +void set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu){ RA_config_t *ra = &mac->ra; uint8_t ul_carrier_id = 0; // NUL @@ -548,9 +631,6 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p ra->ra_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; LOG_D(MAC, "Computed ra_RNTI is %x \n", ra->ra_rnti); - - return ra->ra_rnti; - } // This routine implements Section 5.1.2 (UE Random Access Resource Selection) @@ -563,12 +643,12 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p // -- else if CSI-RS is selected above // - switch initialisation cases // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) -// --- SSB selection, set prach_resources->ra_PreambleIndex +// --- SSB selection, set ra_PreambleIndex // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 // --- set PREAMBLE_INDEX to ra_preamble_index // --- select the SSB signalled by PDCCH // -- RA initiated for SI request: -// --- SSB selection, set prach_resources->ra_PreambleIndex +// --- SSB selection, set ra_PreambleIndex // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission // - Contention-based RA preamble selection: @@ -578,7 +658,7 @@ void nr_get_prach_resources(module_id_t mod_id, uint8_t gNB_id, NR_PRACH_RESOURCES_t *prach_resources, fapi_nr_ul_config_prach_pdu *prach_pdu, - NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; @@ -593,27 +673,26 @@ void nr_get_prach_resources(module_id_t mod_id, if (rach_ConfigDedicated->cfra){ uint8_t cfra_ssb_resource_idx = 0; 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); + LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, ra->ra_PreambleIndex, cfra_ssb_resource_idx); } } else { /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */ - int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? get_nr_PL(mod_id, CC_id, gNB_id) : 0; + int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0; ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu); ra_preambles_config(prach_resources, mac, dl_pathloss); - LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex); + LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex); } if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); - prach_resources->ra_RNTI = set_ra_rnti(mac, prach_pdu); } // TbD: RA_attempt_number not used -void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ +void nr_Msg1_transmitted(module_id_t mod_id){ + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; ra->ra_state = WAIT_RAR; @@ -659,8 +738,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot * @gNB_id gNB ID * @nr_slot_tx current UL TX slot */ -uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, - fapi_nr_ul_config_prach_pdu *prach_pdu, +uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, frame_t frame, @@ -669,34 +747,29 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); RA_config_t *ra = &mac->ra; - NR_RACH_ConfigCommon_t *setup; - if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - else setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; + NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side - if (!prach_resources->init_msg1) { - if ((mac->common_configuration_complete > 0 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) && - ((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150) { - prach_resources->init_msg1 = 1; + if (ra->ra_state == RA_UE_IDLE) { + if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) && + ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) { + ra->ra_state = GENERATE_PREAMBLE; } else { - LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame); + LOG_D(NR_MAC,"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame); return 0; } } - LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: init_msg1 %d, ra_state %d, RA_active %d\n", + LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: ra_state %d, RA_active %d\n", __FUNCTION__, mod_id, frame, nr_slot_tx, - prach_resources->init_msg1, ra->ra_state, ra->RA_active); - if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) { + if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) { if (ra->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ @@ -775,17 +848,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } - if (size_sdu > 0 && (ra->generate_nr_prach == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) { + if (size_sdu > 0 && (ra->ra_state == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) { LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); - // Init RA procedure - init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); - nr_get_RA_window(mac); - // Fill in preamble and PRACH resources - if (ra->generate_nr_prach == GENERATE_PREAMBLE) - nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); - // Padding: fill remainder with 0 if (TBS_max - ra->Msg3_size > 0) { AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); @@ -868,12 +934,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE); - if(ra->generate_nr_prach != GENERATE_IDLE) { - return ra->generate_nr_prach; - } else { - return ra->ra_state; - } - + return ra->generate_nr_prach; } void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index be4bc4b362..f5d694d98f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -374,7 +374,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, else ssb_sc_offset_norm = ssb_subcarrier_offset; - if (mac->common_configuration_complete == 0) + if (mac->first_sync_frame == -1) nr_ue_sib1_scheduler(module_id, cc_id, ssb_start_symbol, @@ -394,6 +394,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, mac->dl_config_request.sfn = frame; mac->dl_config_request.slot = ssb_start_symbol/14; + if (mac->first_sync_frame == -1) + mac->first_sync_frame = frame; return 0; } @@ -1744,16 +1746,17 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, } pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac, + scs, pucch_Config, pucch, pucch_pdu->format_type, pucch_pdu->prb_size, pucch_pdu->freq_hop_flag, pucch_pdu->add_dmrs_flag, - pucch_pdu->nr_of_symbols, - subframe_number, - O_ACK, O_SR, - O_CSI, O_CRC); + pucch_pdu->nr_of_symbols, + subframe_number, + O_ACK, O_SR, + O_CSI, O_CRC); } else AssertFatal(1==0,"problem with pucch configuration\n"); @@ -1793,6 +1796,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, + int scs, NR_PUCCH_Config_t *pucch_Config, PUCCH_sched_t *pucch, uint8_t format_type, @@ -1899,10 +1903,13 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, return (PUCCH_POWER_DEFAULT); } - int16_t pucch_power = P_O_PUCCH + delta_F_PUCCH + DELTA_TF + G_b_f_c; + int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm); + int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs))); + + int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c; NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n", - pucch_power, contributor, PL, delta_F_PUCCH, DELTA_TF, G_b_f_c); + pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c); return (pucch_power); } @@ -2635,7 +2642,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, } } AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n"); - ssb_rsrp[1][0] = mac->ssb_rsrp_dBm; + ssb_rsrp[1][0] = mac->phy_measurements.ssb_rsrp_dBm; uint8_t ssbi; @@ -4223,5 +4230,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t } return ret; +} +// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission +// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 +// Assumptions: +// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE +// Measurement units: +// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) +int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) +{ + + long referenceSignalPower; + //TODO improve PL measurements. Probably not correct as it is. + if (mac->scc) + referenceSignalPower = mac->scc->ss_PBCH_BlockPower; + else + referenceSignalPower = mac->scc_SIB->ss_PBCH_BlockPower; + + int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm); + + LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", + pathloss, + referenceSignalPower, + pow(10, referenceSignalPower/10), + ssb_rsrp_dBm, + pow(10, ssb_rsrp_dBm/10)); + + return pathloss; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 7f6da1b915..903b20b037 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2699,11 +2699,14 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s (int)slotP, &prach_occasion_info_p); - if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) { + if (is_nr_prach_slot && ra->ra_state == GENERATE_PREAMBLE) { AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); ra->generate_nr_prach = GENERATE_PREAMBLE; + init_RA(module_idP, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated); + nr_get_RA_window(mac); + format = prach_occasion_info_p->format; format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format @@ -2733,7 +2736,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s prach_config_pdu->restricted_set = prach_config->restricted_set_config; prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; - LOG_D(NR_MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); + LOG_D(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", + frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ronb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) { @@ -2796,9 +2800,16 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s } } // if format1 + nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, prach_config_pdu, ra->rach_ConfigDedicated); + prach_config_pdu->ra_PreambleIndex = ra->ra_PreambleIndex; + prach_config_pdu->prach_tx_power = get_prach_tx_power(module_idP); + set_ra_rnti(mac, prach_config_pdu); + fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, NULL); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); + + nr_Msg1_transmitted(module_idP); } // is_nr_prach_slot } // if is_nr_UL_slot } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 3af6089487..d61adf5d3d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -792,20 +792,13 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t } uint8_t aggregation_level; - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss, 1<0) break; - } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - int CCEIndex = find_pdcch_candidate(nr_mac, - CC_id, - aggregation_level, - nr_of_candidates, - &ra->sched_pdcch, - coreset, - 0); + int CCEIndex = get_cce_index(nr_mac, + CC_id, slot, 0, + &aggregation_level, + ss, + coreset, + &ra->sched_pdcch, + true); if (CCEIndex < 0) { LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti); return; @@ -947,7 +940,7 @@ void nr_get_Msg3alloc(module_id_t module_id, tdd_beam_association[num_tdd_period] = ra->beam_id; } - LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id); + LOG_I(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id); uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; @@ -1188,21 +1181,13 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } uint8_t aggregation_level; - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss, 1<0) break; - } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - - int CCEIndex = find_pdcch_candidate(nr_mac, - CC_id, - aggregation_level, - nr_of_candidates, - &ra->sched_pdcch, - coreset, - 0); + int CCEIndex = get_cce_index(nr_mac, + CC_id, slotP, 0, + &aggregation_level, + ss, + coreset, + &ra->sched_pdcch, + true); if (CCEIndex < 0) { LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti); @@ -1414,10 +1399,16 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_ControlResourceSet_t *coreset = ra->coreset; AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); + uint16_t mac_sdu_length = 0; + rnti_t tc_rnti = ra->rnti; // If UE is known by the network, C-RNTI to be used instead of TC-RNTI - if(ra->msg3_dcch_dtch) { + if (ra->msg3_dcch_dtch) { ra->rnti = ra->crnti; + } else { + mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, NULL); + if (mac_sdu_length <= 0) + return; // need to wait until RRCSetup is encoded } NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti); @@ -1426,10 +1417,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra return; } - if(UE->enc_rval.encoded <= 0) return; // need to wait until RRCSetup is encoded - - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - long BWPStart = 0; long BWPSize = 0; NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; @@ -1444,31 +1431,75 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // get CCEindex, needed also for PUCCH and then later for PDCCH uint8_t aggregation_level; - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss, 1<0) break; - } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - - int CCEIndex = find_pdcch_candidate(nr_mac, - CC_id, - aggregation_level, - nr_of_candidates, - &ra->sched_pdcch, - coreset, - 0); + int CCEIndex = get_cce_index(nr_mac, + CC_id, slotP, 0, + &aggregation_level, + ss, + coreset, + &ra->sched_pdcch, + true); if (CCEIndex < 0) { LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI 0x%04x!\n", __func__, ra->rnti); return; } + // Checking if the DCI allocation is feasible in current subframe + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { + LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); + return; + } + + uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); + NR_tda_info_t msg4_tda = nr_get_pdsch_tda_info(dl_bwp, time_domain_assignment); + NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, + dl_bwp, + &msg4_tda, + 1); + + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; + uint8_t mcsIndex = 0; + int rbStart = 0; + int rbSize = 0; + uint8_t tb_scaling = 0; + uint32_t tb_size = 0; + uint8_t subheader_len = (mac_sdu_length < 256) ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG); + uint16_t pdu_length = mac_sdu_length + subheader_len + 7; //7 is contetion resolution length + uint16_t *vrb_map = cc[CC_id].vrb_map; + // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size + do { + if(rbSize < BWPSize) + rbSize++; + else + mcsIndex++; + LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); + tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), + nr_get_code_rate_dl(mcsIndex, mcsTableIdx), + rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; + } while (tb_size < pdu_length && mcsIndex<=28); + + AssertFatal(tb_size >= pdu_length,"Cannot allocate Msg4\n"); + + int i = 0; + while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { + if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) { + rbStart += i+1; + i = 0; + } else { + i++; + } + } + + if (rbStart > (BWPSize - rbSize)) { + LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, ra->rnti); + return; + } + const int delta_PRI=0; int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); - LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI); + LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); if (alloc<0) { @@ -1478,6 +1509,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti); + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ int current_harq_pid = sched_ctrl->retrans_dl_harq.head; // HARQ management @@ -1501,6 +1533,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; harq->feedback_slot = pucch->ul_slot; harq->feedback_frame = pucch->frame; + harq->tb_size = tb_size; uint8_t *buf = (uint8_t *) harq->transportBlock; // Bytes to be transmitted @@ -1534,56 +1567,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } } - uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP); - NR_tda_info_t msg4_tda = nr_get_pdsch_tda_info(dl_bwp, time_domain_assignment); - NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, - dl_bwp, - &msg4_tda, - 1); - - uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; - uint8_t mcsIndex = 0; - int rbStart = 0; - int rbSize = 0; - uint8_t tb_scaling = 0; - uint16_t *vrb_map = cc[CC_id].vrb_map; - // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size - do { - if(rbSize < BWPSize) - rbSize++; - else - mcsIndex++; - LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); - harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), - nr_get_code_rate_dl(mcsIndex, mcsTableIdx), - rbSize, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, tb_scaling,1) >> 3; - } while (harq->tb_size < ra->mac_pdu_length && mcsIndex<=28); - - AssertFatal(harq->tb_size >= ra->mac_pdu_length,"Cannot allocate Msg4\n"); - - int i = 0; - while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) { - if (vrb_map[BWPStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) { - rbStart += i+1; - i = 0; - } else { - i++; - } - } - - if (rbStart > (BWPSize - rbSize)) { - LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, ra->rnti); - return; - } - - // Checking if the DCI allocation is feasible in current subframe - nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { - LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti); - return; - } - - // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them const int coresetid = coreset->controlResourceSetId; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index adba522db9..af76867ef3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -385,6 +385,7 @@ bool allocate_dl_retransmission(module_id_t module_id, NR_UE_info_t *UE, int current_harq_pid) { + int CC_id = 0; gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; @@ -400,11 +401,11 @@ bool allocate_dl_retransmission(module_id_t module_id, int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index; const int coresetid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : dl_bwp->BWPSize; + const uint16_t bwpSize = coresetid == 0 ? nr_mac->cset0_bwp_size : dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart int rbSize = 0; - const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); + const int tda = get_dl_tda(nr_mac, scc, slot); AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); if (tda == retInfo->time_domain_allocation && @@ -476,28 +477,13 @@ bool allocate_dl_retransmission(module_id_t module_id, } /* Find a free CCE */ - - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); - uint8_t nr_of_candidates; - - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - - int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], - /* CC_id = */ 0, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(nr_mac, + CC_id, slot, UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); if (CCEIndex<0) { LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission RNTI %04x\n", frame, slot, UE->rnti); @@ -519,7 +505,7 @@ bool allocate_dl_retransmission(module_id_t module_id, } sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(RC.nrmac[module_id], + fill_pdcch_vrb_map(nr_mac, /* CC_id = */ 0, &sched_ctrl->sched_pdcch, CCEIndex, @@ -560,6 +546,7 @@ void pf_dl(module_id_t module_id, UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; int remainUEs = max_num_ue; int curUE = 0; + int CC_id = 0; /* Loop UE_info->list to check retransmission */ UE_iterator(UE_list, UE) { @@ -569,7 +556,8 @@ void pf_dl(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure==1) + continue; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; @@ -580,6 +568,9 @@ void pf_dl(module_id_t module_id, const uint32_t b = UE->mac_stats.dl.current_bytes; UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b; + if (remainUEs == 0) + continue; + /* retransmission */ if (sched_pdsch->dl_harq_pid >= 0) { /* Allocate retransmission */ @@ -589,15 +580,9 @@ void pf_dl(module_id_t module_id, LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot); continue; } - /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - if (remainUEs == 0) - return; - } else { /* skip this UE if there are no free HARQ processes. This can happen e.g. * if the UE disconnected in L2sim, in which case the gNB is not notified @@ -659,7 +644,7 @@ void pf_dl(module_id_t module_id, const int coresetid = sched_ctrl->coreset->controlResourceSetId; const uint16_t bwpSize = coresetid == 0 ? - RC.nrmac[module_id]->cset0_bwp_size : + mac->cset0_bwp_size : dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart @@ -669,28 +654,13 @@ void pf_dl(module_id_t module_id, continue; } - /* Find a free CCE */ - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, iterator->UE->rnti); - uint8_t nr_of_candidates; - - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - - int CCEIndex = find_pdcch_candidate(mac, - /* CC_id = */ 0, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(mac, + CC_id, slot, iterator->UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); if (CCEIndex<0) { LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI RNTI %04x\n", frame, slot, rnti); iterator++; @@ -722,7 +692,7 @@ void pf_dl(module_id_t module_id, /* MCS has been set above */ NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], scc, slot); + sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); sched_pdsch->tda_info = nr_get_pdsch_tda_info(dl_bwp, sched_pdsch->time_domain_allocation); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6238016cb3..9f78ac06c1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -250,27 +250,13 @@ void nr_preprocessor_phytest(module_id_t module_id, 0); sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); - - int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], - CC_id, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(RC.nrmac[module_id], + CC_id, slot, UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); AssertFatal(CCEIndex >= 0, "%s(): could not find CCE for UE %04x\n", __func__, @@ -412,27 +398,13 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); - - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); - - int CCEIndex = find_pdcch_candidate(nr_mac, - CC_id, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(nr_mac, + CC_id, slot, UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); if (CCEIndex < 0) { LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); return false; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ccdc8aca59..d85d8d85a1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -114,10 +114,6 @@ uint8_t nr_ss_first_symb_idx_scs_240_120_set1_mux2[6] = {0,1,2,3,0,1}; // Mux pattern type 3 uint8_t nr_ss_first_symb_idx_scs_120_120_mux3[4] = {4,8,2,6}; -/// Search space max values indexed by scs -uint8_t nr_max_number_of_candidates_per_slot[4] = {44, 36, 22, 20}; -uint8_t nr_max_number_of_cces_per_slot[4] = {56, 56, 48, 32}; - // CQI TABLES (10 times the value in 214 to adequately compare with R) // Table 1 (38.214 5.2.2.1-2) uint16_t cqi_table1[16][2] = {{0,0},{2,780},{2,1200},{2,1930},{2,3080},{2,4490},{2,6020},{4,3780}, @@ -132,16 +128,6 @@ uint16_t cqi_table3[16][2] = {{0,0},{2,300},{2,500},{2,780},{2,1200},{2,1930},{2 {2,6020},{4,3780},{4,4900},{4,6160},{6,4660},{6,5670},{6,6660},{6,7720}}; -static inline uint8_t get_max_candidates(uint8_t scs) { - AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs); - return (nr_max_number_of_candidates_per_slot[scs]); -} - -static inline uint8_t get_max_cces(uint8_t scs) { - AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs); - return (nr_max_number_of_cces_per_slot[scs]); -} - uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format) { @@ -431,16 +417,15 @@ NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, return pdcch; } - -int find_pdcch_candidate(gNB_MAC_INST *mac, +int find_pdcch_candidate(const gNB_MAC_INST *mac, int cc_id, int aggregation, int nr_of_candidates, - NR_sched_pdcch_t *pdcch, - NR_ControlResourceSet_t *coreset, + const NR_sched_pdcch_t *pdcch, + const NR_ControlResourceSet_t *coreset, uint32_t Y){ - uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map; + const uint16_t *vrb_map = mac->common_channels[cc_id].vrb_map; const int N_ci = 0; const int N_rb = pdcch->n_rb; // nb of rbs of coreset per symbol @@ -475,6 +460,39 @@ int find_pdcch_candidate(gNB_MAC_INST *mac, return -1; } + +int get_cce_index(const gNB_MAC_INST *nrmac, + const int CC_id, + const int slot, + const rnti_t rnti, + uint8_t *aggregation_level, + const NR_SearchSpace_t *ss, + const NR_ControlResourceSet_t *coreset, + NR_sched_pdcch_t *sched_pdcch, + bool is_common) +{ + + const uint32_t Y = is_common ? 0 : get_Y(ss, slot, rnti); + uint8_t nr_of_candidates; + for (int i=0; i<5; i++) { + // for now taking the lowest value among the available aggregation levels + find_aggregation_candidates(aggregation_level, + &nr_of_candidates, + ss, + 1<0) + break; + } + int CCEIndex = find_pdcch_candidate(nrmac, + CC_id, + *aggregation_level, + nr_of_candidates, + sched_pdcch, + coreset, + Y); + return CCEIndex; +} + void fill_pdcch_vrb_map(gNB_MAC_INST *mac, int CC_id, NR_sched_pdcch_t *pdcch, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index b9373c85cb..2ff7196679 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -131,17 +131,22 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { }; -int get_pucch_index(int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size) +int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size) { // PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots // this functions return the index to the structure for slot passed to the function const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; - // ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in a TDD period - // ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods + const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period; + // (frame * n_ul_slots_frame) adds up the number of UL slots in the previous frames + const int frame_start = frame * n_ul_slots_frame; + // ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods of this frame + const int ul_period_start = (slot / nr_slots_period) * n_ul_slots_period; + // ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in this TDD period + const int ul_period_slot = (slot % nr_slots_period) - first_ul_slot_period; // the sum gives the index of current UL slot in the frame which is normalized wrt sched_pucch_size - return ((slot % nr_slots_period) - first_ul_slot_period + (slot / nr_slots_period) * n_ul_slots_period) % sched_pucch_size; + return (frame_start + ul_period_start + ul_period_slot) % sched_pucch_size; } @@ -159,7 +164,7 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n"); - const int pucch_index = get_pucch_index(slotP, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); + const int pucch_index = get_pucch_index(frameP, slotP, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index]; if (!curr_pucch->active) continue; @@ -226,7 +231,7 @@ void nr_csi_meas_reporting(int Mod_idP, const NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || RC.nrmac[Mod_idP]->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n"); - const int pucch_index = get_pucch_index(sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); + const int pucch_index = get_pucch_index(sched_frame, sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n"); curr_pucch->r_pucch = -1; @@ -1118,7 +1123,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, continue; const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f]) / n_slots_frame)) & 1023; // we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures - const int pucch_index = get_pucch_index(pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); + const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; if (curr_pucch->active && curr_pucch->frame == pucch_frame && @@ -1228,7 +1233,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); - const int pucch_index = get_pucch_index(slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); + const int pucch_index = get_pucch_index(SFN, slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; if (curr_pucch->active && diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 6c95048ce7..38da157a28 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -34,7 +34,6 @@ #include "common/utils/nr/nr_common.h" #include "utils.h" #include - #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" //#define SRS_IND_DEBUG @@ -1383,7 +1382,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, int *n_rb_sched, NR_UE_info_t* UE, int harq_pid, - const NR_SIB1_t *sib1, const NR_ServingCellConfigCommon_t *scc, const int tda) { @@ -1450,24 +1448,13 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, } /* Find a free CCE */ - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - int CCEIndex = find_pdcch_candidate(nrmac, - CC_id, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(nrmac, + CC_id, slot, UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); if (CCEIndex<0) { LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE->rnti); return false; @@ -1518,6 +1505,7 @@ static int comparator(const void *p, const void *q) { return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef; } + void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, @@ -1529,22 +1517,21 @@ void pf_ul(module_id_t module_id, const int CC_id = 0; gNB_MAC_INST *nrmac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const int min_rb = 5; // UEs that could be scheduled UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; - int remainUEs=max_num_ue; + int remainUEs = max_num_ue; int curUE=0; /* Loop UE_list to calculate throughput and coeff */ UE_iterator(UE_list, UE) { - if (UE->Msg4_ACKed != true) + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure == 1) continue; LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; int rbStart = 0; // wrt BWP start @@ -1558,13 +1545,16 @@ void pf_ul(module_id_t module_id, const uint32_t b = stats->current_bytes; UE->ul_thr_ue = (1 - a) * UE->ul_thr_ue + a * b; + if(remainUEs == 0) + continue; + /* Check if retransmission is necessary */ sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n",UE->rnti,sched_pusch->ul_harq_pid); if (sched_pusch->ul_harq_pid >= 0) { /* Allocate retransmission*/ const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); - bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, sib1, scc, tda); + bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, scc, tda); if (!r) { LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE->rnti); continue; @@ -1573,12 +1563,6 @@ void pf_ul(module_id_t module_id, /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; - - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - if (remainUEs == 0) - return; - continue; } @@ -1604,44 +1588,25 @@ void pf_ul(module_id_t module_id, if (bo->harq_round_max == 1) sched_pusch->mcs = max_mcs; else - sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame); + sched_pusch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->ul_bler_stats, max_mcs, frame); /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled * based on data to transmit) */ if (B == 0 && do_sched) { /* if no data, pre-allocate 5RB */ /* Find a free CCE */ - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) break; - } - int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], - CC_id, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); - + int CCEIndex = get_cce_index(nrmac, + CC_id, slot, UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); if (CCEIndex<0) { LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti); continue; } - /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ - remainUEs--; - - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - if (remainUEs == 0) - return; - sched_pusch->nrOfLayers = 1; sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_pusch->slot); sched_pusch->tda_info = nr_get_pusch_tda_info(current_BWP, sched_pusch->time_domain_allocation); @@ -1658,11 +1623,11 @@ void pf_ul(module_id_t module_id, if (rbStart + min_rb >= bwpSize) { LOG_W(NR_MAC, "cannot allocate continuous UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", UE->rnti,rbStart,min_rb,bwpSize); - return; + continue; } sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(RC.nrmac[module_id], + fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, @@ -1688,6 +1653,7 @@ void pf_ul(module_id_t module_id, for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap; + remainUEs--; continue; } @@ -1705,30 +1671,18 @@ void pf_ul(module_id_t module_id, qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator); UEsched_t *iterator=UE_sched; - const int min_rbSize = 5; /* Loop UE_sched to find max coeff and allocate transmission */ - while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) { + while (remainUEs> 0 && n_rb_sched >= min_rb && iterator->UE != NULL) { NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl; + int CCEIndex = get_cce_index(nrmac, + CC_id, slot, iterator->UE->rnti, + &sched_ctrl->aggregation_level, + sched_ctrl->search_space, + sched_ctrl->coreset, + &sched_ctrl->sched_pdcch, + false); - const uint32_t Y = get_Y(sched_ctrl->search_space, slot, iterator->UE->rnti); - uint8_t nr_of_candidates; - for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<0) - break; - } - int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], - CC_id, - sched_ctrl->aggregation_level, - nr_of_candidates, - &sched_ctrl->sched_pdcch, - sched_ctrl->coreset, - Y); if (CCEIndex<0) { LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, iterator->UE->rnti); iterator++; @@ -1738,7 +1692,6 @@ void pf_ul(module_id_t module_id, NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP; - const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->nrOfLayers = 1; @@ -1749,10 +1702,9 @@ void pf_ul(module_id_t module_id, &sched_pusch->tda_info, sched_pusch->nrOfLayers); - update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm); - int rbStart = 0; const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); + const uint16_t bwpSize = current_BWP->BWPSize; while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; sched_pusch->rbStart = rbStart; @@ -1763,7 +1715,7 @@ void pf_ul(module_id_t module_id, if (rbStart + min_rb >= bwpSize) { LOG_W(NR_MAC, "cannot allocate UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize); - return; + continue; } else LOG_D(NR_MAC,"allocating UL data for RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize); @@ -1771,24 +1723,24 @@ void pf_ul(module_id_t module_id, /* Calculate the current scheduling bytes */ const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); /* adjust rbSize and MCS according to PHR and BPRE */ - sched_pusch->mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + sched_pusch->mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; if(sched_ctrl->pcmax!=0 || sched_ctrl->ph!=0) // verify if the PHR related parameter have been initialized - nr_ue_max_mcs_min_rb(current_BWP->scs, sched_ctrl->ph, sched_pusch, current_BWP, min_rbSize, B, &max_rbSize, &sched_pusch->mcs); + nr_ue_max_mcs_min_rb(current_BWP->scs, sched_ctrl->ph, sched_pusch, current_BWP, min_rb, B, &max_rbSize, &sched_pusch->mcs); if (sched_pusch->mcs < sched_ctrl->ul_bler_stats.mcs) sched_ctrl->ul_bler_stats.mcs = sched_pusch->mcs; /* force estimated MCS down */ + update_ul_ue_R_Qm(sched_pusch->mcs, current_BWP->mcs_table, current_BWP->pusch_Config, &sched_pusch->R, &sched_pusch->Qm); uint16_t rbSize = 0; uint32_t TBS = 0; - nr_find_nb_rb(sched_pusch->Qm, sched_pusch->R, 1, // layers sched_pusch->tda_info.nrOfSymbols, sched_pusch->dmrs_info.N_PRB_DMRS * sched_pusch->dmrs_info.num_dmrs_symb, B, - min_rbSize, + min_rb, max_rbSize, &TBS, &rbSize); @@ -1802,7 +1754,7 @@ void pf_ul(module_id_t module_id, /* Mark the corresponding RBs as used */ sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(RC.nrmac[module_id], + fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 64f9882294..0d1e2fc3e0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -269,12 +269,12 @@ NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, NR_BWP_t *bwp, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); -int find_pdcch_candidate(gNB_MAC_INST *mac, +int find_pdcch_candidate(const gNB_MAC_INST *mac, int cc_id, int aggregation, int nr_of_candidates, - NR_sched_pdcch_t *pdcch, - NR_ControlResourceSet_t *coreset, + const NR_sched_pdcch_t *pdcch, + const NR_ControlResourceSet_t *coreset, uint32_t Y); void fill_pdcch_vrb_map(gNB_MAC_INST *mac, @@ -473,7 +473,15 @@ void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); -bool find_free_CCE(sub_frame_t slot, NR_UE_info_t *UE); +int get_cce_index(const gNB_MAC_INST *nrmac, + const int CC_id, + const int slot, + const rnti_t rnti, + uint8_t *aggregation_level, + const NR_SearchSpace_t *ss, + const NR_ControlResourceSet_t *coreset, + NR_sched_pdcch_t *sched_pdcch, + bool is_common); bool nr_find_nb_rb(uint16_t Qm, uint16_t R, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 1559f55a43..96a436ebc0 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -1085,6 +1085,12 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t } +void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm) +{ + mac->phy_measurements.ssb_index = ssb_index; + mac->phy_measurements.ssb_rsrp_dBm = rsrp_dbm; +} + // L2 Abstraction Layer // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ @@ -1223,7 +1229,9 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){ case FAPI_NR_RX_PDU_TYPE_SSB: - mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm; + handle_ssb_meas(mac, + (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index, + (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm); ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits, diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 67e06914ef..30067e921a 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -117,7 +117,8 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, const rb_id_t Srb_id, const rnti_t rnti, const uint8_t Nb_tb, - uint8_t *const buffer_pP ){ + uint8_t *const buffer_pP) +{ #ifdef DEBUG_RRC LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); @@ -162,19 +163,21 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, if ((Srb_id & RAB_OFFSET) == CCCH) { LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id); - char *payload_pP; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_idP], rnti); LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id); if (ue_context_p == NULL) { - LOG_E(NR_RRC,"[gNB %d] Frame %d CCCH request but no ue_context\n", Mod_idP, frameP); + if(buffer_pP != NULL) + LOG_E(NR_RRC,"[gNB %d] Frame %d CCCH request but no ue_context\n", Mod_idP, frameP); return 0; } uint16_t payload_size = ue_context_p->ue_context.Srb0.Tx_buffer.payload_size; + if (buffer_pP == NULL) + return payload_size; // check if data is there for MAC if (payload_size > 0) { - payload_pP = ue_context_p->ue_context.Srb0.Tx_buffer.Payload; + char *payload_pP = ue_context_p->ue_context.Srb0.Tx_buffer.Payload; LOG_D(NR_RRC,"[gNB %d] CCCH has %d bytes (dest: %p, src %p)\n", Mod_idP, payload_size, buffer_pP, payload_pP); // Fill buffer memcpy((void *)buffer_pP, (void*)payload_pP, payload_size); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 1c2f38069d..2729a78b33 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -75,7 +75,6 @@ #include "NR_DLInformationTransfer.h" #include "NR_RRCReestablishmentRequest.h" #include "NR_UE-CapabilityRequestFilterNR.h" -#include "PHY/defs_nr_common.h" #include "common/utils/nr/nr_common.h" #if defined(NR_Rel16) #include "NR_SCS-SpecificCarrier.h" @@ -1242,7 +1241,7 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr // DRB Configuration for (int i = bearer_id_start; i < bearer_id_start + nb_bearers_to_setup; i++ ){ const NR_RLC_Config_PR rlc_conf = use_rlc_um_for_drb ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am; - NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + i, i, rlc_conf, priority[i-bearer_id_start]); + NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + i, i, rlc_conf, priority[i-1]); ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig); } diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 3b08a24027..af2cfdd2c8 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -35,6 +35,8 @@ #include "LAYER2/MAC/mac.h" #include "LAYER2/RLC/rlc.h" +#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits. + extern UE_RRC_INST *UE_rrc_inst; extern uint8_t DRB2LCHAN[8]; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fdd6fb9544..bf84cf0c2e 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -784,7 +784,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( int qos_flow_index = 0; int pdu_sessions_done = 0; int i; - uint8_t drb_id_to_setup_start = 1; + uint8_t drb_id_to_setup_start = 0; uint8_t nb_drb_to_setup = rrc->configuration.drbs; long drb_priority[NGAP_MAX_DRBS_PER_UE]; NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -903,6 +903,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering); + if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); } @@ -3238,9 +3239,6 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha } } - uint8_t drb_id_to_setup_start = 0; - uint8_t nb_drb_to_setup = 0; - long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) /* Configure SRB2 */ NR_SRB_ToAddMod_t *SRB2_config = NULL; @@ -3264,6 +3262,9 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha /* Configure DRB */ NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList = NULL; + uint8_t drb_id_to_setup_start = 0; + uint8_t nb_drb_to_setup = 0; + long drb_priority[1] = {13}; // For now, we assume only one drb per pdu session with a default priority (will be dynamic in future) if(req->drbs_to_be_setup_length>0){ if(ue_context_p->ue_context.DRB_configList == NULL){ ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); @@ -3273,13 +3274,13 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha for (int i=0; idrbs_to_be_setup_length; i++){ DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; + if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config); f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; transport_layer_addr_t addr; memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; extern instance_t DUuniqInstance; - if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; incoming_teid = newGtpuCreateTunnel(DUuniqInstance, req->rnti, drb_p.drb_id, @@ -3407,6 +3408,8 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co /* Configure DRB */ NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList = NULL; + int drb_id_to_setup_start = 0; + long drb_priority[1] = {13}; // For now, we assume only one drb per pdu session with a default priority (will be dynamic in future) if(req->drbs_to_be_setup_length>0){ if(ue_context_p->ue_context.DRB_configList == NULL){ ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); @@ -3415,12 +3418,14 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co for (int i=0; idrbs_to_be_setup_length; i++){ DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; + if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config); f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; transport_layer_addr_t addr; memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; extern instance_t DUuniqInstance; + if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; incoming_teid = newGtpuCreateTunnel(DUuniqInstance, req->rnti, drb_p.drb_id, @@ -3436,8 +3441,6 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - uint8_t drb_id_to_setup_start = 1; - long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, @@ -3456,7 +3459,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, co LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); uint8_t drb_id = ue_context_p->ue_context.DRB_configList->list.array[0]->drb_Identity; rnti_t rnti = ue_context_p->ue_context.rnti; - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3); LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, sizeof(gtpv1u_gnb_tunnel_data_req_t)); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index af2a0ee9e8..618cdef23b 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1115,7 +1115,7 @@ static int Gtpv1uHandleGpdu(int h, if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){ LOG_D (GTPU, "Create and send DL DATA Delivery status for the previously received PDU, NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id + 3); LOG_D(GTPU, "Available buffer size in RLC for Tx: %d \n", rlc_tx_buffer_space); /*Total size of DDD_status PDU = 1 octet to report extension header length * size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN diff --git a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp index 2a351dcce0..abbaddb255 100644 --- a/radio/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/radio/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1417,11 +1417,15 @@ extern "C" { s->tx_stream = s->usrp->get_tx_stream(stream_args_tx); /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i+choffset); + // N310 with UHD >= 4.2.0 has issues with changing the BW, which is a NOP on N310 in earlier versions + // see also: https://github.com/EttusResearch/uhd/issues/644 + if (device->type != USRP_N300_DEV) { + for(int i=0; i<((int) s->usrp->get_tx_num_channels()) && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i+choffset); - for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i+choffset); + for(int i=0; i<((int) s->usrp->get_rx_num_channels()) && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i+choffset); + } for (int i=0; i