diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index 762894f277..8a3fc8f9e2 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -308,29 +308,6 @@ pipeline { } } } - stage ("L2-Sim-Test-5G") { - when { expression {do5Gtest} } - steps { - script { - triggerSlaveJob ('RAN-L2-Sim-Test-5G', 'L2-Sim-Test-5G') - } - } - post { - always { - script { - // Using a unique variable name for each test stage to avoid overwriting on a global variable - // due to parallel-time concurrency - l2Sim5GStatus = finalizeSlaveJob('RAN-L2-Sim-Test-5G') - } - } - failure { - script { - currentBuild.result = 'FAILURE' - failingStages += l2Sim5GStatus - } - } - } - } stage ("LTE-B200-FDD-LTEBOX-Container") { when { expression {do4Gtest} } steps { diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_infra.yaml similarity index 92% rename from ci-scripts/ci_ueinfra.yaml rename to ci-scripts/ci_infra.yaml index 7fda8bab20..8142e960dd 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -56,6 +56,39 @@ adb_ue_2: MTU: 1500 LogStore: /media/usb-drive/ci_adb_2-logs +oc-cn5g: + Host: avra + NetworkScript: echo "inet 172.21.6.102" + RunIperf3Server: False + +porcepix-cn4g: + Host: porcepix + NetworkScript: docker exec prod-trf-gen ip a show dev eth0 + CmdPrefix: docker exec prod-trf-gen + +porcepix-cn5g: + Host: porcepix + NetworkScript: docker exec prod-trf-gen ip a show dev eth0 + CmdPrefix: docker exec prod-trf-gen + RunIperf3Server: False + +nano-cn4g: + Host: nano + NetworkScript: docker exec prod-trf-gen ip a show dev eth0 + CmdPrefix: docker exec prod-trf-gen + +ltebox-nano: + Host: nano + NetworkScript: ip a show dev tun1 + +sabox-nepes: + Host: nepes + NetworkScript: ip a show dev tun1 + +ltebox-nepes: + Host: nepes + NetworkScript: ip a show dev tun1 + amarisoft_ue: Host: amariue InitScript: /root/lteue-linux-2023-10-27/ue/lteue /root/oaicicd/ran_sa_aw2s_asue_2x2/aw2s-multi-20897-2x2.cfg & @@ -306,6 +339,18 @@ rfsim4g_enb_nos1: CmdPrefix: docker exec rfsim4g-oai-enb IF: oaitun_enb1 +rfsim4g_enb_fembms: + Host: localhost + NetworkScript: docker exec rfsim4g-oai-enb ip a show dev oaitun_enm1 + CmdPrefix: docker exec rfsim4g-oai-enb + IF: oaitun_enm1 + +rfsim4g_ue_fembms: + Host: localhost + NetworkScript: docker exec rfsim4g-oai-lte-ue0 ip a show dev oaitun_uem1 + CmdPrefix: docker exec rfsim4g-oai-lte-ue0 + IF: oaitun_uem1 + l2sim5g_ue: Host: localhost AttachScript: docker start l2sim-oai-nr-ue0 diff --git a/ci-scripts/cls_cmd.py b/ci-scripts/cls_cmd.py index 4eb64e2abe..7821f8263c 100644 --- a/ci-scripts/cls_cmd.py +++ b/ci-scripts/cls_cmd.py @@ -31,7 +31,8 @@ import subprocess as sp import os import paramiko import uuid -import sys +import sys +import time SSHTIMEOUT=7 @@ -106,6 +107,7 @@ class LocalCmd(Cmd): # if we wait for stdout, subprocess does not return before the end of the command # however, we don't want to wait for commands with &, so just return fake command ret = sp.run(line, shell=True, cwd=self.cwd, timeout=5) + time.sleep(0.1) else: ret = sp.run(line, shell=True, cwd=self.cwd, stdout=sp.PIPE, stderr=sp.STDOUT, timeout=timeout) except Exception as e: @@ -210,6 +212,7 @@ class RemoteCmd(Cmd): # however, we don't want to wait for commands with &, so just return fake command self.client.exec_command(line, timeout = 5) ret = sp.CompletedProcess(args=line, returncode=0, stdout=b'') + time.sleep(0.1) else: stdin, stdout, stderr = self.client.exec_command(line, timeout=timeout) ret = sp.CompletedProcess(args=line, returncode=stdout.channel.recv_exit_status(), stdout=stdout.read(size=None) + stderr.read(size=None)) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 860412e9f3..2eb0a98d16 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -169,97 +169,6 @@ def AnalyzeBuildLogs(buildRoot, images, globalStatus): collectInfo[image] = files return collectInfo -def AnalyzeIperf(cliOptions, clientReport, serverReport): - req_bw = 1.0 # default iperf throughput, in Mbps - result = re.search('-b *(?P[0-9\.]+)(?P[kKMG])', cliOptions) - if result is not None: - req_bw = float(result.group('iperf_bandwidth')) - magn = result.group('magnitude') - if magn == "k" or magn == "K": - req_bw /= 1000 - elif magn == "G": - req_bw *= 1000 - req_dur = 10 # default iperf send duration - result = re.search('-t *(?P[0-9]+)', cliOptions) - if result is not None: - req_dur = int(result.group('duration')) - - reportLine = None - # find server report in client status - clientReportLines = clientReport.split('\n') - for l in range(len(clientReportLines)): - res = re.search('read failed: Connection refused', clientReportLines[l]) - if res is not None: - message = 'iperf connection refused by server!' - logging.error(f'\u001B[1;37;41mIperf Test FAIL: {message}\u001B[0m') - return (False, message) - res = re.search('Server Report:', clientReportLines[l]) - if res is not None and l + 1 < len(clientReportLines): - reportLine = clientReportLines[l+1] - logging.debug(f'found server report: "{reportLine}"') - - statusTemplate = '(?:|\[ *\d+\].*) +0\.0-\s*(?P[0-9\.]+) +sec +[0-9\.]+ [kKMG]Bytes +(?P[0-9\.]+) (?P[kKMG])bits\/sec +(?P[0-9\.]+) ms +(\d+\/ *\d+) +(\((?P[0-9\.]+)%\))' - # if we do not find a server report in the client logs, check the server logs - # and use the last line which is typically close/identical to server report - if reportLine is None: - for l in serverReport.split('\n'): - res = re.search(statusTemplate, l) - if res is not None: - reportLine = l - if reportLine is None: - logging.warning('no report in server status found!') - return (False, 'could not parse iperf logs') - logging.debug(f'found client status: {reportLine}') - - result = re.search(statusTemplate, reportLine) - if result is None: - logging.error('could not analyze report from statusTemplate') - return (False, 'could not parse iperf logs') - - duration = float(result.group('duration')) - bitrate = float(result.group('bitrate')) - magn = result.group('magnitude') - if magn == "k" or magn == "K": - bitrate /= 1000 - elif magn == "G": # we assume bitrate in Mbps, therefore it must be G now - bitrate *= 1000 - jitter = float(result.group('jitter')) - packetloss = float(result.group('packetloss')) - - logging.debug('\u001B[1;37;44m iperf result \u001B[0m') - msg = f'Req Bitrate: {req_bw}' - logging.debug(f'\u001B[1;34m{msg}\u001B[0m') - - br_loss = bitrate/req_bw - bmsg = f'Bitrate : {bitrate} (perf {br_loss})' - logging.debug(f'\u001B[1;34m{bmsg}\u001B[0m') - msg += '\n' + bmsg - if br_loss < 0.9: - msg += '\nBitrate performance too low (<90%)' - logging.debug(f'\u001B[1;37;41mBitrate performance too low (<90%)\u001B[0m') - return (False, msg) - - plmsg = f'Packet Loss: {packetloss}%' - logging.debug(f'\u001B[1;34m{plmsg}\u001B[0m') - msg += '\n' + plmsg - if packetloss > 5.0: - msg += '\nPacket Loss too high!' - logging.debug(f'\u001B[1;37;41mPacket Loss too high \u001B[0m') - return (False, msg) - - dmsg = f'Duration : {duration} (req {req_dur})' - logging.debug(f'\u001B[1;34m{dmsg}\u001B[0m') - msg += '\n' + dmsg - if duration < float(req_dur): - msg += '\nDuration of iperf too short!' - logging.debug(f'\u001B[1;37;41mDuration of iperf too short\u001B[0m') - return (False, msg) - - jmsg = f'Jitter : {jitter}' - logging.debug(f'\u001B[1;34m{jmsg}\u001B[0m') - msg += '\n' + jmsg - return (True, msg) - #----------------------------------------------------------- # Class Declaration #----------------------------------------------------------- @@ -1026,7 +935,6 @@ class Containerize(): cnt = 100 status = True logging.info('\u001B[1m Deploying OAI object Pass\u001B[0m') - time.sleep(10) 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 @@ -1467,76 +1375,6 @@ class Containerize(): HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', [message]) - def PingExit(self, HTML, RAN, UE, status, message): - if status: - HTML.CreateHtmlTestRowQueue(self.pingOptions, 'OK', [message]) - else: - logging.error('\u001B[1;37;41m ping test FAIL -- ' + message + ' \u001B[0m') - HTML.CreateHtmlTestRowQueue(self.pingOptions, 'KO', [message]) - # Automatic undeployment - logging.warning('----------------------------------------') - logging.warning('\u001B[1m Starting Automatic undeployment \u001B[0m') - logging.warning('----------------------------------------') - HTML.testCase_id = 'AUTO-UNDEPLOY' - HTML.desc = 'Automatic Un-Deployment' - self.UndeployGenObject(HTML, RAN, UE) - self.exitStatus = 1 - - def IperfFromContainer(self, HTML, RAN, UE): - myCmd = cls_cmd.LocalCmd() - self.exitStatus = 0 - - ymlPath = self.yamlPath[0].split('/') - logPath = '../cmake_targets/log/' + ymlPath[1] - cmd = f'mkdir -p {logPath}' - myCmd.run(cmd, silent=True) - - # Start the server process - cmd = f'docker exec -d {self.svrContName} /bin/bash -c "nohup iperf {self.svrOptions} > /tmp/iperf_server.log 2>&1"' - myCmd.run(cmd) - time.sleep(3) - - # Start the client process - cmd = f'docker exec {self.cliContName} /bin/bash -c "iperf {self.cliOptions}" 2>&1 | tee {logPath}/iperf_client_{HTML.testCase_id}.log' - clientStatus = myCmd.run(cmd, timeout=100) - - # Stop the server process - cmd = f'docker exec {self.svrContName} /bin/bash -c "pkill iperf"' - myCmd.run(cmd) - time.sleep(3) - serverStatusFilename = f'{logPath}/iperf_server_{HTML.testCase_id}.log' - cmd = f'docker cp {self.svrContName}:/tmp/iperf_server.log {serverStatusFilename}' - myCmd.run(cmd, timeout=60) - myCmd.close() - - # clientStatus was retrieved above. The serverStatus was - # written in the background, then copied to the local machine - with open(serverStatusFilename, 'r') as f: - serverStatus = f.read() - (iperfStatus, msg) = AnalyzeIperf(self.cliOptions, clientStatus.stdout, serverStatus) - if iperfStatus: - logging.info('\u001B[1m Iperf Test PASS\u001B[0m') - else: - logging.error('\u001B[1;37;41m Iperf Test FAIL\u001B[0m') - self.IperfExit(HTML, RAN, UE, iperfStatus, msg) - - def IperfExit(self, HTML, RAN, UE, status, message): - html_cell = f'UE\n{message}' - if status: - HTML.CreateHtmlTestRowQueue(self.cliOptions, 'OK', [html_cell]) - else: - logging.error('\u001B[1m Iperf Test FAIL -- ' + message + ' \u001B[0m') - HTML.CreateHtmlTestRowQueue(self.cliOptions, 'KO', [html_cell]) - # Automatic undeployment - logging.warning('----------------------------------------') - logging.warning('\u001B[1m Starting Automatic undeployment \u001B[0m') - logging.warning('----------------------------------------') - HTML.testCase_id = 'AUTO-UNDEPLOY' - HTML.desc = 'Automatic Un-Deployment' - self.UndeployGenObject(HTML, RAN, UE) - self.exitStatus = 1 - - def CheckAndAddRoute(self, svrName, ipAddr, userName, password): logging.debug('Checking IP routing on ' + svrName) mySSH = SSH.SSHConnection() diff --git a/ci-scripts/cls_module_ue.py b/ci-scripts/cls_module.py similarity index 96% rename from ci-scripts/cls_module_ue.py rename to ci-scripts/cls_module.py index 19dac1044d..d0cfba0299 100644 --- a/ci-scripts/cls_module_ue.py +++ b/ci-scripts/cls_module.py @@ -41,7 +41,7 @@ import cls_cmd class Module_UE: - def __init__(self, module_name, filename="ci_ueinfra.yaml"): + def __init__(self, module_name, filename="ci_infra.yaml"): with open(filename, 'r') as f: all_ues = yaml.load(f, Loader=yaml.FullLoader) m = all_ues.get(module_name) @@ -64,7 +64,8 @@ class Module_UE: self.trace = m.get('trace') == True self.logStore = m.get('LogStore') self.cmd_prefix = m.get('CmdPrefix') - logging.info(f'initialized UE {self.module_name}@{self.host} from {filename}') + self.runIperf3Server = m.get('RunIperf3Server', True) + logging.info(f'initialized {self.module_name}@{self.host} from {filename}') def __str__(self): return f"{self.module_name}@{self.host} [IP: {self.getIP()}]" @@ -189,6 +190,9 @@ class Module_UE: def getHost(self): return self.host + def getRunIperf3Server(self): + return self.runIperf3Server + def getCmdPrefix(self): return self.cmd_prefix if self.cmd_prefix else "" diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index d7fecf8397..102eb1dfe7 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -45,6 +45,7 @@ import signal import statistics as stat from multiprocessing import SimpleQueue, Lock import concurrent.futures +import json #import our libs import helpreadme as HELP @@ -52,13 +53,188 @@ import constants as CONST import cls_cluster as OC import sshconnection -import cls_module_ue +import cls_module import cls_cmd logging.getLogger("matplotlib").setLevel(logging.WARNING) import matplotlib.pyplot as plt import numpy as np +#----------------------------------------------------------- +# Helper functions used here and in other classes +#----------------------------------------------------------- +def Iperf_ComputeModifiedBW(idx, ue_num, profile, args): + result = re.search('-b\s*(?P[0-9\.]+)(?P[KMG])', str(args)) + if result is None: + raise Exception('Iperf bandwidth not found or in incorrect format!') + iperf_bandwidth = result.group('iperf_bandwidth') + if profile == 'balanced': + iperf_bandwidth_new = float(iperf_bandwidth)/ue_num + if profile == 'single-ue': + iperf_bandwidth_new = float(iperf_bandwidth) + if profile == 'unbalanced': + # residual is 2% of max bw + residualBW = float(iperf_bandwidth) / 50 + if idx == 0: + iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) + else: + iperf_bandwidth_new = residualBW + iperf_bandwidth_str = result.group(0) + iperf_bandwidth_unit = result.group(2) + iperf_bandwidth_str_new = f"-b {'%.2f' % iperf_bandwidth_new}{iperf_bandwidth_unit}" + result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(args)) + if result is None: + raise Exception('Calculate Iperf bandwidth failed!') + return result + +def Iperf_ComputeTime(args): + result = re.search('-t\s*(?P\d+)', str(args)) + if result is None: + raise Exception('Iperf time not found!') + return int(result.group('iperf_time')) + +def Iperf_analyzeV3TCPJson(filename, iperf_tcp_rate_target): + if (not os.path.isfile(filename)): + return (False, 'Iperf3 TCP: Log file not present') + if (os.path.getsize(filename)==0): + return (False, 'Iperf3 TCP: Log file is empty') + + with open(filename) as file: + filename = json.load(file) + try: + sender_bitrate = round(filename['end']['streams'][0]['sender']['bits_per_second']/1000000,2) + receiver_bitrate = round(filename['end']['streams'][0]['receiver']['bits_per_second']/1000000,2) + except Exception as e: + return (False, 'Could not compute Iperf3 bitrate!') + + snd_msg = f'Sender Bitrate : {sender_bitrate} Mbps' + rcv_msg = f'Receiver Bitrate : {receiver_bitrate} Mbps' + success = True + if (iperf_tcp_rate_target is not None): + if (int(receiver_bitrate) < int(iperf_tcp_rate_target)): + rcv_msg += f" (too low! < {iperf_tcp_rate_target} Mbps)" + success = False + else: + rcv_msg += f" (target : {iperf_tcp_rate_target} Mbps)" + return(success, f'{snd_msg}\n{rcv_msg}') + +def Iperf_analyzeV3BIDIRJson(filename): + if (not os.path.isfile(filename)): + return (False, 'Iperf3 Bidir TCP: Log file not present') + if (os.path.getsize(filename)==0): + return (False, 'Iperf3 Bidir TCP: Log file is empty') + + with open(filename) as file: + filename = json.load(file) + try: + sender_bitrate_dl = round(filename['end']['streams'][0]['sender']['bits_per_second']/1000000,2) + receiver_bitrate_dl = round(filename['end']['streams'][0]['receiver']['bits_per_second']/1000000,2) + sender_bitrate_ul = round(filename['end']['streams'][1]['sender']['bits_per_second']/1000000,2) + receiver_bitrate_ul = round(filename['end']['streams'][1]['receiver']['bits_per_second']/1000000,2) + except Exception as e: + return (False, 'Could not compute BIDIR bitrate!') + + msg = f'Sender Bitrate DL : {sender_bitrate_dl} Mbps\n' + msg += f'Receiver Bitrate DL : {receiver_bitrate_dl} Mbps\n' + msg += f'Sender Bitrate UL : {sender_bitrate_ul} Mbps\n' + msg += f'Receiver Bitrate UL : {receiver_bitrate_ul} Mbps\n' + return (True, msg) + +def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_threshold): + if (not os.path.isfile(filename)): + return (False, 'Iperf3 UDP: Log file not present') + if (os.path.getsize(filename)==0): + return (False, 'Iperf3 UDP: Log file is empty') + sender_bitrate = None + receiver_bitrate = None + with open(filename, 'r') as server_file: + for line in server_file.readlines(): + res_sender = re.search(r'(?P[0-9\.]+)\s+(?P[KMG]bits\/sec)\s+(?P[0-9\.]+\s+ms)\s+(?P\d+)/(?P\d+) \((?P[0-9\.]+).*?\s+(sender)', line) + res_receiver = re.search(r'(?P[0-9\.]+)\s+(?P[KMG]bits\/sec)\s+(?P[0-9\.]+\s+ms)\s+(?P\d+)/(?P\d+) \((?P[0-9\.]+).*?\s+(receiver)', line) + if res_sender is not None: + sender_bitrate = res_sender.group('bitrate') + sender_unit = res_sender.group('unit') + sender_jitter = res_sender.group('jitter') + sender_lostPack = res_sender.group('lostPack') + sender_sentPack = res_sender.group('sentPack') + sender_packetloss = res_sender.group('lost') + if res_receiver is not None: + receiver_bitrate = res_receiver.group('bitrate') + receiver_unit = res_receiver.group('unit') + receiver_jitter = res_receiver.group('jitter') + receiver_lostPack = res_receiver.group('lostPack') + receiver_receivedPack = res_receiver.group('receivedPack') + receiver_packetloss = res_receiver.group('lost') + + if receiver_bitrate is not None and sender_bitrate is not None: + if sender_unit == 'Kbits/sec': + sender_bitrate = float(sender_bitrate) / 1000 + if receiver_unit == 'Kbits/sec': + receiver_bitrate = float(receiver_bitrate) / 1000 + br_perf = 100 * float(receiver_bitrate) / float(sender_bitrate) + br_perf = '%.2f ' % br_perf + sender_bitrate = '%.2f ' % float(sender_bitrate) + receiver_bitrate = '%.2f ' % float(receiver_bitrate) + req_msg = f'Sender Bitrate : {sender_bitrate} Mbps' + bir_msg = f'Receiver Bitrate : {receiver_bitrate} Mbps' + brl_msg = f'{br_perf}%' + jit_msg = f'Jitter : {receiver_jitter}' + pal_msg = f'Packet Loss : {receiver_packetloss} %' + if float(br_perf) < float(iperf_bitrate_threshold): + brl_msg = f'too low! < {iperf_bitrate_threshold}%' + if float(receiver_packetloss) > float(iperf_packetloss_threshold): + pal_msg += f' (too high! > {iperf_packetloss_threshold}%)' + result = float(br_perf) >= float(iperf_bitrate_threshold) and float(receiver_packetloss) <= float(iperf_packetloss_threshold) + return (result, f'{req_msg}\n{bir_msg} ({brl_msg})\n{jit_msg}\n{pal_msg}') + else: + return (False, 'Could not analyze iperf report') + +def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetloss_threshold, iperf_opt): + if (not os.path.isfile(server_filename)): + return (False, 'Could not analyze, server report not found!') + # Computing the requested bandwidth in float + req_bw = 1.0 # default iperf throughput, in Mbps + result = re.search('-b *(?P[0-9\.]+)(?P[kKMG])', iperf_opt) + if result is not None: + req_bw = float(result.group('iperf_bandwidth')) + magn = result.group('magnitude') + if magn == "k" or magn == "K": + req_bw /= 1000 + elif magn == "G": + req_bw *= 1000 + statusTemplate = '(?:|\[ *\d+\].*) +0\.0-\s*(?P[0-9\.]+) +sec +[0-9\.]+ [kKMG]Bytes +(?P[0-9\.]+) (?P[kKMG])bits\/sec +(?P[0-9\.]+) ms +(\d+\/ *\d+) +(\((?P[0-9\.]+)%\))' + + with open(server_filename, 'r') as server_file: + for line in server_file.readlines(): + res = re.search(statusTemplate, str(line)) + if res is not None: + result = res + if result is None: + return (False, 'Could not parse server report!') + + bitrate = float(result.group('bitrate')) + magn = result.group('magnitude') + if magn == "k" or magn == "K": + bitrate /= 1000 + elif magn == "G": # we assume bitrate in Mbps, therefore it must be G now + bitrate *= 1000 + jitter = float(result.group('jitter')) + packetloss = float(result.group('packetloss')) + br_perf = float(bitrate)/float(req_bw) * 100 + br_perf = '%.2f ' % br_perf + + result = float(br_perf) >= float(iperf_bitrate_threshold) and float(packetloss) <= float(iperf_packetloss_threshold) + req_msg = f'Req Bitrate : {req_bw}' + bir_msg = f'Bitrate : {bitrate}' + brl_msg = f'Bitrate Perf: {br_perf} %' + if float(br_perf) < float(iperf_bitrate_threshold): + brl_msg += f' (too low! <{iperf_bitrate_threshold}%)' + jit_msg = f'Jitter : {jitter}' + pal_msg = f'Packet Loss : {packetloss}' + if float(packetloss) > float(iperf_packetloss_threshold): + pal_msg += f' (too high! >{self.iperf_packetloss_threshold}%)' + return (result, f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}') + #----------------------------------------------------------- # OaiCiTest Class Definition #----------------------------------------------------------- @@ -86,7 +262,7 @@ class OaiCiTest(): self.iperf_bitrate_threshold = '' self.iperf_profile = '' self.iperf_options = '' - self.iperf_direction = '' + self.iperf_tcp_rate_target = '' self.nbMaxUEtoAttach = -1 self.UEDevices = [] self.UEDevicesStatus = [] @@ -113,6 +289,7 @@ class OaiCiTest(): self.clean_repository = True self.air_interface='' self.ue_ids = [] + self.svr_id = None self.cmd_prefix = '' # prefix before {lte,nr}-uesoftmodem @@ -222,7 +399,7 @@ class OaiCiTest(): def InitializeUE(self, HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] messages = [] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.initialize) for ue in ues] @@ -438,7 +615,7 @@ class OaiCiTest(): self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS) def AttachUE(self, HTML, RAN, EPC, CONTAINERS): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.attach) for ue in ues] attached = [f.result() for f in futures] @@ -453,7 +630,7 @@ class OaiCiTest(): self.AutoTerminateUEandeNB(HTML, RAN, EPC, CONTAINERS) def DetachUE(self, HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.detach) for ue in ues] [f.result() for f in futures] @@ -461,7 +638,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue('NA', 'OK', messages) def DataDisableUE(self, HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.dataDisable) for ue in ues] status = [f.result() for f in futures] @@ -473,7 +650,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue('N/A', 'KO', ["Could not disable UE data!"]) def DataEnableUE(self, HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] logging.debug(f'disabling data for UEs {ues}') with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.dataEnable) for ue in ues] @@ -486,7 +663,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue('N/A', 'KO', ["Could not enable UE data!"]) def CheckStatusUE(self,HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] logging.debug(f'checking status of UEs {ues}') messages = [] with concurrent.futures.ThreadPoolExecutor() as executor: @@ -590,7 +767,7 @@ class OaiCiTest(): if self.ue_ids == []: raise Exception("no module names in self.ue_ids provided") - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] logging.debug(ues) pingLock = Lock() with concurrent.futures.ThreadPoolExecutor() as executor: @@ -604,372 +781,65 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', messages) self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS) - def Iperf_ComputeTime(self): - result = re.search('-t (?P\d+)', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') - sys.exit(1) - return result.group('iperf_time') - - def Iperf_ComputeModifiedBW(self, idx, ue_num): - result = re.search('-b (?P[0-9\.]+)[KMG]', str(self.iperf_args)) - if result is None: - logging.error('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') - sys.exit(1) - iperf_bandwidth = result.group('iperf_bandwidth') - if self.iperf_profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if self.iperf_profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) - if self.iperf_profile == 'unbalanced': - # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 - if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) - else: - iperf_bandwidth_new = residualBW - iperf_bandwidth_str = f'-b {iperf_bandwidth}' - iperf_bandwidth_str_new = f"-b {'%.2f' % iperf_bandwidth_new}" - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) - if result is None: - logging.error('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') - sys.exit(1) - return result - - def Iperf_analyzeV2TCPOutput(self, SSH, filename): - - SSH.command(f'awk -f /tmp/tcp_iperf_stats.awk {filename}', '\$', 5) - result = re.search('Avg Bitrate : (?P[0-9\.]+ Mbits\/sec) Max Bitrate : (?P[0-9\.]+ Mbits\/sec) Min Bitrate : (?P[0-9\.]+ Mbits\/sec)', SSH.getBefore()) - if result is not None: - avgbitrate = result.group('average') - maxbitrate = result.group('maximum') - minbitrate = result.group('minimum') - msg = 'TCP Stats :\n' - if avgbitrate is not None: - msg += f'Avg Bitrate : {avgbitrate} \n' - if maxbitrate is not None: - msg += f'Max Bitrate : {maxbitrate} \n' - if minbitrate is not None: - msg += f'Min Bitrate : {minbitrate} \n' - return (True, msg) - - return (False, "could not analyze log file") - - def Iperf_analyzeV2Output(self, iperf_real_options, EPC, SSH): - - result = re.search('-u', str(iperf_real_options)) - if result is None: - filename = f'{EPC.SourceCodePath}/scripts/iperf_{self.testCase_id}_{device_id}.log' - response = self.Iperf_analyzeV2TCPOutput(SSH, filename) - return response - - result = re.search('Server Report:', SSH.getBefore()) - if result is None: - result = re.search('read failed: Connection refused', SSH.getBefore()) - if result is not None: - msg = 'Could not connect to iperf server!' - return (False, msg) - else: - msg = 'Server Report and Connection refused Not Found!' - return (False, msg) - # Computing the requested bandwidth in float - result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is not None: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - result = re.search('Server Report:\r\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', SSH.getBefore()) - if result is not None: - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - jitter = result.group('jitter') - - iperfStatus = True - msg = f'Req Bitrate : {req_bandwidth} \n' - if bitrate is not None: - msg += f'Bitrate : {bitrate} \n' - result = re.search('(?P[0-9\.]+) [KMG]bits/sec', str(bitrate)) - if result is not None: - actual_bw = float(str(result.group('real_bw'))) - result = re.search('[0-9\.]+ K', bitrate) - if result is not None: - actual_bw = actual_bw * 1000 - result = re.search('[0-9\.]+ M', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000 - result = re.search('[0-9\.]+ G', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000000 - br_loss = 100 * actual_bw / req_bw - bitperf = '%.2f ' % br_loss - msg += f'Bitrate Perf: {bitperf} %\n' - if packetloss is not None: - msg += f'Packet Loss : {packetloss} %\n' - if float(packetloss) > float(self.iperf_packetloss_threshold): - msg += 'Packet Loss too high!\n' - iperfStatus = False - if jitter is not None: - msg += f'Jitter : {jitter} \n' - - return (iperfStatus, msg) - else: - return (False, "could not analyze server log") - - - def Iperf_analyzeV2BIDIR(self, server_filename, client_filename): - - #check the 2 files are here - if (not os.path.isfile(client_filename)) or (not os.path.isfile(server_filename)): - return (False, 'Bidir TCP: Client or Server Log File not present') - #check the 2 files size - if (os.path.getsize(client_filename)==0) and (os.path.getsize(server_filename)==0): - return (False, 'Bidir TCP: Client and Server Log File are empty') - - report_msg = '' - #if client is not empty, all the info is in, otherwise we ll use the server file to get some partial info - client_filesize = os.path.getsize(client_filename) - if client_filesize == 0: - report_msg+="Client file (UE) present but !!! EMPTY !!!\n" - report_msg+="Partial report from server file" - filename = server_filename - else : - report_msg+="Report from client file (UE)" - filename = client_filename - - report=[] #used to check if relevant lines were found - - with open(filename, 'r') as f_client: - for line in f_client.readlines(): - result = re.search(rf'^\[\s+\d+\](?P\[.+\]).*\s+(?P[0-9\.]+ [KMG]bits\/sec).*\s+(?P\bsender|receiver\b)', str(line)) - if result is not None: - report.append(str(line)) - report_msg += f"\n{result.group('role')} {result.group('direction')}\t: {result.group('bitrate')}" - if len(report) == 0: - return (False, 'Bidir TCP: Could not analyze from Log file') - - return (True, report_msg) - - def Iperf_analyzeV2Server(self, iperf_real_options, filename, type): - if (not os.path.isfile(filename)): - return (False, 'Could not analyze from server log') - # Computing the requested bandwidth in float - result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is None: - return (False, 'Could not compute Iperf bandwidth!') - else: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - server_file = open(filename, 'r') - br_sum = 0.0 - ji_sum = 0.0 - pl_sum = 0 - ps_sum = 0 - row_idx = 0 - for line in server_file.readlines(): - if type==0: - result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(?P[0-9]+)/ +(?P[0-9]+)', str(line)) - else: - result = re.search('^\[\s+\d\].+ (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(?P[0-9]+)\/\s*(?P[0-9]+)', str(line)) - - if result is not None: - bitrate = result.group('bitrate') - jitter = result.group('jitter') - packetlost = result.group('lostPack') - packetsent = result.group('sentPack') - br = bitrate.split(' ') - ji = jitter.split(' ') - row_idx = row_idx + 1 - curr_br = float(br[0]) - pl_sum = pl_sum + int(packetlost) - ps_sum = ps_sum + int(packetsent) - if (br[1] == 'Kbits/sec'): - curr_br = curr_br * 1000 - if (br[1] == 'Mbits/sec'): - curr_br = curr_br * 1000 * 1000 - br_sum = curr_br + br_sum - ji_sum = float(ji[0]) + ji_sum - - server_file.close() - - if (row_idx > 0): - br_sum = br_sum / row_idx - ji_sum = ji_sum / row_idx - br_loss = 100 * br_sum / req_bw - if (br_sum > 1000): - br_sum = br_sum / 1000 - if (br_sum > 1000): - br_sum = br_sum / 1000 - bitrate = '%.2f Mbits/sec' % br_sum - else: - bitrate = '%.2f Kbits/sec' % br_sum - else: - bitrate = '%.2f bits/sec' % br_sum - bitperf = '%.2f ' % br_loss - bitperf += '%' - jitter = '%.2f ms' % (ji_sum) - if (ps_sum > 0): - pl = float(100 * pl_sum / ps_sum) - packetloss = '%2.1f ' % (pl) - packetloss += '%' - - result = float(br_loss) >= float(self.iperf_bitrate_threshold) and float(pl) <= float(self.iperf_packetloss_threshold) - req_msg = f'Req Bitrate : {req_bandwidth}' - bir_msg = f'Bitrate : {bitrate}' - brl_msg = f'Bitrate Perf: {bitperf}' - if float(br_loss) < float(self.iperf_bitrate_threshold): - brl_msg += f' (too low! <{self.iperf_bitrate_threshold}%)' - jit_msg = f'Jitter : {jitter}' - pal_msg = f'Packet Loss : {packetloss}' - if float(pl) > float(self.iperf_packetloss_threshold): - pal_msg += f' (too high! >{self.iperf_packetloss_threshold}%)' - return (result, f'{req_msg}\n{bir_msg}\n{brl_msg}\n{jit_msg}\n{pal_msg}') - else: - return (False, 'Could not analyze from server log') - - def Iperf_Module(self, EPC, ue, RAN, idx, ue_num): + def Iperf_Module(self, EPC, ue, svr, RAN, idx, ue_num, CONTAINERS): ueIP = ue.getIP() if not ueIP: return (False, f"UE {ue.getName()} has no IP address") - SSH = sshconnection.SSHConnection() - server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log' - client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log' - if (re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE)) or (re.match('OAICN5G', EPC.Type, re.IGNORECASE)): - #retrieve trf-gen container IP address - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('docker inspect --format="TRF_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" prod-trf-gen', '\$', 5) - result = re.search('TRF_IP_ADDR = (?P[0-9\.]+)', SSH.getBefore()) - if result is None: - raise Exception("could not corver prod-trf-gen IP address") - cn_target_ip = result.group('trf_ip_addr') - SSH.close() - cn_iperf_prefix = "docker exec prod-trf-gen" # -w /iperf-2.0.13 necessary? - elif (re.match('OC-OAI-CN5G', EPC.Type, re.IGNORECASE)): - cn_target_ip = "172.21.6.102" - else: # lteboix, sabox - cn_target_ip = "192.172.0.1" - cn_iperf_prefix = "" + svrIP = svr.getIP() + if not svrIP: + return (False, f"Iperf server {ue.getName()} has no IP address") + runIperf3Server = svr.getRunIperf3Server() iperf_opt = self.iperf_args + jsonReport = "--json" + serverReport = "" udpIperf = re.search('-u', iperf_opt) is not None - udpSwitch = '-u' if udpIperf else '' - if udpIperf: - iperf_opt = self.Iperf_ComputeModifiedBW(idx, ue_num) - logging.info(f'iperf options modified from "{self.iperf_args}" to "{iperf_opt}" for {ue.getName()}') - iperf_time = int(self.Iperf_ComputeTime()) - port = f'-p {5001+idx}' - # hack: the ADB UEs don't have iperf in $PATH, so we need to hardcode for the moment - iperf_ue = '/data/local/tmp/iperf' if re.search('adb', ue.getName()) else 'iperf' + bidirIperf = re.search('--bidir', iperf_opt) is not None + client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log' + server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log' + ymlPath = CONTAINERS.yamlPath[0].split('/') + logPath = f'../cmake_targets/log/{ymlPath[1]}' + if udpIperf: + iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args) + # note: for UDP testing we don't want to use json report - reports 0 Mbps received bitrate + jsonReport = "" + # note: enable server report collection on the UE side, no need to store and collect server report separately on the server side + serverReport = "--get-server-output" + logging.info(f'iperf options modified from "{self.iperf_args}" to "{iperf_opt}" for {ue.getName()}') + iperf_time = Iperf_ComputeTime(self.iperf_args) + # hack: the ADB UEs don't have iperf in $PATH, so we need to hardcode for the moment + iperf_ue = '/data/local/tmp/iperf3' if re.search('adb', ue.getName()) else 'iperf3' ue_header = f'UE {ue.getName()} ({ueIP})' - if self.iperf_direction == "DL": - logging.debug("Iperf in DL requested") - cmd = cls_cmd.getConnection(ue.getHost()) - cmd.run(f'rm {server_filename}') - cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -s -B {ueIP} {udpSwitch} -i 1 -t {iperf_time * 1.5} {port} &> /tmp/{server_filename} &') - cmd.close() - - cmd = cls_cmd.getConnection(EPC.IPAddress) - cmd.run(f'rm {EPC.SourceCodePath}/{client_filename}') - cmd.run(f'{cn_iperf_prefix} iperf -c {ueIP} {iperf_opt} {port} &> {EPC.SourceCodePath}/{client_filename}', timeout=iperf_time * 1.5) - cmd.copyin(f'{EPC.SourceCodePath}/{client_filename}', client_filename) - cmd.close() - - cmd = cls_cmd.getConnection(ue.getHost()) - cmd.copyin(f'/tmp/{server_filename}', server_filename) - cmd.close() - + if svr.getName() == "rfsim4g_enb_fembms": + with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: + port = 5002 + idx + cmd_ue.run(f'{ue.getCmdPrefix()} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=iperf_time*1.5) + cmd_svr.run(f'{svr.getCmdPrefix()} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 2>&1 | tee {client_filename}', timeout=iperf_time*1.5) + cmd_ue.run(f'cp {client_filename} {logPath}/{client_filename}') + cmd_ue.run(f'cp {server_filename} {logPath}/{server_filename}') + status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, iperf_opt) + else: + with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: + port = 5002 + idx + # note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False` + if runIperf3Server: + cmd_svr.run(f'{svr.getCmdPrefix()} nohup iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} &', timeout=iperf_time*1.5) + cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False) + cmd_ue.run(f'{ue.getCmdPrefix()} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> /tmp/{client_filename}', timeout=iperf_time*1.5) + if svr.getHost() == 'localhost': + cmd_ue.run(f'mkdir -p {logPath}') + cmd_ue.run(f'cp /tmp/{client_filename} {logPath}/{client_filename}') + cmd_ue.run(f'cp /tmp/{client_filename} {client_filename}') + else: + cmd_ue.copyin(f'/tmp/{client_filename}', client_filename) if udpIperf: - status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1) + status, msg = Iperf_analyzeV3UDP(client_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold) + elif bidirIperf: + status, msg = Iperf_analyzeV3BIDIRJson(client_filename) else: - cmd = cls_cmd.getConnection(EPC.IPAddress) - status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f"{EPC.SourceCodePath}/{client_filename}") - cmd.close() - - elif self.iperf_direction == "UL": - logging.debug("Iperf in UL requested") - cmd = cls_cmd.getConnection(EPC.IPAddress) - cmd.run(f'rm {EPC.SourceCodePath}/{server_filename}') - cmd.run(f'{cn_iperf_prefix} iperf -s {udpSwitch} -t {iperf_time * 1.5} {port} &> {EPC.SourceCodePath}/{server_filename} &') - cmd.close() - - cmd = cls_cmd.getConnection(ue.getHost()) - cmd.run(f'rm /tmp/{client_filename}') - cmd.run(f'{ue.getCmdPrefix()} {iperf_ue} -B {ueIP} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5) - cmd.copyin(f'/tmp/{client_filename}', client_filename) - cmd.close() - - cmd = cls_cmd.getConnection(EPC.IPAddress) - cmd.copyin(f'{EPC.SourceCodePath}/{server_filename}', server_filename) - cmd.close() - - if udpIperf: - status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1) - else: - cmd = cls_cmd.getConnection(ue.getHost()) - status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f"/tmp/{client_filename}") - cmd.close() - - elif self.iperf_direction=="BIDIR": - logging.debug("Bi-directional iperf requested") - cmd = cls_cmd.getConnection(EPC.IPAddress) - cmd.run(f'rm {EPC.SourceCodePath}/{server_filename}') - cmd.run(f'{cn_iperf_prefix} iperf3 -s -i 1 -1 {port} &> {EPC.SourceCodePath}/{server_filename} &') - cmd.close() - - cmd = cls_cmd.getConnection(ue.getHost()) - cmd.run(f'rm /tmp/{client_filename}') - cmd.run(f'iperf3 -B {ueIP} -c {cn_target_ip} {iperf_opt} {port} &> /tmp/{client_filename}', timeout=iperf_time*1.5) - cmd.copyin(f'/tmp/{client_filename}', client_filename) - cmd.close() - - cmd = cls_cmd.getConnection(EPC.IPAddress) - cmd.copyin(f'{EPC.SourceCodePath}/{server_filename}', server_filename) - cmd.close() - - status, msg = self.Iperf_analyzeV2BIDIR(server_filename, client_filename) - - elif self.iperf_direction == "IPERF3": - cmd = cls_cmd.getConnection(ue.getHost()) - cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False) - port = f'{5002+idx}' - cmd.run(f'{ue.getCmdPrefix()} iperf3 -B {ueIP} -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5) - cmd.copyin(f'/tmp/{server_filename}', server_filename) - cmd.close() - if udpIperf: - status, msg = self.Iperf_analyzeV2Server(iperf_opt, server_filename, 1) - else: - cmd = cls_cmd.getConnection(EPC.IPAddress) - status, msg = self.Iperf_analyzeV2TCPOutput(cmd, f'/tmp/{server_filename}') - cmd.close() - - else : - raise Exception("Incorrect or missing IPERF direction in XML") + status, msg = Iperf_analyzeV3TCPJson(client_filename, self.iperf_tcp_rate_target) logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m') for l in msg.split('\n'): @@ -988,12 +858,16 @@ class OaiCiTest(): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - logging.debug(f'Iperf: iperf_args "{self.iperf_args}" iperf_direction "{self.iperf_direction}" iperf_packetloss_threshold "{self.iperf_packetloss_threshold}" iperf_bitrate_threshold "{self.iperf_bitrate_threshold}" iperf_profile "{self.iperf_profile}" iperf_options "{self.iperf_options}"') + logging.debug(f'Iperf: iperf_args "{self.iperf_args}" iperf_packetloss_threshold "{self.iperf_packetloss_threshold}" iperf_bitrate_threshold "{self.iperf_bitrate_threshold}" iperf_profile "{self.iperf_profile}" iperf_options "{self.iperf_options}"') - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + if self.ue_ids == [] or self.svr_id == None: + raise Exception("no module names in self.ue_ids or/and self.svr_id provided") + + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] + svr = cls_module.Module_UE(self.svr_id) logging.debug(ues) with concurrent.futures.ThreadPoolExecutor() as executor: - futures = [executor.submit(self.Iperf_Module, EPC, ue, RAN, i, len(ues)) for i, ue in enumerate(ues)] + futures = [executor.submit(self.Iperf_Module, EPC, ue, svr, RAN, i, len(ues), CONTAINERS) for i, ue in enumerate(ues)] results = [f.result() for f in futures] # each result in results is a tuple, first member goes to successes, second to messages successes, messages = map(list, zip(*results)) @@ -1127,15 +1001,15 @@ class OaiCiTest(): mib_found = True except Exception as e: logging.error(f'\033[91m MIB marker was not found \033[0m') - result = re.search("Measured Carrier Frequency (?P\d{1,15}) Hz", str(line)) + result = re.search("Initial sync: pbch decoded sucessfully", str(line)) if result is not None and (not frequency_found): try: - mibMsg = f"Measured Carrier Frequency = {result.group('measured_carrier_frequency')} Hz" + mibMsg = f"UE decoded PBCH successfully" HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug(f'\033[94m{mibMsg}\033[0m') frequency_found = True except Exception as e: - logging.error(f'\033[91m Measured Carrier Frequency not found \033[0m') + logging.error(f'\033[91m UE did not find PBCH\033[0m') result = re.search("PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) if result is not None and (not plmn_found): try: @@ -1272,7 +1146,7 @@ class OaiCiTest(): return global_status def TerminateUE(self, HTML): - ues = [cls_module_ue.Module_UE(n.strip()) for n in self.ue_ids] + ues = [cls_module.Module_UE(n.strip()) for n in self.ue_ids] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [executor.submit(ue.terminate) for ue in ues] archives = [f.result() for f in futures] @@ -1404,7 +1278,7 @@ class OaiCiTest(): time.sleep(self.idle_sleep_time) HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) - def X2_Status(self, idx, fileName): + def X2_Status(self, idx, fileName, EPC): cmd = "curl --silent http://" + EPC.IPAddress + ":9999/stats | jq '.' > " + fileName message = cmd + '\n' logging.debug(cmd) diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 825fcd1c49..5a8d1abd04 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -186,7 +186,7 @@ L1s = ( num_cc = 1; tr_n_preference = "local_mac"; prach_dtx_threshold = 200; - pucch0_dtx_threshold = 150; + pucch0_dtx_threshold = 100; ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 } ); diff --git a/ci-scripts/main.py b/ci-scripts/main.py index db6fedde1a..ad93646de9 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -268,10 +268,11 @@ def GetParametersFromXML(action): elif action == 'Iperf': CiTestObj.iperf_args = test.findtext('iperf_args') CiTestObj.ue_ids = test.findtext('id').split(' ') - CiTestObj.iperf_direction = test.findtext('direction') + CiTestObj.svr_id = test.findtext('svr_id') or None CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') CiTestObj.iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold') or '90' CiTestObj.iperf_profile = test.findtext('iperf_profile') or 'balanced' + CiTestObj.iperf_tcp_rate_target = test.findtext('iperf_tcp_rate_target') or None if CiTestObj.iperf_profile != 'balanced' and CiTestObj.iperf_profile != 'unbalanced' and CiTestObj.iperf_profile != 'single-ue': logging.error(f'test-case has wrong profile {CiTestObj.iperf_profile}, forcing balanced') CiTestObj.iperf_profile = 'balanced' @@ -375,20 +376,6 @@ def GetParametersFromXML(action): if (string_field is not None): CONTAINERS.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] - elif action == 'IperfFromContainer': - string_field = test.findtext('server_container_name') - if (string_field is not None): - CONTAINERS.svrContName = string_field - string_field = test.findtext('server_options') - if (string_field is not None): - CONTAINERS.svrOptions = string_field - string_field = test.findtext('client_container_name') - if (string_field is not None): - CONTAINERS.cliContName = string_field - string_field = test.findtext('client_options') - if (string_field is not None): - CONTAINERS.cliOptions = string_field - elif action == 'Run_LDPCTest' or action == 'Run_NRulsimTest' or action == 'Run_LDPCt1Test': ldpc.runargs = test.findtext('physim_run_args') diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index 645e5480be..5772cd4eeb 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -41,7 +41,6 @@ - Deploy_Run_PhySim - DeployGenObject - UndeployGenObject - - IperfFromContainer - StatsFromGenObject - LicenceAndFormattingCheck - Push_Local_Registry diff --git a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml index 4ce82b54aa..de7baff19b 100644 --- a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml +++ b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml @@ -105,21 +105,23 @@ - IperfFromContainer + Iperf Iperf UDP Downlink - l2sim4g-oai-lte-ue1 - l2sim4g-trf-gen - -B 12.0.0.2 -u -i 1 -s - -c 12.0.0.2 -u -i 1 -t 30 -b 1M + l2sim4g_ue + l2sim4g_ext_dn + -u -t 30 -b 1M -R + 25 + 80 - IperfFromContainer + Iperf Iperf UDP Uplink - l2sim4g-trf-gen - l2sim4g-oai-lte-ue1 - -u -i 1 -s - -B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 3M + l2sim4g_ue + l2sim4g_ext_dn + -u -t 30 -b 3M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml index 37d53e09e4..9f88fb71ef 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml @@ -110,22 +110,24 @@ 5 - - IperfFromContainer - Iperf UDP Downlink - rfsim4g-oai-lte-ue0 - rfsim4g-trf-gen - -B 12.0.0.2 -u -i 1 -s - -c 12.0.0.2 -u -i 1 -t 30 -b 2M + + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 2M -R + 25 + 80 - - IperfFromContainer - Iperf UDP Uplink - rfsim4g-trf-gen - rfsim4g-oai-lte-ue0 - -u -i 1 -s - -B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 1M + + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 1M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml index 5a6189dced..9b6fdabbce 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml @@ -91,21 +91,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim4g-oai-lte-ue0 - rfsim4g-oai-enb - -B 10.0.1.2 -u -i 1 -s - -B 10.0.1.1 -c 10.0.1.2 -u -i 1 -t 30 -b 2M + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_enb_nos1 + -u -t 30 -b 2M -R + 25 + 80 - IperfFromContainer - Iperf UDP Uplink - rfsim4g-oai-enb - rfsim4g-oai-lte-ue0 - -B 10.0.1.1 -u -i 1 -s - -B 10.0.1.2 -c 10.0.1.1 -u -i 1 -t 30 -b 1M + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_enb_nos1 + -u -t 30 -b 1M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml index e6c3e1f965..d058f9f150 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml @@ -111,21 +111,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim4g-oai-lte-ue0 - rfsim4g-trf-gen - -B 12.0.0.2 -u -i 1 -s - -c 12.0.0.2 -u -i 1 -t 30 -b 2M + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 2M -R + 25 + 80 - IperfFromContainer - Iperf UDP Uplink - rfsim4g-trf-gen - rfsim4g-oai-lte-ue0 - -u -i 1 -s - -B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 1M + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 1M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml index 86b217a2a4..280814a888 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml @@ -111,21 +111,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim4g-oai-lte-ue0 - rfsim4g-trf-gen - -B 12.0.0.2 -u -i 1 -s - -c 12.0.0.2 -u -i 1 -t 30 -b 2M + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 2M -R + 25 + 80 - IperfFromContainer - Iperf UDP Uplink - rfsim4g-trf-gen - rfsim4g-oai-lte-ue0 - -u -i 1 -s - -B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 1M + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 1M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index 60db5359e8..1a508b772a 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -72,12 +72,13 @@ - IperfFromContainer - Push MBMS traffic - rfsim4g-oai-lte-ue0 - rfsim4g-oai-enb - -sui1 -B 10.0.2.2 - -uc 10.0.2.2 -i1 -t10 -b2M -B10.0.2.1 + Iperf + Iperf UDP DL + rfsim4g_ue_fembms + rfsim4g_enb_fembms + -u -t 30 -b 2M + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml index 1685a4e47d..56ab42c323 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml @@ -72,12 +72,13 @@ - IperfFromContainer - Push MBMS traffic - rfsim4g-oai-lte-ue0 - rfsim4g-oai-enb - -sui1 -B 10.0.2.2 - -uc 10.0.2.2 -i1 -t10 -b2M -B10.0.2.1 + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_enb_nos1 + -u -t 30 -b 2M -R + 25 + 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml index 862e9cca52..a5501f2879 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml @@ -112,21 +112,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim4g-oai-lte-ue0 - rfsim4g-trf-gen - -B 12.0.0.2 -u -i 1 -s - -c 12.0.0.2 -u -i 1 -t 30 -b 2M + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 2M -R + 25 + 80 - IperfFromContainer - Iperf UDP Uplink - rfsim4g-trf-gen - rfsim4g-oai-lte-ue0 - -u -i 1 -s - -B 12.0.0.2 -c 192.168.61.11 -u -i 1 -t 30 -b 1M + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 1M + 25 + 80 diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim.xml b/ci-scripts/xml_files/container_5g_e1_rfsim.xml index e4ddb9e4d7..3d9bec6b9d 100644 --- a/ci-scripts/xml_files/container_5g_e1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_e1_rfsim.xml @@ -40,7 +40,7 @@ Pull_Local_Registry Pull Images from Local Registry 0 - oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan + oai-gnb oai-nr-cuup oai-nr-ue diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 09b69730a3..fc35442088 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -75,21 +75,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 10 -b 20M + Iperf + Iperf (DL/20Mbps/UDP)(30 sec) + -u -b 20M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 5M + Iperf + Iperf (UL/5Mbps/UDP)(30 sec) + -u -b 5M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index 59be0e3738..da059dadd4 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -85,21 +85,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 30 -b 3M + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 3M + Iperf + Iperf (UL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 89a31b55b4..e3779d3e6b 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -180,21 +180,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 30 -b 3M + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 1M + Iperf + Iperf (UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml index e90cbc309b..944d9fafc6 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml @@ -85,21 +85,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 5 -b 3M + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 5 -b 1M + Iperf + Iperf (UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml index 2b3f3413db..7899ac00c7 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml @@ -85,21 +85,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 10 -b 3M + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 1M + Iperf + Iperf (UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml index 6ed13ceb6e..3020f63055 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml @@ -86,21 +86,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-gnb - -sui1 -B10.0.1.2 - -uc10.0.1.2 -i1 -t10 -b30k -B10.0.1.1 + Iperf + Iperf (DL/30kbps/UDP)(30 sec) + -u -b 0.03M -t 30 -R -c 10.0.1.1 + rfsim5g_ue + rfsim5g_gnb_nos1 + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-gnb - rfsim5g-oai-nr-ue - -sui1 -B10.0.1.1 - -uc10.0.1.1 -i1 -t10 -b30k -B10.0.1.2 + Iperf + Iperf (UL/30kbps/UDP)(30 sec) + -u -b 0.03M -t 30 -c 10.0.1.1 + rfsim5g_ue + rfsim5g_gnb_nos1 + 5 + 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml index f2f4d5e78e..0540d44f1f 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml @@ -85,21 +85,23 @@ - IperfFromContainer - Iperf UDP Downlink - rfsim5g-oai-nr-ue - rfsim5g-oai-ext-dn - -B 12.1.1.2 -u -i 1 -s - -c 12.1.1.2 -u -i 1 -t 10 -b 3M + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 - IperfFromContainer - Iperf UDP Uplink - rfsim5g-oai-ext-dn - rfsim5g-oai-nr-ue - -u -i 1 -s - -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 10 -b 1M + Iperf + Iperf (UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 + rfsim5g_ue + rfsim5g_ext_dn + 5 + 90 diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml index 3c4a0d006e..ffdf7317f1 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml @@ -118,91 +118,82 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1.xml Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -i 1 + -u -b 15M -t 30 -R 50 50 - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -i 1 + -u -b 15M -t 30 -R 50 - DL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 15M -t 30 -i 1 + -u -b 15M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - DL + -t 30 -R adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 -i 1 + -u -b 9M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 -i 1 + -u -b 9M -t 30 50 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml index 0f4b6535ef..711d685bad 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml @@ -126,62 +126,57 @@ Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -i 1 + -u -b 15M -t 30 -R 50 50 - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -i 1 + -u -b 15M -t 30 -R 50 - DL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 -i 1 + -u -b 9M -t 30 50 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 -i 1 + -u -b 9M -t 30 50 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml index 6fd083a2e8..5d9eb0c13f 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml @@ -112,92 +112,83 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Iperf iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) - -u -b 30M -t 30 -i 1 + -u -b 30M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile) - -u -b 30M -t 30 -i 1 + -u -b 30M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 30M -t 30 -i 1 + -u -b 30M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (10MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - DL + -t 30 -R adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/18Mbps/UDP)(30 sec)(balanced profile) - -u -b 18M -t 30 -i 1 + -u -b 18M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/18Mbps/UDP)(30 sec)(single-ue profile) - -u -b 18M -t 30 -i 1 + -u -b 18M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (10MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (10MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 + -t 30 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml index 01be9676be..358eeb20cc 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml @@ -105,22 +105,22 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Iperf iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) - -u -b 30M -t 30 -i 1 + -u -b 30M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 -i 1 + -u -b 20M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml index 4d42fb4153..7b8a06e51c 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml @@ -134,41 +134,38 @@ Iperf iperf (10MHz - DL/10Mbps/UDP)(30 sec)(balanced profile) - -u -b 10M -t 30 -i 1 + -u -b 10M -t 30 -R 50 - single-ue - DL lte_oai_ue_carabe + nano-cn4g Iperf iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm + -t 30 -R 50 - single-ue - DL lte_oai_ue_carabe + nano-cn4g Iperf iperf (10MHz - UL/10Mbps/UDP)(30 sec)(balanced profile) - -u -b 10M -t 30 -i 1 + -u -b 10M -t 30 50 - single-ue - UL lte_oai_ue_carabe + nano-cn4g Iperf iperf (10MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm + -t 30 50 balanced - UL lte_oai_ue_carabe + nano-cn4g diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue_cleanup.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue_cleanup.xml index 33df87d924..03d502fe14 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue_cleanup.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue_cleanup.xml @@ -25,11 +25,29 @@ Images Clean-Up trash +000000 +111111 222222 333333 + + Undeploy_Object + Undeploy eNB + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma + 0 + 0 + + + + Undeploy_Object + Undeploy LTE-UE + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma + 1 + 1 + + Clean_Test_Server_Images Clean Test Images on eNB Test Server diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml index 8bb2dfafc9..c526cd9786 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml @@ -111,92 +111,84 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Iperf iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile) - -u -b 70M -t 30 -i 1 + -u -b 70M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) - -u -b 70M -t 30 -i 1 + -u -b 70M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 70M -t 30 -i 1 + -u -b 70M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 + -t 30 -R balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/12Mbps/UDP)(30 sec)(balanced profile) - -u -b 12M -t 30 -i 1 + -u -b 12M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/17Mbps/UDP)(30 sec)(single-ue profile) - -u -b 17M -t 30 -i 1 + -u -b 17M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 + -t 30 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml index d181fd1a0d..7928cccbe1 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml @@ -119,100 +119,93 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - DL + -t 30 -R adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 unbalanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm + -t 30 50 - UL adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml index 1c87cefe82..ce4ce3346c 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml @@ -127,80 +127,72 @@ Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (5MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - DL + -t 30 -R adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm2.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm2.xml index 7222215932..d79c668b58 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm2.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm2.xml @@ -109,99 +109,86 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm2.xml Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 balanced - DL adb_ue_1 adb_ue_2 Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 -R 50 - single-ue - DL adb_ue_1 Iperf iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 6.5M -t 30 -i 1 + -u -b 6.5M -t 30 50 unbalanced - DL adb_ue_1 adb_ue_2 Iperf iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 Iperf iperf (5MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - DL + -t 30 -R adb_ue_1 adb_ue_2 Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 unbalanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (5MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml index ef9239fe86..2487163e20 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml @@ -109,100 +109,93 @@ Replaces xml_files/enb_usrp210_band40_test_10mhz_tm1.xml Iperf iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (10MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm + -t 30 -R 50 - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 unbalanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (10MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (10MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml index d853b56855..476f159ea2 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml @@ -109,99 +109,91 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1.xml Iperf iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 13.5M -t 30 -i 1 + -u -b 13.5M -t 30 -R 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - DL + -t 30 -R adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 -R 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 -R 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 + -u -b 2M -t 30 50 unbalanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml index 0fae91af5f..b8c6d2c09f 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml @@ -111,102 +111,95 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml Iperf iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(balanced) - -u -b 27.5M -t 30 -i 1 + -u -b 27.5M -t 30 -R 50 50 balanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(single-ue) - -u -b 27.5M -t 30 -i 1 + -u -b 27.5M -t 30 -R 50 50 - single-ue - DL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 27.5M -t 30 -i 1 + -u -b 27.5M -t 30 -R 50 50 unbalanced - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - DL + -t 30 -R adb_ue_1 + ltebox-nano Iperf iperf (20MHz - DL/TCP)(30 sec) - -t 30 -i 1 -fm + -t 30 -R 50 - DL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/7Mbps/UDP)(30 sec)(balanced) - -u -b 7M -t 30 -i 1 + -u -b 7M -t 30 50 balanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/7Mbps/UDP)(30 sec)(single-ue) - -u -b 7M -t 30 -i 1 + -u -b 7M -t 30 50 - single-ue - UL adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/7Mbps/UDP)(30 sec)(unbalanced) - -u -b 7M -t 30 -i 1 + -u -b 7M -t 30 50 unbalanced - UL adb_ue_1 adb_ue_2 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec)(single-ue) - -t 30 -i 1 -fm - 50 - single-ue - UL + -t 30 adb_ue_1 + ltebox-nano Iperf iperf (20MHz - UL/TCP)(30 sec) - -t 30 -i 1 -fm - 50 - UL + -t 30 adb_ue_1 adb_ue_2 + ltebox-nano diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_cleanup.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_cleanup.xml new file mode 100644 index 0000000000..01c89ae585 --- /dev/null +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_cleanup.xml @@ -0,0 +1,54 @@ + + + images-clean-up + Images Clean-Up + trash + +111111 +222222 +333333 + + + + + Detach_UE + Detach UE + up2 + + + + Undeploy_Object + Undeploy eNB + ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2 + 0 + 0 + + + + Clean_Test_Server_Images + Clean Test Images + 0 + + + diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml index 7bec0f8a83..8334ca49d1 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml @@ -106,23 +106,21 @@ Iperf iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) - -u -b 26M -t 60 - DL + -u -b 26M -t 60 -R up2 + porcepix-cn4g 5 95 - single-ue Iperf iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) -u -b 7M -t 60 - UL up2 + porcepix-cn4g 5 95 - single-ue diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml index f57b77648c..bee8c9eba5 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml @@ -106,23 +106,21 @@ Iperf iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) - -u -b 1M -t 60 - DL + -u -b 1M -t 60 -R up2 + porcepix-cn4g 5 95 - single-ue Iperf iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) -u -b 7M -t 60 - UL up2 + porcepix-cn4g 5 95 - single-ue diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index 220b646f25..98eb70a808 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -186,32 +186,29 @@ Iperf iperf (DL/70Mbps/UDP)(60 sec)(single-ue profile) - -u -b 70M -t 60 -i 1 -fm - DL + -u -b 70M -t 60 -R idefix + ltebox-nepes 25 80 - single-ue Iperf iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) - -u -b 8M -t 60 -i 1 -fm - UL + -u -b 8M -t 60 idefix + ltebox-nepes 1 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR idefix - single-ue + ltebox-nepes diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index 51817790dd..42ceb07530 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -98,7 +98,7 @@ Iperf iperf (DL/UDP/80M)(30 sec)(single-ue profile) -u -b 80M -t 30 -R - IPERF3 + porcepix-cn5g sphex_quectel 25 80 @@ -108,7 +108,7 @@ Iperf iperf (UL/UDP/40M)(30 sec)(single-ue profile) -u -b 40M -t 30 - IPERF3 + porcepix-cn5g sphex_quectel 25 80 diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml index 2a84098875..23ecc5195e 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_cleanup.xml @@ -25,12 +25,21 @@ CleanUp AERIAL trash + 000000 111111 222222 333333 + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_gnb_aerial + 0 + 0 + + Clean_Test_Server_Images Clean Test Images on Test Server diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 10170885f0..3885fbdd8e 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -49,6 +49,8 @@ 000010 000020 002016 + 000030 + 000040 000200 003000 004000 @@ -171,23 +173,42 @@ Iperf iperf (DL/7Mbps/UDP)(30 sec)(multi-ue profile) - -u -b 70M -t 30 -i 1 -R - IPERF3 + -u -b 70M -t 30 -R amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 balanced + oc-cn5g + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 4 + oc-cn5g Iperf iperf (UL/3.6Mbps/UDP)(30 sec)(multi-ue profile) - -u -b 36M -t 30 -i 1 - IPERF3 + -u -b 36M -t 30 amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 25 80 balanced + oc-cn5g + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + oc-cn5g + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 1 + oc-cn5g diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml index 8c8daf9e04..0b90afeee3 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_cleanup.xml @@ -27,20 +27,29 @@ 111111 222222 + 333333 - Clean_Test_Server_Images - Clean Test Images on Test Server - 0 - - - Terminate_UE Terminate UE amarisoft_ue + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_aw2s_gnb + 0 + 0 + + + + Clean_Test_Server_Images + Clean Test Images on Test Server + 0 + + diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 0296ecfe93..7d139f46fe 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -36,6 +36,8 @@ 070000 070001 070002 + 070003 + 070004 060001 000002 060002 @@ -136,32 +138,47 @@ Iperf iperf (DL/30Mbps/UDP)(30 sec)(single-ue profile) - -u -b 30M -t 30 -i 1 -fm - DL + -u -b 30M -t 30 -R idefix + sabox-nepes 25 80 - single-ue Iperf iperf (UL/3.5Mbps/UDP)(30 sec)(single-ue profile) - -u -b 3.5M -t 30 -i 1 -fm - UL + -u -b 3.5M -t 30 idefix + sabox-nepes 1 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR idefix - single-ue + sabox-nepes + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + idefix + sabox-nepes + 40 + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + idefix + sabox-nepes + 10 diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index 541edb9172..af550ad4b6 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -37,6 +37,8 @@ 370001 370000 370002 + 370003 + 370004 360001 100002 360002 @@ -128,32 +130,47 @@ Iperf iperf (DL/80Mbps/UDP)(30 sec) - -u -b 80M -t 30 -i 1 -fm - DL + -u -b 80M -t 30 -R idefix + sabox-nepes 10 95 - single-ue Iperf iperf (UL/8Mbps/UDP)(30 sec) - -u -b 8M -t 30 -i 1 -fm - UL + -u -b 8M -t 30 idefix + sabox-nepes 1 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 20 --bidir - BIDIR idefix - single-ue + sabox-nepes + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + idefix + sabox-nepes + 30 + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + idefix + sabox-nepes + 15 diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index e473fdea10..9d9ff62012 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -49,6 +49,8 @@ 170001 170000 170002 + 170003 + 170004 110011 110002 100001 @@ -160,32 +162,47 @@ Iperf iperf (DL/50Mbps/UDP)(30 sec) - -u -b 50M -t 30 -i 1 -fm - DL + -u -b 50M -t 30 -R idefix + sabox-nepes 10 95 - single-ue Iperf iperf (UL/25Mbps/UDP)(30 sec) - -u -b 25M -t 30 -i 1 -fm - UL + -u -b 25M -t 30 idefix + sabox-nepes 1 95 - single-ue Iperf iperf (BIDIR TCP)(60 sec)(single-ue profile) -t 60 --bidir - BIDIR idefix - single-ue + sabox-nepes + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + idefix + sabox-nepes + 45 + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + idefix + sabox-nepes + 25 diff --git a/ci-scripts/xml_files/container_sa_n310_nrue.xml b/ci-scripts/xml_files/container_sa_n310_nrue.xml index ce7dd26b6d..c4dbb83410 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue.xml @@ -91,8 +91,8 @@ Iperf iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile) -u -b 20M -t 30 -i 1 -R - IPERF3 oai_ue_caracal + oc-cn5g 25 80 @@ -101,8 +101,8 @@ Iperf iperf (UL/5Mbps/UDP)(30 sec)(single-ue profile) -u -b 5M -t 30 -i 1 - IPERF3 oai_ue_caracal + oc-cn5g 25 80 diff --git a/ci-scripts/xml_files/container_sa_n310_nrue_cleanup.xml b/ci-scripts/xml_files/container_sa_n310_nrue_cleanup.xml index 0bac1e010b..035e38a40d 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue_cleanup.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue_cleanup.xml @@ -27,16 +27,34 @@ 111111 222222 + 333333 + 444444 + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/5g_sa_n310_gnb + 0 + 0 + + + + Undeploy_Object + Undeploy nr UE + ci-scripts/yaml_files/5g_sa_n310_nrue + 1 + 1 + + + Clean_Test_Server_Images Clean Test Images on Test Server 0 - + Clean_Test_Server_Images Clean Test Images on Test Server 1 diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index c826d93ce6..e1fb0f5318 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -36,6 +36,8 @@ 270000 270001 270002 + 270003 + 270004 260001 200002 260002 @@ -130,32 +132,47 @@ Iperf iperf (DL/80Mbps/UDP)(30 sec)(single-ue profile) - -u -b 80M -t 30 -i 1 -fm - DL + -u -b 80M -t 30 -R idefix + sabox-nepes 5 95 - single-ue Iperf iperf (UL/6Mbps/UDP)(30 sec)(single-ue profile) - -u -b 6M -t 30 -i 1 -fm - UL + -u -b 6M -t 30 idefix + sabox-nepes 1 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR idefix - single-ue + sabox-nepes + + + + Iperf + iperf (DL/TCP)(30 sec)(multi-ue profile) + -t 30 -R + idefix + sabox-nepes + 35 + + + + Iperf + iperf (UL/TCP)(30 sec)(multi-ue profile) + -t 30 + idefix + sabox-nepes + 5 diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml index df0f01488d..5ca01a196e 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml @@ -159,31 +159,25 @@ Iperf iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile) - -u -b 125M -t 60 - DL + -u -b 125M -t 60 -R nrmodule2_quectel 15 85 - single-ue Iperf iperf (UL/1Mbps/UDP)(20 sec)(single-ue profile) -u -b 3M -t 60 - UL nrmodule2_quectel 5 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR nrmodule2_quectel - single-ue diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml index e300bd7f1c..1a08d33ecf 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml @@ -158,23 +158,19 @@ Iperf iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile) - -u -b 125M -t 60 - DL + -u -b 125M -t 60 -R idefix 25 80 - single-ue Iperf iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) -u -b 8M -t 60 - UL idefix 1 95 - single-ue diff --git a/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml index 732dd3bb7d..261e2623dd 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel_attach_detach.xml @@ -124,21 +124,17 @@ Iperf iperf (DL/20Mbps/UDP)(60 sec)(single-ue profile) - -u -b 20M -t 60 - DL + -u -b 20M -t 60 -R idefix 50 - single-ue Iperf iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile) -u -b 3M -t 60 - UL idefix 50 - single-ue diff --git a/ci-scripts/xml_files/fr1_nsa_quectel_long.xml b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml index a37cbb4d72..cccbd3fa41 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel_long.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel_long.xml @@ -121,21 +121,17 @@ Iperf iperf (DL/20Mbps/UDP)(600 sec)(single-ue profile) - -u -b 20M -t 600 - DL + -u -b 20M -t 600 -R idefix 50 - single-ue Iperf iperf (UL/3Mbps/UDP)(600 sec)(single-ue profile) -u -b 3M -t 600 - UL idefix 50 - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml b/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml index 97a6404c55..5f02fd6026 100644 --- a/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml +++ b/ci-scripts/xml_files/fr1_sa_oaiue_b200.xml @@ -94,21 +94,17 @@ Iperf iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile) - -u -b 60M -t 60 - DL + -u -b 60M -t 60 -R oai_ue_obelix 5 - single-ue Iperf iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile) -u -b 3M -t 60 - UL oai_ue_obelix 5 - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml index a6e17c2473..37b36cf431 100644 --- a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml +++ b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml @@ -111,10 +111,8 @@ Iperf iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile) oai_ue_obelix - -u -b 60M -t 60 - DL + -u -b 60M -t 60 -R 5 - single-ue @@ -122,9 +120,7 @@ iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile) oai_ue_obelix -u -b 3M -t 60 - UL 5 - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml b/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml index 315674c9e6..8d8ce8160a 100644 --- a/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml +++ b/ci-scripts/xml_files/fr1_sa_oaiue_x300.xml @@ -96,10 +96,8 @@ Iperf iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile) oai_ue_obelix - -u -b 60M -t 60 - DL + -u -b 60M -t 60 -R 5 - single-ue @@ -107,9 +105,7 @@ iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile) oai_ue_obelix -u -b 3M -t 60 - UL 5 - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml index 2cc3909c38..63e9d4efc8 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel.xml @@ -131,32 +131,26 @@ Iperf iperf (DL/60Mbps/UDP)(60 sec)(single-ue profile) - -u -b 60M -t 60 - DL + -u -b 60M -t 60 -R nrmodule2_quectel 5 95 - single-ue Iperf iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) -u -b 7M -t 60 - UL nrmodule2_quectel 5 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR nrmodule2_quectel - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml index b348905fac..d6fe76b81e 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml @@ -120,32 +120,26 @@ Iperf iperf (DL/180Mbps/UDP)(60 sec)(single-ue profile) - -u -b 180M -t 60 - DL + -u -b 180M -t 60 -R nrmodule2_quectel 50 50 - single-ue Iperf iperf (UL/3Mbps/UDP)(60 sec)(single-ue profile) -u -b 3M -t 60 - UL nrmodule2_quectel 5 95 - single-ue Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir - BIDIR nrmodule2_quectel - single-ue diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml index 4679514317..f921f9658b 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml @@ -128,62 +128,50 @@ Iperf iperf (DL/10Mbps/UDP)(30 sec)(single-ue profile) - -u -b 10M -t 30 - DL + -u -b 10M -t 30 -R nrmodule2_quectel 5 95 - single-ue Iperf iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 - DL + -u -b 20M -t 30 -R nrmodule2_quectel 5 95 - single-ue Iperf iperf (DL/40Mbps/UDP)(30 sec)(single-ue profile) - -u -b 40M -t 30 - DL + -u -b 40M -t 30 -R nrmodule2_quectel 5 95 - single-ue Iperf iperf (DL/60Mbps/UDP)(30 sec)(single-ue profile) - -u -b 60M -t 30 - DL + -u -b 60M -t 30 -R nrmodule2_quectel 5 95 - single-ue Iperf iperf (DL/90Mbps/UDP)(30 sec)(single-ue profile) - -u -b 90M -t 30 - DL + -u -b 90M -t 30 -R nrmodule2_quectel 10 90 - single-ue Iperf iperf (DL/130Mbps/UDP)(30 sec)(single-ue profile) - -u -b 130M -t 30 - DL + -u -b 130M -t 30 -R nrmodule2_quectel 50 50 - single-ue diff --git a/ci-scripts/yaml_files/5g_rfsimulator/mini_nonrf_config.yaml b/ci-scripts/yaml_files/5g_rfsimulator/mini_nonrf_config.yaml index 037fa1e41e..10fb5bcdfd 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/mini_nonrf_config.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/mini_nonrf_config.yaml @@ -175,7 +175,7 @@ upf: support_features: enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off - remote_n6_gw: localhost # Dummy host since simple-switch does not use N6 GW + remote_n6_gw: 127.0.0.1 # Dummy host since simple-switch does not use N6 GW upf_info: sNssaiUpfInfoList: - sNssai: *embb_slice1 diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/mini_nonrf_config_3slices.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/mini_nonrf_config_3slices.yaml index 369eb6356a..589e8ab772 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_e1/mini_nonrf_config_3slices.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/mini_nonrf_config_3slices.yaml @@ -193,7 +193,7 @@ upf: support_features: enable_bpf_datapath: no # If "on": BPF is used as datapath else simpleswitch is used, DEFAULT= off enable_snat: yes # If "on": Source natting is done for UE, DEFAULT= off - remote_n6_gw: localhost # Dummy host since simple-switch does not use N6 GW + remote_n6_gw: 127.0.0.1 # Dummy host since simple-switch does not use N6 GW upf_info: sNssaiUpfInfoList: - sNssai: *embb_slice1 diff --git a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml index 32c862a5e3..c01a82dcc5 100644 --- a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml @@ -54,7 +54,7 @@ services: --continuous-tx -E --telnetsrv --telnetsrv.shrmod ci --gNBs.[0].min_rxtxtime 2 --gNBs.[0].do_CSIRS 1 --gNBs.[0].do_SRS 1 - --RUs.[0].att_rx 18 --RUs.[0].att_tx 18 + --RUs.[0].att_rx 14 --RUs.[0].att_tx 14 --log_config.global_log_options level,nocolor,time,line_num,function volumes: - ../../conf_files/gnb-du.sa.band78.106prb.usrpb200.conf:/opt/oai-gnb/etc/gnb.conf diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 8bac61eaf1..3dad62dda7 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -85,11 +85,9 @@ static const int tables_5_3_2[5][12] = { {32, 66, 132, 264, -1, -1, -1, -1, -1, -1, -1, -1} // 120FR2 }; -int get_supported_band_index(int scs, int band, int n_rbs) +int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs) { - int scs_index = scs; - if (band > 256) - scs_index++; + int scs_index = scs + freq_range; for (int i = 0; i < 12; i++) { if(n_rbs == tables_5_3_2[scs_index][i]) return i; @@ -224,7 +222,7 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_ // 38.101-1 section 6.2.2 // Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands int index = get_nr_table_idx(nr_band, scs); - int bw_index = get_supported_band_index(scs, nr_band, nb_ul); + int bw_index = get_supported_band_index(scs, nr_band > 256 ? FR2 : FR1, nb_ul); int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, bw_index) * 1000; float limit = frame_type == TDD ? 0.04 : 0.03; float rel_bw = (float) (2 * band_size_khz) / (float) (nr_bandtable[index].ul_max + nr_bandtable[index].ul_min); @@ -538,29 +536,36 @@ int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) } // Returns the corresponding row index of the NR table -int get_nr_table_idx(int nr_bandP, uint8_t scs_index) { +int get_nr_table_idx(int nr_bandP, uint8_t scs_index) +{ int scs_khz = 15 << scs_index; - int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; - for(int j = 0; j < sizeofArray(supplementary_bands); j++){ - if (nr_bandP == supplementary_bands[j]) - AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); + int supplementary_bands[] = {29, 75, 76, 80, 81, 82, 83, 84, 86, 89, 95}; + for(int j = 0; j < sizeofArray(supplementary_bands); j++) { + AssertFatal(nr_bandP != supplementary_bands[j], + "Band %d is a supplementary band (%d). This is not supported yet.\n", + nr_bandP, + supplementary_bands[j]); } - int i; for (i = 0; i < sizeofArray(nr_bandtable); i++) { - if ( nr_bandtable[i].band == nr_bandP && nr_bandtable[i].deltaf_raster == scs_khz ) + if (nr_bandtable[i].band == nr_bandP && nr_bandtable[i].deltaf_raster == scs_khz) break; } if (i == sizeofArray(nr_bandtable)) { - LOG_I(PHY, "not found same deltaf_raster == scs_khz, use only band and last deltaf_raster \n"); - for(i=sizeofArray(nr_bandtable)-1; i >=0; i--) - if ( nr_bandtable[i].band == nr_bandP ) + LOG_D(PHY, "Not found same deltaf_raster == scs_khz, use only band and last deltaf_raster \n"); + for(i = sizeofArray(nr_bandtable) - 1; i >= 0; i--) + if (nr_bandtable[i].band == nr_bandP) break; } - AssertFatal(i >= 0 && i < sizeofArray(nr_bandtable), "band is not existing: %d\n",nr_bandP); - LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); + AssertFatal(i >= 0 && i < sizeofArray(nr_bandtable), "band is not existing: %d\n", nr_bandP); + LOG_D(PHY, + "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", + i, + nr_bandtable[i].band, + nr_bandtable[i].dl_min, + nr_bandtable[i].ul_min); return i; } @@ -829,18 +834,6 @@ void get_samplerate_and_bw(int mu, } } -void get_K1_K2(int N1, int N2, int *K1, int *K2) -{ - // num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214 - if(N2 == N1 || N1 == 2) - *K1 = 2; - else if (N2 == 1) - *K1 = 5; - else - *K1 = 3; - *K2 = N2 > 1 ? 2 : 1; -} - // from start symbol index and nb or symbols to symbol occupation bitmap in a slot uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) { return ((1< realpath IMAGE=$1 -COREDUMP=$2 -SOURCES=$3 +COREDUMP=$(realpath $2) +SOURCES=$(realpath $3) set -x @@ -32,6 +33,9 @@ docker image inspect $IMAGE > /dev/null || exit 1 if [ $(grep "oai-gnb:" <<< $IMAGE) ] || [ $(grep "oai-gnb-aerial:" <<< $IMAGE) ]; then EXEC=bin/nr-softmodem TYPEPATH=oai-gnb +elif [ $(grep "oai-gnb-aw2s:" <<< $IMAGE) ]; then + EXEC=bin/nr-softmodem + TYPEPATH=oai-gnb-aw2s elif [ $(grep "oai-nr-ue:" <<< $IMAGE) ]; then EXEC=bin/nr-uesoftmodem TYPEPATH=oai-nr-ue diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 2f4fad4257..725e3a9919 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -254,9 +254,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*)); for (int id = 0; id < gNB->max_nb_srs; id++) { gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*)); + gNB->nr_srs_info[id]->srs_generated_signal = malloc16_clear(MAX_NUM_NR_SRS_AP * sizeof(c16_t *)); for(int ap=0; apnr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); + gNB->nr_srs_info[id]->srs_generated_signal[ap] = + malloc16_clear(fp->ofdm_symbol_size * MAX_NUM_NR_SRS_SYMBOLS * sizeof(c16_t)); } } @@ -513,7 +514,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, } fp->threequarter_fs = 0; - int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL); + int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL); gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index); nr_init_frame_parms(gNB_config, fp); diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index e5f28d1c50..666d92a87d 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -318,24 +318,19 @@ void nr_layer_mapping(int nbCodes, } } -void nr_ue_layer_mapping(int16_t *mod_symbs, - uint8_t n_layers, - uint32_t n_symbs, - int16_t **tx_layers) { - +void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, int sz, c16_t tx_layers[][sz]) +{ for (int i=0; i>15; - tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; + tx_layers[l][i] = c16mulRealShift(mod_symbs[n_layers * i + l], AMP, 15); } } } - -void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) +void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH) { - simde__m128i dft_in128[1][3240], dft_out128[1][3240]; - uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; + simde__m128i dft_in128[3240], dft_out128[3240]; + c16_t *dft_in0 = (c16_t *)dft_in128, *dft_out0 = (c16_t *)dft_out128; uint32_t i, ip; @@ -659,36 +654,32 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) } } -int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset) +c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec_matrix, uint8_t n_layers, int32_t re_offset) { - int32_t precodatatx_F = 0; + c16_t precodatatx_F = {0}; for (int al = 0; alchest_freq; @@ -81,20 +82,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, FILE *debug_ch_est; debug_ch_est = fopen("debug_ch_est.txt","w"); #endif - //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ul_id]; c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates; const int symbolSize = gNB->frame_parms.ofdm_symbol_size; - const int soffset = (Ns&3)*gNB->frame_parms.symbols_per_slot*symbolSize; + const int soffset = (Ns & 3) * gNB->frame_parms.symbols_per_slot*symbolSize; const int nushift = (p >> 1) & 1; - int ch_offset = symbolSize*symbol; + int ch_offset = symbolSize*symbol; const int symbol_offset = symbolSize*symbol; - const int k0 = bwp_start_subcarrier; const int nb_rb_pusch = pusch_pdu->rb_size; - LOG_D(PHY, "In %s: ch_offset %d, soffset %d, symbol_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", - __FUNCTION__, + LOG_D(PHY, "ch_offset %d, soffset %d, symbol_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n", ch_offset, soffset, symbol_offset, symbolSize, @@ -114,7 +112,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], - (int32_t *)pilot, + pilot, (1000 + p), 0, nb_rb_pusch, @@ -122,14 +120,14 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, pusch_pdu->dmrs_config_type); } else { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible - const uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2)); + const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2)); const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; - int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; + c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, (int32_t *)pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1); @@ -154,7 +152,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset]; - c16_t *ul_ch = &ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset]; + c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; memset(ul_ch,0,sizeof(*ul_ch)*symbolSize); #ifdef DEBUG_PUSCH @@ -235,7 +233,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // Revert delay pilot_cnt = 0; - ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; + ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP); c16_t *ul_inv_delay_table = gNB->frame_parms.delay_table[inv_delay_idx]; for (int n = 0; n < 3 * nb_rb_pusch; n++) { @@ -450,7 +448,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, } #ifdef DEBUG_PUSCH - ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; + ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset]; for (int idxP = 0; idxP < ceil((float)nb_rb_pusch * 12 / 8); idxP++) { for (int idxI = 0; idxI < 8; idxI++) { printf("%d\t%d\t", ul_ch[idxP * 8 + idxI].r, ul_ch[idxP * 8 + idxI].i); @@ -611,19 +609,21 @@ uint32_t calc_power(const int16_t *x, const uint32_t size) { return sum_x2/size - (sum_x/size)*(sum_x/size); } -int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const int32_t **srs_generated_signal, - int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int8_t *snr_per_rb, - int8_t *snr) { - +int nr_srs_channel_estimation( + const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t **srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] + [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int8_t *snr_per_rb, + int8_t *snr) +{ #ifdef SRS_DEBUG LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); #endif @@ -694,9 +694,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, uint16_t subcarrier_cdm = subcarrier; for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { - - int16_t generated_real = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].r; - int16_t generated_imag = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].i; + int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r; + int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i; int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r; int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index e3210552fc..cb1745b027 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -43,6 +43,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, unsigned char Ns, + int nl, unsigned short p, unsigned char symbol, int ul_id, @@ -72,18 +73,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, unsigned char symbol, uint32_t nb_re_pusch); -int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const int32_t **srs_generated_signal, - int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_freq[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<num_symbols)], - int32_t srs_estimated_channel_time[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int32_t srs_estimated_channel_time_shifted[][1<num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int8_t *snr_per_rb, - int8_t *snr); +int nr_srs_channel_estimation( + const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t **srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] + [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], + int8_t *snr_per_rb, + int8_t *snr); void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms, int *rxdataF_comp, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 17655b581a..82c55a1465 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -51,10 +51,10 @@ static const int wt2[12][2] = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}}; // complex conjugate of mod table -static const short nr_rx_mod_table[14] = - {0, 0, 23170, -23170, -23170, 23170, 23170, -23170, 23170, 23170, -23170, -23170, -23170, 23170}; -static const short nr_rx_nmod_table[14] = - {0, 0, -23170, 23170, 23170, -23170, -23170, 23170, -23170, -23170, 23170, 23170, 23170, -23170}; +static const c16_t nr_rx_mod_table[7] = + {{0, 0}, {23170, -23170}, {-23170, 23170}, {23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}}; +static const c16_t nr_rx_nmod_table[7] = + {{0, 0}, {-23170, 23170}, {23170, -23170}, {-23170, 23170}, {-23170, -23170}, {23170, 23170}, {23170, -23170}}; int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { if (dmrs_config_type == pusch_dmrs_type1) { @@ -67,7 +67,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) { int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, unsigned int *nr_gold_pusch, - int32_t *output, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, @@ -92,16 +92,21 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, for (int i=dmrs_offset; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[k<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(k<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + output[k] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PUSCH printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); - printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]); + printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", + i, + idx, + nr_gold_pusch[(i << 1) >> 5], + (((nr_gold_pusch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), + (((nr_gold_pusch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), + output[k].r, + output[k].i); #endif } @@ -115,11 +120,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, return(0); } - int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, unsigned int Ns, unsigned int *nr_gold_pdsch, - int32_t *output, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pdsch_rb, @@ -139,11 +143,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, if (ue->frame_parms.Ncp == NORMAL) { for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); - const short *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; + const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1); - ((int16_t *)output)[i << 1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1]; - ((int16_t *)output)[(i << 1) + 1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1]; + output[i] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PDSCH printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]); @@ -153,8 +156,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, nr_gold_pdsch[(i << 1) >> 5], (((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), - ((int16_t *)output)[i << 1], - ((int16_t *)output)[(i << 1) + 1]); + output[i].r, + output[i].i); #endif } } else { @@ -167,11 +170,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } - int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, unsigned int Ns, unsigned int *nr_gold_pdcch, - int32_t *output, + c16_t *output, unsigned short p, unsigned short nb_rb_coreset) { @@ -182,12 +184,17 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, if (p==2000) { for (int i=0; i<((nb_rb_coreset*6)>>1); i++) { idx = ((((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[i<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(i<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + output[i] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PDCCH if (i<8) - printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d addr %p\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); + printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", + i, + idx, + nr_gold_pdcch[(i << 1) >> 5], + (((nr_gold_pdcch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), + (((nr_gold_pdcch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), + output[i].r, + output[i].i); #endif } } @@ -195,8 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } - -int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) +void nr_pbch_dmrs_rx(const int symbol, const unsigned int *nr_gold_pbch, c16_t *output) { int m,m0,m1; uint8_t idx=0; @@ -217,18 +223,15 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) /// QPSK modulation for (m=m0; m>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1); - ((int16_t*)output)[(m-m0)<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[((m-m0)<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; - + output[m - m0] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; + #ifdef DEBUG_PBCH if (m<16) {printf("nr_gold_pbch[(m<<1)>>5] %x\n",nr_gold_pbch[(m<<1)>>5]); - printf("m %d output %d %d addr %p\n", m, ((int16_t*)output)[m<<1], ((int16_t*)output)[(m<<1)+1],&output[0]); + printf("m %d output %d %d\n", m, output[m].r, output[m].i); } #endif } - - return(0); } /*! @@ -237,7 +240,7 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output) \param length is number of RE in a OFDM symbol \param *output pointer to all ptrs RE in a OFDM symbol */ -void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order) +void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order) { uint8_t idx, b_idx; for (int i=0; i>b_idx)&1)<<(mod_order-j-1); } - output[i<<1] = nr_rx_mod_table[(offset+idx)<<1]; - output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1]; + output[i] = nr_rx_mod_table[offset + idx]; } } int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, - int16_t *dmrs_seq, - int32_t *output, + c16_t *dmrs_seq, + c16_t *output, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, @@ -278,19 +280,21 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB for (int i=dmrs_offset; i= MAX_INDEX_DMRS_UL_ALLOCATED_REs) index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1; @@ -149,79 +140,63 @@ int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) { * *********************************************************************/ -static int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, - unsigned int u, - unsigned int v, - unsigned int scaling, - unsigned int if_dmrs_seq) +static c16_t *base_sequence_36_or_larger(unsigned int Msc_RS, + unsigned int u, + unsigned int v, + unsigned int scaling, + unsigned int if_dmrs_seq) { - int16_t *rv_overbar; - unsigned int N_ZC, M_ZC; - double q_overbar, x; - unsigned int q,m,n; - + const unsigned int M_ZC = if_dmrs_seq ? dmrs_ul_allocated_res[Msc_RS] : ul_allocated_re[Msc_RS]; - if (if_dmrs_seq) - M_ZC = dmrs_ul_allocated_res[Msc_RS]; - else - M_ZC = ul_allocated_re[Msc_RS]; - + c16_t *rv_overbar = malloc16(IQ_SIZE * M_ZC); + AssertFatal(rv_overbar, "Fatal memory allocation problem \n"); - rv_overbar = malloc16(IQ_SIZE*M_ZC); - if (rv_overbar == NULL) { - msg("Fatal memory allocation problem \n"); - assert(0); - } + /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ + const unsigned int N_ZC = if_dmrs_seq ? dmrs_ref_ul_primes[Msc_RS] : ref_ul_primes[Msc_RS]; - if (if_dmrs_seq) - N_ZC = dmrs_ref_ul_primes[Msc_RS]; - else - N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ - - - q_overbar = N_ZC * (u+1)/(double)31; + const double q_overbar = N_ZC * (u + 1) / (double)31; /* q = (q_overbar + 1/2) + v.(-1)^(2q_overbar) */ + double q; if ((((int)floor(2*q_overbar))&1) == 0) - q = (int)(floor(q_overbar+.5)) - v; + q = floor(q_overbar + .5) - v; else - q = (int)(floor(q_overbar+.5)) + v; + q = floor(q_overbar + .5) + v; - for (n = 0; n < M_ZC; n++) { - m=n%N_ZC; - x = (double)q * m * (m+1)/N_ZC; - rv_overbar[2*n] = (int16_t)(floor(scaling*cos(M_PI*x))); /* cos(-x) = cos(x) */ - rv_overbar[2*n+1] = -(int16_t)(floor(scaling*sin(M_PI*x))); /* sin(-x) = -sin(x) */ + for (int n = 0; n < M_ZC; n++) { + const int m = n % N_ZC; + const double x = q * m * (m + 1) / N_ZC; + rv_overbar[n].r = (int16_t)(floor(scaling * cos(M_PI * x))); /* cos(-x) = cos(x) */ + rv_overbar[n].i = -(int16_t)(floor(scaling * sin(M_PI * x))); /* sin(-x) = -sin(x) */ } return rv_overbar; } -int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; -int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; +c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling) { /* prevent multiple calls, relevant when both UE & gNB initialize this */ static bool already_called = false; - if (already_called) return; + if (already_called) + return; already_called = true; - - unsigned int u,Msc_RS; unsigned int v = 0; // sequence hopping and group hopping are not supported yet - for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { - for (u=0; u < U_GROUP_NUMBER; u++) { + for (unsigned int Msc_RS = 0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { + for (unsigned int u = 0; u < U_GROUP_NUMBER; u++) { gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling); } } - for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { - for (u=0; u < U_GROUP_NUMBER; u++) { - gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); - } - } + for (unsigned int Msc_RS = INDEX_SB_LESS_32 + 1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { + for (unsigned int u = 0; u < U_GROUP_NUMBER; u++) { + gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); + } + } } -int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; void generate_ul_reference_signal_sequences(unsigned int scaling) { /* prevent multiple calls, relevant when both UE & gNB initialize this */ diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index 3ef9b30c28..9ed101f247 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -228,7 +228,7 @@ static const uint16_t ref_ul_primes[SRS_SB_CONF] = { }; /* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */ -extern int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; +extern c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF]; /* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */ static const char phi_M_ZC_6[6 * U_GROUP_NUMBER] = { @@ -524,9 +524,9 @@ static const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] = { }; /// PUSCH DMRS for transform precoding -extern int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; -extern int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; -int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res); +extern c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +extern c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +int get_index_for_dmrs_lowpapr_seq(int num_dmrs_res); void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling); void free_gnb_lowpapr_sequences(void); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 8d0391c255..8ed0988ba6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1450,16 +1450,13 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, uint8_t slot, unsigned char harq_pid) { - uint8_t aarx; - uint32_t bwp_start_subcarrier; - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id].harq_process->ulsch_pdu; NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id]; pusch_vars->dmrs_symbol = INVALID_VALUE; gNB->nbSymb = 0; - bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + uint32_t bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start) * NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; LOG_D(PHY,"pusch %d.%d : bwp_start_subcarrier %d, rb_start %d, first_carrier_offset %d\n", frame,slot,bwp_start_subcarrier, rel15_ul->rb_start, frame_parms->first_carrier_offset); LOG_D(PHY,"pusch %d.%d : ul_dmrs_symb_pos %x\n",frame,slot,rel15_ul->ul_dmrs_symb_pos); @@ -1477,11 +1474,12 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, if (pusch_vars->dmrs_symbol == INVALID_VALUE) pusch_vars->dmrs_symbol = symbol; - for (int nl=0; nlnrOfLayers; nl++) { + for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++) { uint32_t nvar_tmp = 0; nr_pusch_channel_estimation(gNB, slot, - get_dmrs_port(nl,rel15_ul->dmrs_ports), + nl, + get_dmrs_port(nl, rel15_ul->dmrs_ports), symbol, ulsch_id, bwp_start_subcarrier, @@ -1502,10 +1500,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, frame_parms->nb_antennas_rx, frame_parms->N_RB_UL, false); - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) - { - if (symbol == rel15_ul->start_symbol_index) - { + for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + if (symbol == rel15_ul->start_symbol_index) { pusch_vars->ulsch_power[aarx] = 0; pusch_vars->ulsch_noise_power[aarx] = 0; } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 7ffb5af0e7..56b08f2e1d 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1015,7 +1015,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, - nfapi_nr_pucch_pdu_t* pucch_pdu) { + nfapi_nr_pucch_pdu_t* pucch_pdu) +{ c16_t **rxdataF = gNB->common_vars.rxdataF; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; @@ -1607,14 +1608,15 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, // estimate CQI for MAC (from antenna port 0 only) // TODO this computation is wrong -> to be ignored at MAC for now - int SNRtimes10 = + int cqi = 0xff; + /*int SNRtimes10 = dB_fixed_times10(signal_energy_nodc((int32_t *)&rxdataF[0][soffset + (l2 * frame_parms->ofdm_symbol_size) + re_offset[0]], 12 * pucch_pdu->prb_size)) - (10 * gNB->measurements.n0_power_tot_dB); int cqi,bit_left; if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; - else cqi=(640+SNRtimes10)/5; + else cqi=(640+SNRtimes10)/5;*/ uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq; uci_pdu->pduBitmap=0; @@ -1638,8 +1640,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, LOG_D(PHY, "[DLSCH/PDSCH/PUCCH2] %d.%d HARQ payload (%d) = %d\n", frame, slot, i, uci_pdu->harq.harq_payload[i]); decodedPayload[0]>>=8; } - bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3); - uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<bit_len_harq - ((harq_bytes - 1) << 3); + uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1 << bit_left) - 1); LOG_D(PHY, "[DLSCH/PDSCH/PUCCH2] %d.%d HARQ payload (%d) = %d\n", frame, slot, i, uci_pdu->harq.harq_payload[i]); decodedPayload[0] >>= pucch_pdu->bit_len_harq; } @@ -1664,8 +1666,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255; decodedPayload[0]>>=8; } - bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3); - uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<bit_len_csi_part1-((csi_part1_bytes-1)<<3); + uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1 << bit_left) - 1); decodedPayload[0] = pucch_pdu->bit_len_csi_part1 < 64 ? decodedPayload[0] >> bit_left : 0; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index 3f0f70526e..0c84dbc87a 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -20,15 +20,16 @@ */ #ifndef __FILT16A_H__ #define __FILT16A_H__ -static const short filt16a_l0[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const c16_t filt16a_l0[8] = {{16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; static const short filt16a_mm0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0}; -static const short filt16a_r0[16] = {0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 0, 0, 0, 0}; +static const c16_t filt16a_r0[8] = {{0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {24576, 28672}, {0, 0}, {0, 0}}; -static const short filt16a_m0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, -12288, 0, 0, 0, 0}; +static const c16_t filt16a_m0[8] = + {{0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {-8192, -12288}, {0, 0}, {0, 0}}; -static const short filt16a_l1[16] = {20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const c16_t filt16a_l1[8] = {{20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; static const short filt16a_mm1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0}; @@ -36,11 +37,12 @@ static const short filt16a_ml1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, static const short filt16a_mr1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0}; -static const short filt16a_r1[16] = {0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 0, 0, 0, 0}; +static const c16_t filt16a_r1[8] = {{0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {20480, 24576}, {0, 0}, {0, 0}}; -static const short filt16a_m1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0}; +static const c16_t filt16a_m1[8] = + {{-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {-4096, -8192}, {0, 0}, {0, 0}}; -static const short filt16a_l2[16] = {24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const c16_t filt16a_l2[8] = {{24576, 20480}, {16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; static const short filt16a_mm2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0}; @@ -48,19 +50,21 @@ static const short filt16a_ml2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, static const short filt16a_mr2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0}; -static const short filt16a_r2[16] = {0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 0, 0, 0, 0}; +static const c16_t filt16a_r2[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {0, 0}, {0, 0}}; -static const short filt16a_m2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0}; +static const c16_t filt16a_m2[8] = + {{-8192, -4096}, {0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {0, 0}, {0, 0}}; -static const short filt16a_l3[16] = {28672, 24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const c16_t filt16a_l3[8] = {{28672, 24576}, {20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}; static const short filt16a_mm3[16] = {0, 0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; static const short filt16a_ml3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; -static const short filt16a_r3[16] = {0, 0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 0, 0, 0, 0}; +static const c16_t filt16a_r3[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {0, 0}, {0, 0}}; -static const short filt16a_m3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0}; +static const c16_t filt16a_m3[8] = + {{-12288, -8192}, {-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}}; static const short filt16a_l0_dc[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 297cd8130a..7b3f2f3f3d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -37,9 +37,10 @@ extern openair0_config_t openair0_cfg[]; -//#define DEBUG_PDSCH -//#define DEBUG_PDCCH -//#define DEBUG_PBCH +// #define DEBUG_PDSCH +// #define DEBUG_PDCCH +// #define DEBUG_PBCH(a...) printf(a) +#define DEBUG_PBCH(a...) //#define DEBUG_PRS_CHEST // To enable PRS Matlab dumps //#define DEBUG_PRS_PRINTS // To enable PRS channel estimation debug logs @@ -295,39 +296,39 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // Choose the interpolation filters switch (k_prime) { case 0: - fl = filt16a_l0; + fl = (short int *)filt16a_l0; fml = filt16a_mm0; fmm = filt16a_mm0; - fmr = filt16a_m0; - fm = filt16a_m0; - fr = filt16a_r0; + fmr = (short int *)filt16a_m0; + fm = (short int *)filt16a_m0; + fr = (short int *)filt16a_r0; break; case 1: - fl = filt16a_l1; + fl = (short int *)filt16a_l1; fml = filt16a_ml1; fmm = filt16a_mm1; fmr = filt16a_mr1; - fm = filt16a_m1; - fr = filt16a_r1; + fm = (short int *)filt16a_m1; + fr = (short int *)filt16a_r1; break; case 2: - fl = filt16a_l2; + fl = (short int *)filt16a_l2; fml = filt16a_ml2; fmm = filt16a_mm2; fmr = filt16a_mr2; - fm = filt16a_m2; - fr = filt16a_r2; + fm = (short int *)filt16a_m2; + fr = (short int *)filt16a_r2; break; case 3: - fl = filt16a_l3; + fl = (short int *)filt16a_l3; fml = filt16a_ml3; fmm = filt16a_mm3; fmr = filt16a_mm3; - fm = filt16a_m3; - fr = filt16a_r3; + fm = (short int *)filt16a_m3; + fr = (short int *)filt16a_r3; break; default: @@ -630,156 +631,89 @@ int nr_prs_channel_estimation(uint8_t gNB_id, return(0); } -int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const int symbol, + const int dmrss, + const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], + const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - int pilot[200] __attribute__((aligned(16))); - unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF; - int symbol_offset; - - uint8_t ssb_index=current_ssb->i_ssb; - uint8_t n_hf=current_ssb->n_hf; + AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; - AssertFatal(dmrss >= 0 && dmrss < 3, - "symbol %d is illegal for PBCH DM-RS \n", - dmrss); - - symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; unsigned int k = ue->frame_parms.Nid_cell % 4; -#ifdef DEBUG_PBCH - printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); -#endif + DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%d symbol %d\n", + proc->gNB_id, + ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp, + k, + symbol); // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); - + c16_t pilot[200] __attribute__((aligned(16))); + nr_pbch_dmrs_rx(dmrss, nr_gold_pbch, pilot); + c32_t computed_val = {0}; for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { int re_offset = ssb_offset; - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + c16_t *pil = pilot; + const c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; -#ifdef DEBUG_PBCH - printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL); - printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); - printf("rxF addr %p\n", rxF); -#endif - //if ((ue->frame_parms.N_RB_DL&1)==0) { + DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); + DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); // Treat first 2 pilots specially (left edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i); + DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); -#ifdef DEBUG_PBCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); -#endif - - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); + DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); -#ifdef DEBUG_PBCH - printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { - - // if (pilot_cnt == 30) - // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; } - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - pil += 2; + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - current_ssb->c_re += ch[0]; - current_ssb->c_im += ch[1]; - -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); + DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; } - - - //} - } - return(0); + return computed_val; } int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, @@ -794,33 +728,31 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int Ns = proc->nr_slot_rx; - int pilot[200] __attribute__((aligned(16))); - unsigned short k; - unsigned int pilot_cnt; - int16_t *pil, *rxF, *dl_ch; - const int16_t *fl, *fm, *fr; - int ch_offset,symbol_offset; + c16_t pilot[200] __attribute__((aligned(16))); //int slot_pbch; - uint8_t nushift; - nushift = ue->frame_parms.Nid_cell % 4; + const int nushift = ue->frame_parms.Nid_cell % 4; unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; - ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; + const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol; AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); - symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; + const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; - - k = nushift; - -#ifdef DEBUG_PBCH - printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); -#endif + const int k = nushift; + const c16_t *fl, *fm, *fr; + DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", + proc->gNB_id, + ch_offset, + ue->frame_parms.ofdm_symbol_size, + ue->frame_parms.Ncp, + Ns, + k, + symbol); switch (k) { case 0: @@ -903,136 +835,91 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); + nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot); for (int aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { int re_offset = ssb_offset; - pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + c16_t *pil = pilot; + c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; + c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset]; - memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size)); + memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); -#ifdef DEBUG_PBCH - printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL); - printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset); - printf("rxF addr %p\n", rxF); - printf("dl_ch addr %p\n",dl_ch); -#endif + DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL); + DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset); // Treat first 2 pilots specially (left edge) - int16_t ch[2]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + c16_t ch; + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; -#ifdef DEBUG_PBCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + ch = c16mulShift(*pil, rxF[re_offset], 15); - //for (int i= 0; i<8; i++) - //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); + DEBUG_PBCH("pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch = c16mulShift(*pil, rxF[re_offset], 15); - -#ifdef DEBUG_PBCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PBCH - printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + DEBUG_PBCH("pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i); + multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; dl_ch += 24; - for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) { - + for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { // if (pilot_cnt == 30) // rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)]; // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; + re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; dl_ch += 288; } - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fl, ch, dl_ch, 16); -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fl, - ch, - dl_ch, - 16); - - //for (int i= 0; i<8; i++) - // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); - - pil += 2; + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - multadd_real_vector_complex_scalar(fm, - ch, - dl_ch, - 16); - pil += 2; + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt + 1, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fm, ch, dl_ch, 16); + pil++; re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - -#ifdef DEBUG_PBCH - printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); -#endif - - multadd_real_vector_complex_scalar(fr, - ch, - dl_ch, - 16); - pil += 2; - re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; - dl_ch += 24; - + ch = c16mulShift(*pil, rxF[re_offset], 15); + DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", + pilot_cnt + 2, + rxF[re_offset].r, + rxF[re_offset].i, + ch.r, + ch.i, + pil->r, + pil->i); + multaddRealVectorComplexScalar(fr, ch, dl_ch, 16); + pil++; + re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; + dl_ch += 12; } if( dmrss == 2) // update time statistics for last PBCH symbol @@ -1117,7 +1004,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0], 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { @@ -1613,6 +1500,7 @@ void NFAPI_NR_DMRS_TYPE2_average_prb(NR_DL_FRAME_PARMS *frame_parms, } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, + int nl, unsigned short p, unsigned char symbol, unsigned char nscid, @@ -1655,21 +1543,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pilot[3280] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - nr_pdsch_dmrs_rx(ue, - Ns, - ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], - (int32_t *)pilot, - 1000 + p, - 0, - nb_rb_pdsch + rb_offset, - config_type); - - uint8_t nushift = 0; - if (config_type == NFAPI_NR_DMRS_TYPE1) { - nushift = (p >> 1) & 1; - } else { // NFAPI_NR_DMRS_TYPE2 - nushift = delta; - } + nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type); delay_t delay = {0}; @@ -1681,8 +1555,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("============================================\n"); #endif - c16_t *rxF = &rxdataF[aarx][symbol_offset + nushift]; - c16_t *dl_ch = (c16_t *)&dl_ch_estimates[p * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; + c16_t *rxF = &rxdataF[aarx][symbol_offset + delta]; + c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; memset(dl_ch, 0, sizeof(*dl_ch) * ue->frame_parms.ofdm_symbol_size); if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) { @@ -1724,7 +1598,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } #ifdef DEBUG_PDSCH - dl_ch = (c16_t *)&dl_ch_estimates[p * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; + dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset]; for (uint16_t idxP = 0; idxP < ceil((float)nb_rb_pdsch * 12 / 8); idxP++) { for (uint8_t idxI = 0; idxI < 8; idxI++) { printf("%4d\t%4d\t", dl_ch[idxP * 8 + idxI].r, dl_ch[idxP * 8 + idxI].i); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index f47d49f877..5b1e43f953 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -57,12 +57,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pdcch_dl_ch_estimates[][pdcch_est_size], c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); +c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const int symbol, + const int dmrss, + const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], + const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int estimateSz, @@ -77,6 +77,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, + int nl, unsigned short p, unsigned char symbol, unsigned char nscid, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 840577d296..c21a6a709f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -92,15 +92,15 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int, ue->measurements.rx_spatial_power, NUMBER_OF_CONNECTED_gNB_MAX, - frame_parms->nb_antenna_ports_gNB, - frame_parms->nb_antennas_rx, + cmax(frame_parms->nb_antenna_ports_gNB, 1), + cmax(frame_parms->nb_antennas_rx, 1), false); allocCast3D(rx_spatial_power_dB, unsigned short, ue->measurements.rx_spatial_power_dB, NUMBER_OF_CONNECTED_gNB_MAX, - frame_parms->nb_antenna_ports_gNB, - frame_parms->nb_antennas_rx, + cmax(frame_parms->nb_antenna_ports_gNB, 1), + cmax(frame_parms->nb_antennas_rx, 1), false); // signal measurements diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 60da51e885..fdd8b6acef 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -181,24 +181,24 @@ static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, @param phy_measurements Pointer to UE PHY measurements */ -void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, - int nbRx, - c16_t rxdataF_ext[][rx_size_symbol], - int32_t dl_ch_estimates_ext[][rx_size_symbol], - int32_t dl_ch_mag[][nbRx][rx_size_symbol], - int32_t dl_ch_magb[][nbRx][rx_size_symbol], - int32_t dl_ch_magr[][nbRx][rx_size_symbol], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_layers, - unsigned char symbol, - int length, - uint8_t first_symbol_flag, - unsigned char mod_order, - unsigned short nb_rb, - unsigned char output_shift, - PHY_NR_MEASUREMENTS *measurements); +static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, + int nbRx, + c16_t rxdataF_ext[][rx_size_symbol], + int32_t dl_ch_estimates_ext[][rx_size_symbol], + int32_t dl_ch_mag[][nbRx][rx_size_symbol], + int32_t dl_ch_magb[][nbRx][rx_size_symbol], + int32_t dl_ch_magr[][nbRx][rx_size_symbol], + int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int ***rho, + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_layers, + unsigned char symbol, + int length, + bool first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_NR_MEASUREMENTS *measurements); /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal @param dl_ch_estimates_ext Channel estimates in allocated RBs @@ -242,7 +242,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], unsigned char symbol, - unsigned char first_symbol_flag, + bool first_symbol_flag, unsigned char harq_pid, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size], @@ -434,7 +434,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //---------------------------------------------------------- if (meas_enabled) start_meas(&meas); - if (first_symbol_flag == 1) { + if (first_symbol_flag) { int32_t avg[MAX_ANT][MAX_ANT]; nr_dlsch_channel_level(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, avg, symbol, nb_re_pdsch, nb_rb_pdsch); int avgs = 0; @@ -734,24 +734,24 @@ void nr_dlsch_deinterleaving(uint8_t symbol, // Pre-processing for LLR computation //============================================================================================== -void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, - int nbRx, - c16_t rxdataF_ext[][rx_size_symbol], - int32_t dl_ch_estimates_ext[][rx_size_symbol], - int32_t dl_ch_mag[][nbRx][rx_size_symbol], - int32_t dl_ch_magb[][nbRx][rx_size_symbol], - int32_t dl_ch_magr[][nbRx][rx_size_symbol], - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_layers, - unsigned char symbol, - int length, - uint8_t first_symbol_flag, - unsigned char mod_order, - unsigned short nb_rb, - unsigned char output_shift, - PHY_NR_MEASUREMENTS *measurements) +static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, + int nbRx, + c16_t rxdataF_ext[][rx_size_symbol], + int32_t dl_ch_estimates_ext[][rx_size_symbol], + int32_t dl_ch_mag[][nbRx][rx_size_symbol], + int32_t dl_ch_magb[][nbRx][rx_size_symbol], + int32_t dl_ch_magr[][nbRx][rx_size_symbol], + int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int ***rho, + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_layers, + unsigned char symbol, + int length, + bool first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_NR_MEASUREMENTS *measurements) { @@ -1034,7 +1034,7 @@ void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, dl_ch128_2+=3; rho128+=3; } - if (first_symbol_flag==1) { + if (first_symbol_flag) { //rho_nm = H_arx_n.conj(H_arx_m) //rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][l*n_layers+atx][symbol*nb_rb*12] measurements->rx_correlation[0][aarx][l * n_layers + atx] = signal_energy(&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12],length); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 09ea85fbd4..c8c67c017f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -44,8 +44,8 @@ #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/TOOLS/tools_defs.h" -extern openair0_config_t openair0_cfg[]; //static nfapi_nr_config_request_t config_t; //static nfapi_nr_config_request_t* config =&config_t; int cnt=0; @@ -53,51 +53,16 @@ int cnt=0; // #define DEBUG_INITIAL_SYNCH #define DUMP_PBCH_CH_ESTIMATES 0 -// create a new node of SSB structure -NR_UE_SSB* create_ssb_node(uint8_t i, uint8_t h) { +// structure used for multiple SSB detection +typedef struct NR_UE_SSB { + uint i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) + uint n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 + double metric; // metric to order SSB hypothesis +} NR_UE_SSB; - NR_UE_SSB *new_node = (NR_UE_SSB*)malloc(sizeof(NR_UE_SSB)); - new_node->i_ssb = i; - new_node->n_hf = h; - new_node->c_re = 0; - new_node->c_im = 0; - new_node->metric = 0; - new_node->next_ssb = NULL; - - return new_node; -} - - -// insertion of the structure in the ordered list (highest metric first) -NR_UE_SSB* insert_into_list(NR_UE_SSB *head, NR_UE_SSB *node) { - - if (node->metric > head->metric) { - node->next_ssb = head; - head = node; - return head; - } - - NR_UE_SSB *current = head; - while (current->next_ssb !=NULL) { - NR_UE_SSB *temp=current->next_ssb; - if(node->metric > temp->metric) { - node->next_ssb = temp; - current->next_ssb = node; - return head; - } - else - current = temp; - } - current->next_ssb = node; - - return head; -} - - -void free_list(NR_UE_SSB *node) { - if (node->next_ssb != NULL) - free_list(node->next_ssb); - free(node); +static int ssb_sort(const void *a, const void *b) +{ + return ((NR_UE_SSB *)b)->metric - ((NR_UE_SSB *)a)->metric; } static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, @@ -107,76 +72,66 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc, { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_SSB *best_ssb = NULL; - NR_UE_SSB *current_ssb; - - uint8_t N_L = (frame_parms->Lmax == 4)? 4:8; - uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1; - - // loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection + const int N_L = (frame_parms->Lmax == 4) ? 4 : 8; + const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1; + NR_UE_SSB best_ssb[N_L * N_hf]; + NR_UE_SSB *current_ssb = best_ssb; + // loops over possible pbch dmrs cases to retrieve best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection + start_meas(&ue->dlsch_channel_estimation_stats); for (int hf = 0; hf < N_hf; hf++) { - for (int l = 0; l < N_L ; l++) { - - // initialization of structure - current_ssb = create_ssb_node(l,hf); - - start_meas(&ue->dlsch_channel_estimation_stats); + for (int l = 0; l < N_L; l++) { // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf - for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); - - current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im; - - // generate a list of SSB structures - if (best_ssb == NULL) - best_ssb = current_ssb; - else - best_ssb = insert_into_list(best_ssb,current_ssb); - + cd_t cumul = {0}; + for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) { + c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF); + csum(cumul, cumul, meas); + } + *current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)}; + current_ssb++; } } + qsort(best_ssb, N_L * N_hf, sizeof(NR_UE_SSB), ssb_sort); + stop_meas(&ue->dlsch_channel_estimation_stats); - NR_UE_SSB *temp_ptr = best_ssb; - bool ret = false; - while (!ret && temp_ptr != NULL) { - + const int nb_ant = frame_parms->nb_antennas_rx; + for (NR_UE_SSB *ssb = best_ssb; ssb < best_ssb + N_L * N_hf; ssb++) { start_meas(&ue->dlsch_channel_estimation_stats); // computing channel estimation for selected best ssb const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz]; - __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + __attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz]; + __attribute__((aligned(32))) c16_t dl_ch_estimates_time[nb_ant][frame_parms->ofdm_symbol_size]; for(int i=pbch_initial_symbol; ii_ssb,temp_ptr->n_hf,rxdataF); + nr_pbch_channel_estimation(ue, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + i, + i - pbch_initial_symbol, + ssb->i_ssb, + ssb->n_hf, + rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); fapiPbch_t result = {0}; - - int pbch_res = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF); - ret = pbch_res == 0; - - if (DUMP_PBCH_CH_ESTIMATES && ret) { - write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1); - write_output("pbch_ch_estimates_time.m", - "pbch_ch_estimates_time", - dl_ch_estimates_time, - frame_parms->nb_antennas_rx * frame_parms->ofdm_symbol_size, - 1, - 1); + if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) { + if (DUMP_PBCH_CH_ESTIMATES) { + write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1); + write_output("pbch_ch_estimates_time.m", + "pbch_ch_estimates_time", + dl_ch_estimates_time, + nb_ant * frame_parms->ofdm_symbol_size, + 1, + 1); + } + LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + return true; } - - temp_ptr=temp_ptr->next_ssb; } - free_list(best_ssb); - - if (ret) { - frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant; - LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); - } - return ret; + LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index); + return false; } nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa) @@ -394,11 +349,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i // send sync status to higher layers later when timing offset converge to target timing } - LOG_I(PHY, - "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", - ue->Mod_id, - openair0_cfg[0].rx_freq[0] + ue->common_vars.freq_offset, - ue->common_vars.freq_offset); + LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, ue->common_vars.freq_offset); } else { #ifdef DEBUG_INITIAL_SYNC LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index c58fd5888e..c83083080a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -397,7 +397,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], unsigned char symbol, - unsigned char first_symbol_flag, + bool first_symbol_flag, unsigned char harq_pid, uint32_t pdsch_est_size, int32_t dl_ch_estimates[][pdsch_est_size], diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 885fcd403a..0e511cd72b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -224,7 +224,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// int max_num_re = Nl*number_of_symbols*nb_rb*NR_NB_SC_PER_RB; - int32_t d_mod[max_num_re] __attribute__ ((aligned(16))); + c16_t d_mod[max_num_re] __attribute__((aligned(16))); nr_modulation(scrambled_output, // assume one codeword for the moment available_bits, @@ -245,7 +245,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4); - int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16))); + c16_t mod_dmrs[n_dmrs] __attribute((aligned(16))); /////////// //////////////////////////////////////////////////////////////////////// @@ -253,15 +253,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH layer mapping///////////////////////// /////////// + const int sz = available_bits / mod_order; + c16_t tx_layers[Nl][sz]; + memset(tx_layers, 0, sizeof(tx_layers)); - int16_t **tx_layers = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); - for (int nl=0; nltransform_precoding == transformPrecoder_enabled) { @@ -287,7 +281,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2); // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol - index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); + int index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); u = pusch_pdu->dfts_ofdm.low_papr_group_number; v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index]; @@ -303,7 +297,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ continue; - nr_dft(&y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); + nr_dft(&y[y_offset], &tx_layers[0][y_offset], nb_re_pusch); y_offset = y_offset + nb_re_pusch; @@ -321,7 +315,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, printf("NR_ULSCH_UE: available_bits: %u, mod_order: %d", available_bits,mod_order); for (int ll = 0; ll < (available_bits/mod_order); ll++) { - debug_symbols[ll] = ulsch_ue->y[ll]; + debug_symbols[ll] = ulsch_ue->y[ll]; } printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols); @@ -345,10 +339,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH RE mapping///////////////////////// /////////// - int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl; - int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *)); - for (int nl=0; nlN_RB_UL * 14 * NR_NB_SC_PER_RB * mod_order * Nl; + c16_t tx_precoding[Nl][encoded_length]; + memset(tx_precoding, 0, sizeof(tx_precoding)); for (int nl=0; nl < Nl; nl++) { uint8_t k_prime = 0; @@ -372,7 +365,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t is_ptrs_sym = 0; uint16_t dmrs_idx = 0, ptrs_idx = 0; - int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation + c16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation if ((ul_dmrs_symb_pos >> l) & 0x01) { is_dmrs_sym = 1; @@ -387,7 +380,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part // Perform this on gold sequence, not required when SC FDMA operation is done, LOG_D(PHY,"DMRS in symbol %d\n",l); - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + nr_modulation(pusch_dmrs[l][pusch_pdu->scid], + n_dmrs * 2, + DMRS_MOD_ORDER, + (int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated } else { dmrs_idx = 0; } @@ -397,7 +393,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; - nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs); + nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs); } } @@ -422,166 +418,149 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { // if transform precoding is enabled - if (pusch_pdu->transform_precoding == transformPrecoder_enabled) { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; - } else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; - } + const int tmp = Wt[l_prime[0]] * Wf[k_prime] * AMP; + if (pusch_pdu->transform_precoding == transformPrecoder_enabled) + tx_precoding[nl][sample_offsetF] = c16mulRealShift(dmrs_seq[dmrs_idx], tmp, 15); + else + tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_dmrs[dmrs_idx], tmp, 15); #ifdef DEBUG_PUSCH_MAPPING printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", - nl, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); + nl, + dmrs_idx, + l, + k, + k_prime, + n, + tx_precoding[nl][sample_offsetF].r, + tx_precoding[nl][sample_offsetF].i); #endif dmrs_idx++; k_prime++; - k_prime&=1; - n+=(k_prime)?0:1; - - } else if (is_ptrs == 1) { + k_prime &= 1; + n += (k_prime) ? 0 : 1; + + } else if (is_ptrs == 1) { uint16_t beta_ptrs = 1; // temp value until power control is implemented - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15; + tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * AMP, 15); ptrs_idx++; - } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { - if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1]; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1]; - } - else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *) y)[m<<1]; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *) y)[(m<<1) + 1]; - } + } else if (!is_dmrs_sym + || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { + if (pusch_pdu->transform_precoding == transformPrecoder_disabled) + tx_precoding[nl][sample_offsetF] = tx_layers[nl][m]; + else + tx_precoding[nl][sample_offsetF] = y[m]; #ifdef DEBUG_PUSCH_MAPPING printf("DATA: layer %d\t m %d\t l %d \t k %d \t tx_precoding: %d %d\n", - nl, m, l, k, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1], - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]); + nl, + m, + l, + k, + tx_precoding[nl][sample_offsetF].r, + tx_precoding[nl][sample_offsetF].i); #endif m++; } else { - ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = 0; - ((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = 0; + tx_precoding[nl][sample_offsetF] = (c16_t){0}; } if (++k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; - } //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) - }//for (l=start_symbol; lnb_antennas_tx; ap++) { - for (int l=start_symbol; lnb_antennas_tx; ap++) { + for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) { uint16_t k = start_sc; - for (int rb=0; rbTpmi; - - if (pmi == 0) {//unitary Precoding + for (int rb = 0; rb < nb_rb; rb++) { + // get pmi info + uint8_t pmi = pusch_pdu->Tpmi; + + if (pmi == 0) { // unitary Precoding if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC - if (apnrOfLayers) - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], - NR_NB_SC_PER_RB*sizeof(int32_t)); + if (ap < pusch_pdu->nrOfLayers) + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k], + NR_NB_SC_PER_RB * sizeof(c16_t)); else - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - 0, - NR_NB_SC_PER_RB*sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, NR_NB_SC_PER_RB * sizeof(int32_t)); } else { // RB does cross DC int neg_length = frame_parms->ofdm_symbol_size - k; int pos_length = NR_NB_SC_PER_RB - neg_length; - if (apnrOfLayers) { - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)], - neg_length*sizeof(int32_t)); - memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size], - &tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)], - pos_length*sizeof(int32_t)); + if (ap < pusch_pdu->nrOfLayers) { + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k], + neg_length * sizeof(c16_t)); + memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size], + &tx_precoding[ap][l * frame_parms->ofdm_symbol_size], + pos_length * sizeof(int32_t)); } else { - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k], - 0, - neg_length*sizeof(int32_t)); - memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size], - 0, - pos_length*sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, neg_length * sizeof(int32_t)); + memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size], 0, pos_length * sizeof(int32_t)); } } k += NR_NB_SC_PER_RB; if (k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } - } - else { - //get the precoding matrix weights: + } else { + // get the precoding matrix weights: const char *W_prec; switch (frame_parms->nb_antennas_tx) { - case 1://1 antenna port + case 1: // 1 antenna port W_prec = nr_W_1l_2p[pmi][ap]; break; - case 2://2 antenna ports - if (pusch_pdu->nrOfLayers == 1)//1 layer + case 2: // 2 antenna ports + if (pusch_pdu->nrOfLayers == 1) // 1 layer W_prec = nr_W_1l_2p[pmi][ap]; - else//2 layers + else // 2 layers W_prec = nr_W_2l_2p[pmi][ap]; break; - case 4://4 antenna ports - if (pusch_pdu->nrOfLayers == 1)//1 layer + case 4: // 4 antenna ports + if (pusch_pdu->nrOfLayers == 1) // 1 layer W_prec = nr_W_1l_4p[pmi][ap]; - else if (pusch_pdu->nrOfLayers == 2)//2 layers + else if (pusch_pdu->nrOfLayers == 2) // 2 layers W_prec = nr_W_2l_4p[pmi][ap]; - else if (pusch_pdu->nrOfLayers == 3)//3 layers + else if (pusch_pdu->nrOfLayers == 3) // 3 layers W_prec = nr_W_3l_4p[pmi][ap]; - else//4 layers + else // 4 layers W_prec = nr_W_4l_4p[pmi][ap]; break; default: - LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); + LOG_D(PHY, "Precoding 1,2, or 4 antenna ports are currently supported\n"); W_prec = nr_W_1l_2p[pmi][ap]; break; } - for (int i=0; iofdm_symbol_size + k; - int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); - ((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0]; - ((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1]; - + for (int i = 0; i < NR_NB_SC_PER_RB; i++) { + int32_t re_offset = l * frame_parms->ofdm_symbol_size + k; + txdataF[ap][re_offset] = nr_layer_precoder(encoded_length, tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset); if (++k >= frame_parms->ofdm_symbol_size) { k -= frame_parms->ofdm_symbol_size; } } } - } //RB loop + } // RB loop } // symbol loop - }// port loop + } // port loop - NR_UL_UE_HARQ_t *harq_process_ulsch=NULL; + NR_UL_UE_HARQ_t *harq_process_ulsch = NULL; harq_process_ulsch = &UE->ul_harq_processes[harq_pid]; harq_process_ulsch->status = SCH_IDLE; - - for (int nl = 0; nl < Nl; nl++) { - free_and_zero(tx_layers[nl]); - free_and_zero(tx_precoding[nl]); - } - free_and_zero(tx_layers); - free_and_zero(tx_precoding); - /////////// //////////////////////////////////////////////////////////////////////// } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c deleted file mode 100644 index 4012322111..0000000000 --- a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c +++ /dev/null @@ -1,100 +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 - */ - -/********************************************************************** -* -* FILENAME : pbch_nr.c -* -* MODULE : broacast channel -* -* DESCRIPTION : generation of pbch -* 3GPP TS 38.211 7.3.3 Physical broadcast channel -* -************************************************************************/ - -#include -#include -#include - -#include "PHY/defs.h" - -#define DEFINE_VARIABLES_PBCH_NR_H -#include "PHY/NR_REFSIG/pbch_nr.h" -#undef DEFINE_VARIABLES_PBCH_NR_H - -/******************************************************************* -* -* NAME : pseudo_random_gold_sequence -* -* PARAMETERS : -* -* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence -* -* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation -* Sequence generation -* -*********************************************************************/ - -#define NC (1600) -#define GOLD_LENGTH (31) - -uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit) -{ - int size = M_PN * sizeof(uint32_t); - int size_x = sizeof(int)*M_PN + size; - int *x1 = malloc(size_x); - int *x2 = malloc(size_x); - - if ((x1 == NULL) || (x2 == NULL)) { - msg("Fatal memory allocation problem \n"); - assert(0); - } - else { - bzero(x1, size_x); - bzero(x2, size_x); - } - - x1[0] = 1; - - for (n = 0; n < 31; n++) { - x2[n] = (cinit >> n) & 0x1; - } - - for (int n = 0; n < (NC+M_PN); n++) { - x1(n+31) = (x1(n+3) + x1(n))%2; - x2(n+31) = (x2(n+3) + x2(n+2) + x2(n+1) + x2(n))%2; - } - - int *c = calloc(size); - if (c != NULL) { - bzero(c, size); - } - else { - msg("Fatal memory allocation problem \n"); - assert(0); - } - - for (int n = 0; n < M_PN; n++) { - c(i) = (x1(n+NC) + x2(n+NC))%2; - } - - return c; -} diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 7323d27dbb..b2c0a6242b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -672,7 +672,15 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i *nid2 = pss_source; - LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est); + LOG_I(PHY, + "[UE] nr_synchro_time: Sync source (nid2) = %d, Peak found at pos %d, val = %ld (%d dB power over signal avg %d dB), ffo " + "%lf\n", + pss_source, + peak_position, + peak_value, + dB_fixed64(peak_value), + dB_fixed64(avg[pss_source]), + ffo_est); if (peak_value < 5*avg[pss_source]) return(-1); diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 6d1b775f44..4af545b931 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -179,13 +179,13 @@ uint16_t compute_n_b(frame_t frame_number, ***************************************************************************/ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, + c16_t **txdataF, uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, frame_t frame_number, - slot_t slot_number) { - + slot_t slot_number) +{ #ifdef SRS_DEBUG LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__); #endif @@ -371,20 +371,15 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, // For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols for (int k = 0; k < M_sc_b_SRS; k++) { - - double shift_real = cos(alpha_i * k); - double shift_imag = sin(alpha_i * k); - int16_t r_overbar_real = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k<<1]; - int16_t r_overbar_imag = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][(k<<1)+1]; + cd_t shift = {cos(alpha_i * k), sin(alpha_i * k)}; + const c16_t tmp = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k]; + cd_t r_overbar = {tmp.r, tmp.i}; // cos(x+y) = cos(x)cos(y) - sin(x)sin(y) - double r_real = (shift_real*r_overbar_real - shift_imag*r_overbar_imag) / sqrt_N_ap; + cd_t r = cdMul(shift, r_overbar); - // sin(x+y) = sin(x)cos(y) + cos(x)sin(y) - double r_imag = (shift_imag*r_overbar_real + shift_real*r_overbar_imag) / sqrt_N_ap; - - int32_t r_real_amp = ((int32_t) round((double) amp * r_real)) >> 15; - int32_t r_imag_amp = ((int32_t) round((double) amp * r_imag)) >> 15; + c16_t r_amp = {(((int32_t)round((double)amp * r.r / sqrt_N_ap)) >> 15), + (((int32_t)round((double)amp * r.i / sqrt_N_ap)) >> 15)}; #ifdef SRS_DEBUG int subcarrier_log = subcarrier-subcarrier_offset; @@ -394,10 +389,10 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, if(subcarrier_log%12 == 0) { LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12); } - LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(r_real_amp&0xFFFF), (int16_t)(r_imag_amp&0xFFFF)); + LOG_I(NR_PHY, "(%d) \t%i\t%i\n", subcarrier_log, r_amp.r, r_amp.i); #endif - *(c16_t *)&txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = (c16_t){r_real_amp, r_imag_amp}; + txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = r_amp; // Subcarrier increment subcarrier += K_TC; @@ -465,14 +460,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_ NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size; - if (generate_srs_nr(srs_config_pdu, - frame_parms, - (int32_t **)txdataF, - symbol_offset, - ue->nr_srs_info, - AMP, - proc->frame_tx, - proc->nr_slot_tx) + if (generate_srs_nr(srs_config_pdu, frame_parms, txdataF, symbol_offset, ue->nr_srs_info, AMP, proc->frame_tx, proc->nr_slot_tx) == 0) { return 0; } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index e8e2483474..a017d79730 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -133,7 +133,7 @@ static const uint16_t srs_max_number_cs[3] = {8, 12, 6}; int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, NR_DL_FRAME_PARMS *frame_parms, - int32_t **txdataF, + c16_t **txdataF, uint16_t symbol_offset, nr_srs_info_t *nr_srs_info, int16_t amp, diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index ac2ae3ac5e..0ec5f23b40 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -503,15 +503,15 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, Nid1 = GET_NID1(frame_parms->Nid_cell); LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); } - //#endif - - if (Nid1==N_ID_1_NUMBER) - return false; - + // #endif int re = 0; int im = 0; if (Nid1 == N_ID_1_NUMBER) { - LOG_I(PHY,"Failed to detect SSS after PSS\n"); + LOG_W(PHY, + "Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n", + *tot_metric, + SSS_METRIC_FLOOR_NR, + frame_parms->Nid_cell); return false; } d = (int16_t *)&d_sss[Nid2][Nid1]; @@ -524,7 +524,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing; LOG_W(NR_PHY, - "ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", + "SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", + frame_parms->Nid_cell, ffo_pss, (int)(ffo_pss * frame_parms->subcarrier_spacing), ffo_sss, diff --git a/openair1/PHY/TOOLS/readme.md b/openair1/PHY/TOOLS/readme.md index 626a43a780..0ad6347d58 100644 --- a/openair1/PHY/TOOLS/readme.md +++ b/openair1/PHY/TOOLS/readme.md @@ -55,18 +55,40 @@ For the new qt-based scope designed for NR, please consider the following: ## Troubleshoot Similar as with the Xforms-based scope, you should allow root to open X -windows: +windows if using Xorg: ``` xhost +si:localuser:root ``` -Furthermore, if you get the following error (might be followed by a -segfault) +If you run on Wayland (e.g., Gnome on Ubuntu 22), you might get this error: +``` +Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. +Authorization required, but no authorization protocol specified +qt.qpa.xcb: could not connect to display :0 +qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found. +This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. +``` + +We have to force the use of Wayland. Before that, make sure that the Qt-Wayland +plugin is installed. Also, there seems to be a problem with the qt5-gtk +platform theme, so remove it: +``` +sudo apt-get install qtwayland5 +sudo apt-get remove qt5-gtk-platformtheme +``` + +Now, force the Wayland plugin; also make sure to pass `-E` to sudo: +``` +sudo -E QT_QPA_PLATFORM=wayland ./nr-softmodem --sa -O --dqt +``` + +Furthermore, if you get the following warning, _followed by a segfault_ (i.e., +if it runs, you can ignore this) ``` QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0 ``` -You have to set the XDG runtime directory like one of the following options -(try in order): +You can set the XDG runtime directory like one of the following options (try in +order, keep `QT_QPA_PLATFORM` if necessary) ``` sudo -E XDG_RUNTIME_DIR=/run/user/0 ./nr-softmodem ... sudo -E XDG_RUNTIME_DIR=/tmp/runtime-root ./nr-softmodem ... diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index cd99eb497e..06e31542d5 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -183,6 +183,11 @@ extern "C" { return a.r * a.r + a.i * a.i; } + __attribute__((always_inline)) inline c16_t c16add(const c16_t a, const c16_t b) + { + return (c16_t){.r = (int16_t)(a.r + b.r), .i = (int16_t)(a.i + b.i)}; + } + __attribute__((always_inline)) inline c16_t c16sub(const c16_t a, const c16_t b) { return (c16_t) { .r = (int16_t) (a.r - b.r), @@ -309,6 +314,25 @@ The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$ */ void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N); + // Same with correct types + static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N) + { + // do 8 multiplications at a time + simd_q15_t *x_128 = (simd_q15_t *)in, *y_128 = (simd_q15_t *)out; + + // printf("alpha = %d,%d\n",alpha[0],alpha[1]); + const simd_q15_t alpha_r_128 = set1_int16(alpha.r); + const simd_q15_t alpha_i_128 = set1_int16(alpha.i); + for (unsigned int i = 0; i < N >> 3; i++) { + const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, x_128[i]); + const simd_q15_t yi = mulhi_s1_int16(alpha_i_128, x_128[i]); + const simd_q15_t tmp = simde_mm_loadu_si128(y_128); + simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp, simde_mm_unpacklo_epi16(yr, yi))); + const simd_q15_t tmp2 = simde_mm_loadu_si128(y_128); + simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp2, simde_mm_unpackhi_epi16(yr, yi))); + } + } + static __attribute__((always_inline)) inline void multadd_real_four_symbols_vector_complex_scalar(const int16_t *x, c16_t *alpha, c16_t *y) diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index ef3be45717..8bbb1f9d84 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -307,16 +307,6 @@ typedef struct { fapi_nr_ul_config_srs_pdu srs_config_pdu; } NR_UE_SRS; -// structure used for multiple SSB detection -typedef struct NR_UE_SSB { - uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8) - uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64 - uint32_t metric; // metric to order SSB hypothesis - uint32_t c_re; - uint32_t c_im; - struct NR_UE_SSB *next_ssb; -} NR_UE_SSB; - typedef struct UE_NR_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals int32_t amp[3][10]; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index e99bcddaba..3a7e2032b9 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -115,7 +115,7 @@ typedef enum{ typedef struct { uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS]; uint8_t srs_generated_signal_bits; - int32_t **srs_generated_signal; + c16_t **srs_generated_signal; nfapi_nr_srs_pdu_t srs_pdu; } nr_srs_info_t; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a7b9e5d120..47753c2448 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -951,7 +951,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) slot_rx, srs_pdu, gNB->nr_srs_info[i], - (const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal, + (const c16_t**)gNB->nr_srs_info[i]->srs_generated_signal, srs_received_signal, srs_estimated_channel_freq, srs_estimated_channel_time, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0c253bb198..79b390216e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -489,8 +489,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; - int m; - int first_symbol_flag=0; // We handle only one CW now if (!(NR_MAX_NB_LAYERS>4)) { @@ -523,13 +521,14 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, __attribute__((aligned(32))) int32_t rxdataF_comp[dlsch[0].Nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT]; memset(rxdataF_comp, 0, sizeof(rxdataF_comp)); - for (m = s0; m < (s0 +s1); m++) { + for (int m = s0; m < (s0 +s1); m++) { if (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << m)) { - for (uint8_t aatx=0; aatxNl; aatx++) {//for MIMO Config: it shall loop over no_layers - LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m); + for (int nl = 0; nl < dlsch0->Nl; nl++) { //for MIMO Config: it shall loop over no_layers + LOG_D(PHY,"PDSCH Channel estimation layer %d, slot %d, symbol %d\n", nl, nr_slot_rx, m); nr_pdsch_channel_estimation(ue, proc, - get_dmrs_port(aatx,dlsch0->dlsch_config.dmrs_ports), + nl, + get_dmrs_port(nl,dlsch0->dlsch_config.dmrs_ports), m, dlsch0->dlsch_config.nscid, dlsch0->dlsch_config.dlDmrsScramblingId, @@ -546,9 +545,9 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, int nr_frame_rx = proc->frame_rx; char filename[100]; for (uint8_t aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx); + sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, nl, aarx); int **dl_ch_estimates = ue->pdsch_vars[gNB_id]->dl_ch_estimates; - LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); + LOG_M(filename,"channel_F",&dl_ch_estimates[nl*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); } #endif } @@ -582,12 +581,10 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, int32_t log2_maxh = 0; start_meas(&ue->rx_pdsch_stats); - for (m = s0; m < (s1 + s0); m++) { - - if (m==first_symbol_with_data) - first_symbol_flag = 1; - else - first_symbol_flag = 0; + for (int m = s0; m < (s1 + s0); m++) { + bool first_symbol_flag = false; + if (m == first_symbol_with_data) + first_symbol_flag = true; uint8_t slot = 0; if(m >= ue->frame_parms.symbols_per_slot>>1) diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index b79f438e17..489931adcc 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -162,7 +162,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, else fp->nr_band = 78; fp->threequarter_fs= 0; - int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL); + int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL); gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index); fp->ofdm_offset_divisor = UINT_MAX; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b252f1cdd4..374234e55d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -776,7 +776,7 @@ int main(int argc, char *argv[]) AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); - int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); + int index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB / 2) * nb_rb); AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); dmrs_config_type = pusch_dmrs_type1; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c index 235387acf7..ce52eb1f56 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c @@ -78,8 +78,8 @@ void generate_reference_signals(void) assert(0); } for (int n=0; nsrs_nr.p_SRS_ResourceSetList[0]->p_srs_ResourceList[0]; diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index aaa330ecb2..f95827ee09 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -239,14 +239,20 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + if (!cu_exists_f1_ue_data(cu_ue_f1ap_id)) { + LOG_E(F1AP, "unknown CU UE ID %ld\n", cu_ue_f1ap_id); + return 1; + } + /* the RLC-PDCP does not transport the DU UE ID (yet), so we drop it here. * For the moment, let's hope this won't become relevant; to sleep in peace, * let's put an assert to check that it is the expected DU UE ID. */ f1_ue_data_t ue_data = cu_get_f1_ue_data(cu_ue_f1ap_id); - AssertFatal(ue_data.secondary_ue == du_ue_f1ap_id, - "unexpected DU UE ID %d received, expected it to be %ld\n", - ue_data.secondary_ue, - du_ue_f1ap_id); + if (ue_data.secondary_ue != du_ue_f1ap_id) { + LOG_E(F1AP, "unexpected DU UE ID %d received, expected it to be %ld\n", ue_data.secondary_ue, du_ue_f1ap_id); + return 1; + } /* mandatory */ /* SRBID */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 703ff05e32..c6d1b72422 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -494,6 +494,9 @@ typedef struct{ uint8_t li_bitlen[8]; uint8_t pmi_x1_bitlen[8]; uint8_t pmi_x2_bitlen[8]; + uint8_t pmi_i11_bitlen[8]; + uint8_t pmi_i12_bitlen[8]; + uint8_t pmi_i13_bitlen[8]; uint8_t cqi_bitlen[8]; } CSI_Meas_bitlen_t; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e9f052f20c..1980986144 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -3232,6 +3232,10 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, break; case NR_UL_DCI_FORMAT_0_1: + if (!UL_BWP) { + LOG_E(NR_MAC, "Error! Not possible to configure DCI format 01 without UL BWP.\n"); + return 0; + } /// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, ULSCH indicator 1 --16 size += 16; // Carrier indicator @@ -3385,6 +3389,10 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, case NR_DL_DCI_FORMAT_1_1: LOG_D(NR_MAC, "DCI_FORMAT 1_1 : pdsch_Config %p, pucch_Config %p\n", pdsch_Config, pucch_Config); + if (!DL_BWP) { + LOG_E(NR_MAC, "Error! Not possible to configure DCI format 11 without DL BWP.\n"); + return 0; + } // General note: 0 bits condition is ignored as default nbits is 0. // Format identifier size = 1; @@ -4733,29 +4741,30 @@ void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, } uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - nr_csi_report_t *csi_report) { + nr_csi_report_t *csi_report) +{ struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; uint8_t nb_allowed_ri, ri_bitlen; uint8_t ri_restriction = 0; if (codebookConfig == NULL) { - csi_report->csi_meas_bitlen.ri_bitlen=0; + csi_report->csi_meas_bitlen.ri_bitlen = 0; return ri_restriction; } // codebook type1 single panel - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){ + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present) { struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){ + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; nb_allowed_ri = number_of_bits_set(ri_restriction); ri_bitlen = ceil(log2(nb_allowed_ri)); - ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + ri_bitlen = ri_bitlen < 1 ? ri_bitlen : 1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen = ri_bitlen; } if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){ if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present == @@ -4767,8 +4776,8 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, nb_allowed_ri = number_of_bits_set(ri_restriction); ri_bitlen = ceil(log2(nb_allowed_ri)); - ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + ri_bitlen = ri_bitlen < 2 ? ri_bitlen : 2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen = ri_bitlen; } else { // more than 4 ports @@ -4778,7 +4787,7 @@ uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, nb_allowed_ri = number_of_bits_set(ri_restriction); ri_bitlen = ceil(log2(nb_allowed_ri)); - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + csi_report->csi_meas_bitlen.ri_bitlen = ri_bitlen; } } return ri_restriction; @@ -4894,145 +4903,171 @@ void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, } } -void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, - int *x1, int *x2, int rank, int codebook_mode) { - +static void set_bitlen_size_singlepanel(CSI_Meas_bitlen_t *csi_bitlen, int n1, int n2, int o1, int o2, int rank, int codebook_mode) +{ + int i = rank - 1; // Table 6.3.1.1.2-1 in 38.212 switch(rank){ case 1: - if(n2>1) { + if(n2 > 1) { if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_x2_bitlen[i] = 2; } else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 4; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2 / 2)); + csi_bitlen->pmi_x2_bitlen[i] = 4; } } else{ if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_x2_bitlen[i] = 2; } else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 4; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 4; } } + csi_bitlen->pmi_i13_bitlen[i] = 0; break; case 2: - if(n1*n2 == 2) { + if(n1 * n2 == 2) { if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 3; } - *x1 += 1; + csi_bitlen->pmi_i13_bitlen[i] = 1; } else { - if(n2>1) { + if(n2 > 1) { if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 3; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 3; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2 / 2)); + csi_bitlen->pmi_x2_bitlen[i] = 3; } } else{ if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 3; } } - *x1 += 2; + csi_bitlen->pmi_i13_bitlen[i] = 2; } break; case 3: case 4: if(n1*n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_i13_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { if(n1*n2 >= 8) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1 / 2)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_i13_bitlen[i] = 2; + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_i13_bitlen[i] = 2; + csi_bitlen->pmi_x2_bitlen[i] = 1; } } break; case 5: case 6: - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_i13_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 1; break; case 7: case 8: if(n1 == 4 && n2 == 1) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2 / 2)); + csi_bitlen->pmi_i13_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { if(n1 > 2 && n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2 / 2)); + csi_bitlen->pmi_i13_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 1; } else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; + csi_bitlen->pmi_i11_bitlen[i] = ceil(log2(n1 * o1)); + csi_bitlen->pmi_i12_bitlen[i] = ceil(log2(n2 * o2)); + csi_bitlen->pmi_i13_bitlen[i] = 0; + csi_bitlen->pmi_x2_bitlen[i] = 1; } } break; default: AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n"); } + csi_bitlen->pmi_x1_bitlen[i] = csi_bitlen->pmi_i11_bitlen[i] + csi_bitlen->pmi_i12_bitlen[i] + csi_bitlen->pmi_i13_bitlen[i]; } void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, uint8_t ri_restriction, - nr_csi_report_t *csi_report) { - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - for(int i=0; i<8; i++) { - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0; - if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) + nr_csi_report_t *csi_report) +{ + NR_CodebookConfig_t *codebookConfig = csi_reportconfig->codebookConfig; + for(int i = 0; i < 8; i++) { + csi_report->csi_meas_bitlen.pmi_x1_bitlen[i] = 0; + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i] = 0; + if (codebookConfig == NULL || ((ri_restriction >> i) & 0x01) == 0) return; else { if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) { - if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { - if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present == + struct NR_CodebookConfig__codebookType__type1 *type1 = codebookConfig->codebookType.choice.type1; + if(type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *sp = type1->subType.choice.typeI_SinglePanel; + if(sp->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { csi_report->N1 = 1; csi_report->N2 = 1; - if (i==0) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2; - if (i==1) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1; + if (i == 0) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i] = 2; + if (i == 1) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i] = 1; } else { // more than two - int n1,n2,o1,o2,x1,x2; - get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo); - get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode); + int n1, n2, o1, o2; + get_n1n2_o1o2_singlepanel(&n1, &n2, &o1, &o2, sp->nrOfAntennaPorts.choice.moreThanTwo); + set_bitlen_size_singlepanel(&csi_report->csi_meas_bitlen, n1, n2, o1, o2, i + 1, type1->codebookMode); csi_report->N1 = n1; csi_report->N2 = n2; - csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode; - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2; + csi_report->codebook_mode = type1->codebookMode; } } else @@ -5117,7 +5152,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *cs if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; + nb_resources = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array; csi_report->CSI_Index_list = NULL; break; @@ -5190,14 +5225,14 @@ uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_rep } else { csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements uint16_t temp_bitlen; - for (int i=0; i<8; i++) { + for (int i = 0; i < 8; i++) { temp_bitlen = (csi_meas_bitlen->cri_bitlen+ csi_meas_bitlen->ri_bitlen+ csi_meas_bitlen->li_bitlen[i]+ csi_meas_bitlen->cqi_bitlen[i]+ csi_meas_bitlen->pmi_x1_bitlen[i]+ csi_meas_bitlen->pmi_x2_bitlen[i]); - if(temp_bitlen>max_bitlen) + if(temp_bitlen > max_bitlen) max_bitlen = temp_bitlen; } csi_bitlen += max_bitlen; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 47cfc53d06..07d8ed4513 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -119,7 +119,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n"); mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR; int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->nr_band, + mac->nr_band > 256 ? FR2 : FR1, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); @@ -141,7 +141,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL; mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->nr_band, + mac->nr_band > 256 ? FR2 : FR1, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); @@ -263,7 +263,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2; int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - mac->nr_band, + mac->nr_band > 256 ? FR2 : FR1, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); @@ -288,7 +288,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN; int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoUL->frequencyBandList->list.array[0], + *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); @@ -779,11 +779,8 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, if (id == mac->lc_ordered_list.array[j]->lcid) break; } - if (j < mac->lc_ordered_list.count) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[j]; - asn_sequence_del(&mac->lc_ordered_list, j, 0); - free(lc_info); - } + if (j < mac->lc_ordered_list.count) + asn_sequence_del(&mac->lc_ordered_list, j, 1); else LOG_E(NR_MAC, "Element not present in the list, impossible to release\n"); } @@ -1302,10 +1299,10 @@ static void configure_dedicated_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP } if (dl_dedicated->pdcch_Config) { if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_release) { - for (int i = 0; pdcch->list_Coreset.count; i++) - asn_sequence_del(&pdcch->list_Coreset, i, 1); - for (int i = 0; pdcch->list_SS.count; i++) - asn_sequence_del(&pdcch->list_SS, i, 1); + for (int i = pdcch->list_Coreset.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_Coreset, i - 1, 1); + for (int i = pdcch->list_SS.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_SS, i - 1, 1); } if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_setup) configure_ss_coreset(pdcch, dl_dedicated->pdcch_Config->choice.setup); @@ -2060,10 +2057,10 @@ void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index) NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; release_common_ss_cset(pdcch); - for (int i = 0; pdcch->list_Coreset.count; i++) - asn_sequence_del(&pdcch->list_Coreset, i, 1); - for (int i = 0; pdcch->list_SS.count; i++) - asn_sequence_del(&pdcch->list_SS, i, 1); + for (int i = pdcch->list_Coreset.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_Coreset, i - 1, 1); + for (int i = pdcch->list_SS.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_SS, i - 1, 1); } void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c index ed5abb5846..0a8a20dd74 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c @@ -141,7 +141,7 @@ static void sl_prepare_phy_config(int module_id, AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL"); int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing, - sl_band, + sl_band > 256 ? FR2 : FR1, carriercfg->carrierBandwidth); phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index); diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index be7f83bf92..a7185ee7d2 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -231,11 +231,8 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, mac->coreset0); asn1cFreeStruc(asn_DEF_NR_SI_SchedulingInfo, mac->si_SchedulingInfo); asn1cFreeStruc(asn_DEF_NR_TDD_UL_DL_ConfigCommon, mac->tdd_UL_DL_ConfigurationCommon); - for (int i = 0; i < mac->lc_ordered_list.count; i++) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; - asn_sequence_del(&mac->lc_ordered_list, i, 0); - free(lc_info); - } + for (int i = mac->lc_ordered_list.count; i > 0 ; i--) + asn_sequence_del(&mac->lc_ordered_list, i - 1, 1); } asn1cFreeStruc(asn_DEF_NR_CrossCarrierSchedulingConfig, sc->crossCarrierSchedulingConfig); @@ -263,10 +260,10 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, // release dedicated BWP0 config NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[0]; NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[0]; - for (int i = 0; pdcch->list_Coreset.count; i++) - asn_sequence_del(&pdcch->list_Coreset, i, 1); - for (int i = 0; pdcch->list_SS.count; i++) - asn_sequence_del(&pdcch->list_SS, i, 1); + for (int i = pdcch->list_Coreset.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_Coreset, i - 1, 1); + for (int i = pdcch->list_SS.count; i > 0 ; i--) + asn_sequence_del(&pdcch->list_SS, i - 1, 1); asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config); NR_UE_UL_BWP_t *ubwp = mac->ul_BWPs.array[0]; asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, ubwp->pucch_Config); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 2fd47cc756..69cc9df9c3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -217,18 +217,21 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, 0); } - rel15->dci_length_options[i] = nr_dci_size(current_DL_BWP, - current_UL_BWP, - sc_info, - mac->pdsch_HARQ_ACK_Codebook, - &mac->def_dci_pdu_rel15[dl_config->slot][dci_format], - dci_format, - rnti_type, - coreset, - dl_bwp_id, - ss->searchSpaceType->present, - mac->type0_PDCCH_CSS_config.num_rbs, - alt_size); + uint16_t dci_size = nr_dci_size(current_DL_BWP, + current_UL_BWP, + sc_info, + mac->pdsch_HARQ_ACK_Codebook, + &mac->def_dci_pdu_rel15[dl_config->slot][dci_format], + dci_format, + rnti_type, + coreset, + dl_bwp_id, + ss->searchSpaceType->present, + mac->type0_PDCCH_CSS_config.num_rbs, + alt_size); + if (dci_size == 0) + return; + rel15->dci_length_options[i] = dci_size; } rel15->BWPStart = coreset_id == 0 ? mac->type0_PDCCH_CSS_config.cset_start_rb : current_DL_BWP->BWPStart; diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index b2ba4c77a4..29b4434405 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -67,6 +67,111 @@ c16_t convert_precoder_weight(double complex c_in) return (c16_t) {.r = (short)cr, .i = (short)ci}; } +void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers) +{ + // num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214 + switch (layers) { + case 1: + *K1 = 1; + *K2 = 1; + break; + case 2: + *K2 = N2 == 1 ? 1 : 2; + if(N2 == N1 || N1 == 2) + *K1 = 2; + else if (N2 == 1) + *K1 = 4; + else + *K1 = 3; + break; + case 3: + case 4: + *K2 = N2 == 1 ? 1 : 2; + if (N1 == 6) + *K1 = 5; + else + *K1 = N1; + break; + default: + AssertFatal(false, "Number of layers %d not supported\n", layers); + } +} + +int precoding_weigths_generation(nfapi_nr_pm_list_t *mat, + int pmiq, + int L, + int N1, + int N2, + int O1, + int O2, + int num_antenna_ports, + double complex theta_n[4], + double complex v_lm[N1 * O1 + 4 * O1][N2 * O2 + O2][N2 * N1]) +{ + // Table 5.2.2.2.1-X: + // Codebook for L-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS + // pmi=1,...,pmi_size are computed as follows + int K1 = 0, K2 = 0; + get_K1_K2(N1, N2, &K1, &K2, L); + int I2 = L == 1 ? 4 : 2; + for (int k2 = 0; k2 < K2; k2++) { + for (int k1 = 0; k1 < K1; k1++) { + for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 + for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 + for (int nn = 0; nn < I2; nn++) { // i_2 + mat->pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix + mat->pmi_pdu[pmiq].numLayers = L; + mat->pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; + LOG_D(PHY, "layer %d Codebook pmiq = %d\n", L, pmiq); + for (int j_col = 0; j_col < L; j_col++) { + int llc = ll + (k1 * O1 * (j_col & 1)); + int mmc = mm + (k2 * O2 * (j_col & 1)); + double complex phase_sign = j_col <= ((L - 1) / 2) ? 1 : -1; + double complex res_code; + for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &mat->pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(L * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "%d Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + L, + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { + nfapi_nr_pm_weights_t *weights = &mat->pmi_pdu[pmiq].weights[j_col][i_rows]; + res_code = sqrt(1 / (double)(L * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; + c16_t precoder_weight = convert_precoder_weight(res_code); + weights->precoder_weight_Re = precoder_weight.r; + weights->precoder_weight_Im = precoder_weight.i; + LOG_D(PHY, + "%d Layer Precoding Matrix[pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", + L, + pmiq, + i_rows, + j_col, + creal(res_code), + cimag(res_code), + weights->precoder_weight_Re, + weights->precoder_weight_Im); + } + } + pmiq++; + } + } + } + } + } + return pmiq; +} + nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPorts_t antenna_ports) { int num_antenna_ports = antenna_ports.N1 * antenna_ports.N2 * antenna_ports.XP; @@ -88,28 +193,27 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort int O2 = N2 > 1 ? 4 : 1; //Vertical beam oversampling (1 or 4) int O1 = num_antenna_ports > 2 ? 4 : 1; //Horizontal beam oversampling (1 or 4) - int K1, K2; - get_K1_K2(N1, N2, &K1, &K2); - int max_mimo_layers = (num_antenna_ports < NR_MAX_NB_LAYERS) ? num_antenna_ports : NR_MAX_NB_LAYERS; AssertFatal(max_mimo_layers <= 4, "Max number of layers supported is 4\n"); + AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); - gNB->precoding_matrix_size[0] = N1 * O1 * N2 * O2 * 4; - nfapi_nr_pm_list_t mat = {.num_pm_idx = gNB->precoding_matrix_size[0]}; - for (int i = 1; i < max_mimo_layers; i++) { - gNB->precoding_matrix_size[i] = 2 * N1 * O1 * N2 * O2 * K1 * K2; + int K1 = 0, K2 = 0; + nfapi_nr_pm_list_t mat = {.num_pm_idx = 0}; + for (int i = 0; i < max_mimo_layers; i++) { + get_K1_K2(N1, N2, &K1, &K2, i + 1); + int i2_size = i == 0 ? 4 : 2; + gNB->precoding_matrix_size[i] = i2_size * N1 * O1 * N2 * O2 * K1 * K2; mat.num_pm_idx += gNB->precoding_matrix_size[i]; } - nfapi_nr_pm_pdu_t *pmi_pdu = malloc16(mat.num_pm_idx * sizeof(*pmi_pdu)); - AssertFatal(pmi_pdu != NULL, "out of memory\n"); - mat.pmi_pdu = pmi_pdu; + mat.pmi_pdu = malloc16(mat.num_pm_idx * sizeof(*mat.pmi_pdu)); + AssertFatal(mat.pmi_pdu != NULL, "out of memory\n"); // Generation of codebook Type1 with codebookMode 1 (num_antenna_ports < 16) - AssertFatal(num_antenna_ports < 16, "Max number of antenna ports supported is currently 16\n"); + // Generate DFT vertical beams // ll: index of a vertical beams vector (represented by i1_1 in TS 38.214) - const int max_l = N1 * O1 + (K1 - 1) * O1; + const int max_l = N1 * O1 + 4 * O1; // max k1 is 4*O1 double complex v[max_l][N1]; for (int ll = 0; ll < max_l; ll++) { // i1_1 for (int nn = 0; nn < N1; nn++) { @@ -119,7 +223,7 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort } // Generate DFT Horizontal beams // mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214) - const int max_m = N2 * O2 + (K2 - 1) * O2; + const int max_m = N2 * O2 + O2; // max k2 is O2 double complex u[max_m][N2]; for (int mm = 0; mm < max_m; mm++) { // i1_2 for (int nn = 0; nn < N2; nn++) { @@ -155,268 +259,10 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort } } - double complex res_code; - - // Table 5.2.2.2.1-5: int pmiq = 0; - // Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int nn = 0; nn < 4; nn++) { - pmiq = ll * N2 * O2 * 4 + mm * 4 + nn; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 1; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 1 Codebook pmiq = %d\n", pmiq); - for (int len = 0; len < N1 * N2; len++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; - res_code = sqrt(1 / (double)num_antenna_ports) * v_lm[ll][mm][len]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - len, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } + for (int layers = 1; layers <= max_mimo_layers; layers++) + pmiq = precoding_weigths_generation(&mat, pmiq, layers, N1, N2, O1, O2, num_antenna_ports, theta_n, v_lm); - for (int len = N1 * N2; len < 2 * N1 * N2; len++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[0][len]; - res_code = sqrt(1 / (double)num_antenna_ports) * theta_n[nn] * v_lm[ll][mm][len - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - len, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - } - } - } - int llc = 0; - int mmc = 0; - double complex phase_sign = 0; - // Table 5.2.2.2.1-6: - // Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - // Compute the code book size for generating 2 layers out of Tx antenna ports - - // pmi=1,...,pmi_size, we construct - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 2; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 2 Codebook pmiq = %d\n", pmiq); - for (int j_col = 0; j_col < 2; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col == 1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(2 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - } - } - } - } - } - } - - if (max_mimo_layers < 3) - return mat; - - // Table 5.2.2.2.1-7: - // Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - - // pmi=1,...,pmi_size are computed as follows - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 3; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 3 Codebook pmiq = %d\n", pmiq); - for (int j_col = 0; j_col < 3; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col == 1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = 1; - } - if (j_col == 2) { - llc = ll; - mmc = mm; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(3 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(3 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - } - } - } - } - } - } - - if (max_mimo_layers < 4) - return mat; - - // Table 5.2.2.2.1-8: - // Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS - - for (int ll = 0; ll < N1 * O1; ll++) { // i_1_1 - for (int mm = 0; mm < N2 * O2; mm++) { // i_1_2 - for (int k1 = 0; k1 < K1; k1++) { - for (int k2 = 0; k2 < K2; k2++) { - for (int nn = 0; nn < 2; nn++) { // i_2 - pmiq++; - pmi_pdu[pmiq].pm_idx = pmiq + 1; // index 0 is the identity matrix - pmi_pdu[pmiq].numLayers = 4; - pmi_pdu[pmiq].num_ant_ports = num_antenna_ports; - LOG_D(PHY, "layer 4 pmiq = %d\n", pmiq); - for (int j_col = 0; j_col < 4; j_col++) { - if (j_col == 0) { - llc = ll; - mmc = mm; - phase_sign = 1; - } - if (j_col == 1) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = 1; - } - if (j_col == 2) { - llc = ll; - mmc = mm; - phase_sign = -1; - } - if (j_col == 3) { - llc = ll + k1 * O1; - mmc = mm + k2 * O2; - phase_sign = -1; - } - for (int i_rows = 0; i_rows < N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(4 * num_antenna_ports)) * v_lm[llc][mmc][i_rows]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - for (int i_rows = N1 * N2; i_rows < 2 * N1 * N2; i_rows++) { - nfapi_nr_pm_weights_t *weights = &pmi_pdu[pmiq].weights[j_col][i_rows]; - res_code = sqrt(1 / (double)(4 * num_antenna_ports)) * (phase_sign)*theta_n[nn] * v_lm[llc][mmc][i_rows - N1 * N2]; - c16_t precoder_weight = convert_precoder_weight(res_code); - weights->precoder_weight_Re = precoder_weight.r; - weights->precoder_weight_Im = precoder_weight.i; - LOG_D(PHY, - "4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d \n", - pmiq, - i_rows, - j_col, - creal(res_code), - cimag(res_code), - weights->precoder_weight_Re, - weights->precoder_weight_Im); - } - } - } - } - } - } - } return mat; } @@ -495,7 +341,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant // Carrier configuration struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoDL->frequencyBandList.list.array[0], + *frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1, bw_index); @@ -525,7 +371,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant } struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, - *frequencyInfoUL->frequencyBandList->list.array[0], + *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1, bw_index); @@ -762,8 +608,8 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant num_ssb++; } cfg->num_tlv++; - } - for (int i = 0; i < 32; i++) { + } + for (int i = 0; i < 32; i++) { cfg->ssb_table.ssb_beam_id_list[32 + i].beam_id.tl.tag = NFAPI_NR_CONFIG_BEAM_ID_TAG; if ((cfg->ssb_table.ssb_mask_list[1].ssb_mask.value >> (31 - i)) & 1) { cfg->ssb_table.ssb_beam_id_list[32 + i].beam_id.value = num_ssb; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 1a940b2da0..98d241388e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1112,7 +1112,7 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, int TBS = 0; while(TBS<7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented) mcsindex++; - AssertFatal(mcsindex<28,"Exceeding MCS limit for Msg3\n"); + AssertFatal(mcsindex <= 28, "Exceeding MCS limit for Msg3\n"); int R = nr_get_code_rate_ul(mcsindex,pusch_pdu->mcs_table); pusch_pdu->target_code_rate = R; pusch_pdu->qam_mod_order = nr_get_Qm_ul(mcsindex,pusch_pdu->mcs_table); @@ -1981,7 +1981,10 @@ static void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, s // Pause scheduling according to: // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, false); + // Msg4 may transmit a RRCReconfiguration, for example when UE sends RRCReestablishmentComplete and MAC CE for C-RNTI in Msg3. + // In that case, gNB will generate a RRCReconfiguration that will be transmitted in Msg4, so we need to apply CellGroup after the Ack, + // UE->apply_cellgroup was already set when processing RRCReestablishment message + nr_mac_enable_ue_rrc_processing_timer(RC.nrmac[module_id], UE, UE->apply_cellgroup); nr_clear_ra_proc(module_id, CC_id, frame, ra); if (sched_ctrl->retrans_dl_harq.head >= 0) { @@ -2160,8 +2163,6 @@ void nr_schedule_RA(module_id_t module_idP, case nrRA_Msg3_retransmission: nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra, ul_dci_req); break; - case nrRA_Msg3_dcch_dtch: - /* fallthrough */ case nrRA_Msg4: nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra, DL_req, TX_req); break; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 378c5a1de6..851b9e3faa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -130,6 +130,46 @@ uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, } +// Table 5.2.2.2.1-3 and Table 5.2.2.2.1-4 in 38.214 +void get_k1_k2_indices(const int layers, const int N1, const int N2, const int i13, int *k1, int *k2) +{ + AssertFatal(layers > 0 && layers < 5, "Number of layers %d not supported\n", layers); + *k1 = 0; + *k2 = 0; + if (layers == 2) { + if (N2 == 1) + *k1 = i13; + else if (N1 == N2) { + *k1 = i13 & 1; + *k2 = i13 >> 1; + } + else { + *k1 = (i13 & 1) + (i13 == 3); + *k2 = (i13 == 2); + } + } + if (layers == 3 || layers == 4) { + if (N2 == 1) + *k1 = i13 + 1; + else if (N1 == 2 && N2 == 2) { + *k1 = !(i13 & 1); + *k2 = (i13 > 0); + } + else { + if (i13 == 0) + *k1 = 1; + if (i13 == 1) + *k2 = 1; + if (i13 == 2) { + *k1 = 1; + *k2 = 1; + } + if (i13 == 3) + *k1 = 2; + } + } +} + uint16_t get_pm_index(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, nr_dci_format_t dci_format, @@ -138,14 +178,16 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac, { if (dci_format == NR_DL_DCI_FORMAT_1_0 || nrmac->identity_pm || xp_pdsch_antenna_ports == 1) return 0; //identity matrix (basic 5G configuration handled by PMI report is with XP antennas) - const NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id; const nr_csi_report_t *csi_report = &UE->csi_report_template[report_id]; const int N1 = csi_report->N1; const int N2 = csi_report->N2; const int antenna_ports = (N1 * N2) << 1; - const int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1; + if (antenna_ports < 2) + return 0; // single antenna port + + int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1; const int x2 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2; LOG_D(NR_MAC,"PMI report: x1 %d x2 %d layers: %d\n", x1, x2, layers); @@ -160,8 +202,37 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac, // elements from n+1 to m for 2 layers etc. if (antenna_ports == 2) return 1 + prev_layers_size + x2; // 0 for identity matrix - else - AssertFatal(1==0,"More than 2 antenna ports not yet supported\n"); + else { + int idx = layers - 1; + // the order of i1x in X1 report needs to be verified + // the standard is not very clear (Table 6.3.1.1.2-7 in 38.212) + // it says: PMI wideband information fields X1 , from left to right + int bitlen = csi_report->csi_meas_bitlen.pmi_i13_bitlen[idx]; + if (layers == 1 && bitlen != 0) { + LOG_E(NR_MAC, "Invalid i13 bit length %d for single layer! It should be 0\n", bitlen); + return 0; + } + const int i13 = x1 & ((1 << bitlen) - 1); + x1 >>= bitlen; + bitlen = csi_report->csi_meas_bitlen.pmi_i12_bitlen[idx]; + const int i12 = x1 & ((1 << bitlen) - 1); + x1 >>= bitlen; + bitlen = csi_report->csi_meas_bitlen.pmi_i11_bitlen[idx]; + const int i11 = x1 & ((1 << bitlen) - 1); + const int i2 = x2; + int k1, k2; + get_k1_k2_indices(layers, N1, N2, i13, &k1, &k2); // get indices k1 and k2 for PHY matrix (not actual k1 and k2 values) + const int O2 = N2 == 1 ? 1 : 4; + int O1 = 4; //Horizontal beam oversampling = 4 for more than 2 antenna ports + int max_i2 = 0; + int lay_index = 0; + max_i2 = layers == 1 ? 4 : 2; + int K1, K2; + get_K1_K2(N1, N2, &K1, &K2, layers); + // computing precoding matrix index according to rule set in allocation function init_codebook_gNB + lay_index = i2 + (i11 * max_i2) + (i12 * max_i2 * N1 * O1) + (k1 * max_i2 * N1 * O1 * N2 * O2) + (k2 * max_i2 * N1 * O1 * N2 * O2 * K1); + return 1 + prev_layers_size + lay_index; + } } uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx) @@ -1236,6 +1307,8 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, ss->searchSpaceType->present, cset0_bwp_size, alt_size); + if (dci_size == 0) + return; pdcch_dci_pdu->PayloadSizeBits = dci_size; AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index ad7286e8c1..fec85d5d4c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -761,12 +761,12 @@ static int evaluate_ri_report(uint8_t *payload, NR_UE_sched_ctrl_t *sched_ctrl) { uint8_t ri_index = pickandreverse_bits(payload, ri_bitlen, cumul_bits); - int count=0; - for (int i=0; i<8; i++) { - if ((ri_restriction>>i)&0x01) { + int count = 0; + for (int i = 0; i < 8; i++) { + if ((ri_restriction >> i) & 0x01) { if(count == ri_index) { sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri = i; - LOG_D(MAC,"CSI Reported Rank %d\n", i+1); + LOG_D(MAC,"CSI Reported Rank %d\n", i + 1); return i; } count++; @@ -821,8 +821,8 @@ static uint8_t evaluate_pmi_report(uint8_t *payload, //in case of 2 port CSI configuration x1 is empty and the information bits are in x2 int temp_pmi = pickandreverse_bits(payload, tot_bitlen, cumul_bits); - sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1 = temp_pmi&((1<CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2 = (temp_pmi>>x1_bitlen)&((1<CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1 = temp_pmi & ((1 << x1_bitlen) - 1); + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2 = (temp_pmi >> x1_bitlen) & ((1 << x2_bitlen) - 1); LOG_D(MAC,"PMI Report: X1 %d X2 %d\n", sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3ff19c131d..7ed78885ed 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -40,6 +40,26 @@ //#define SRS_IND_DEBUG +static rnti_t lcid_crnti_lookahead(uint8_t *pdu, int pdu_len) +{ + uint16_t mac_len = 0; + uint16_t mac_subheader_len = 0; + while (pdu_len >= 3) { + if ((pdu[0] & 0x3F) == UL_SCH_LCID_C_RNTI) { + // Extract C-RNTI value + rnti_t crnti = ((pdu[1] & 0xFF) << 8) | (pdu[2] & 0xFF); + LOG_D(NR_MAC, "Received a MAC CE for C-RNTI with %04x\n", crnti); + return crnti; + } + if (!get_mac_len(pdu, pdu_len, &mac_len, &mac_subheader_len)) { + break; + } + pdu += mac_len + mac_subheader_len; + pdu_len -= mac_len + mac_subheader_len; + } + return 0; +} + int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot) { /* we assume that this function is mutex-protected from outside */ @@ -220,26 +240,21 @@ static int nr_process_mac_pdu(instance_t module_idP, break; case UL_SCH_LCID_C_RNTI: - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; - if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) { - // remove UE context just created after Msg.3 in some milliseconds - // as the UE is one already known (not now, as the UE context is - // still needed for the moment) - nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); - //mac_remove_nr_ue(RC.nrmac[module_idP], ra->rnti); - // this UE is the one identified by the RNTI in pduP - ra->rnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); - ra->ra_state = nrRA_Msg3_dcch_dtch; + if (ra->ra_state == nrRA_gNB_IDLE && ra->rnti == UE->rnti) { + // Extract C-RNTI value + rnti_t crnti = ((pduP[1] & 0xFF) << 8) | (pduP[2] & 0xFF); + AssertFatal(false, + "Received MAC CE for C-RNTI %04x without RA running, procedure exists? Or is it a bug while decoding the " + "MAC PDU?\n", + crnti); break; } } - - //38.321 section 6.1.3.2 - //fixed length + // 38.321 section 6.1.3.2 + // fixed length mac_len = 2; - /* Extract CRNTI value */ break; case UL_SCH_LCID_SINGLE_ENTRY_PHR: @@ -310,39 +325,28 @@ static int nr_process_mac_pdu(instance_t module_idP, LOG_E(NR_MAC, "pdu_len %d is invalid (shorter than MAC PDU header)\n", pdu_len); return 0; } + LOG_D(NR_MAC, "UE %04x %d.%d: Received LCID %d bytes %d\n", UE->rnti, frameP, slot, rx_lcid, mac_len); - rnti_t crnti = UE->rnti; - NR_UE_info_t* UE_idx = UE; - for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { - NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; - if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == UE->rnti) { - uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len; - if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) { - crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF); - LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti); - UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti); - break; - } - } - } + AssertFatal(UE->CellGroup, + "UE %04x %d.%d: Received LCID %d which is not configured (UE has no CellGroup)\n", + UE->rnti, + frameP, + slot, + rx_lcid); - if (UE_idx->CellGroup) { - LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti); - UE->mac_stats.ul.total_sdu_bytes += mac_len; - mac_rlc_data_ind(module_idP, - crnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pduP + mac_subheader_len), - mac_len, - 1, - NULL); - } else { - AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid); - } + mac_rlc_data_ind(module_idP, + UE->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *)(pduP + mac_subheader_len), + mac_len, + 1, + NULL); + + UE->mac_stats.ul.total_sdu_bytes += mac_len; UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len; break; @@ -710,129 +714,136 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; if (ra->ra_state != nrRA_WAIT_Msg3) continue; - - if(no_sig) { + + if (no_sig) { LOG_D(NR_MAC, "Random Access %i failed at state %s (no signal)\n", i, nrra_text[ra->ra_state]); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - } else { + continue; + } - // random access pusch with TC-RNTI - if (ra->rnti != current_rnti) { - LOG_D(NR_MAC, - "expected TC_RNTI %04x to match current RNTI %04x\n", - ra->rnti, - current_rnti); + // random access pusch with TC-RNTI + if (ra->rnti != current_rnti) { + LOG_D(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti); - if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) { - LOG_D(NR_MAC, - "Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n", - i, - nrra_text[ra->ra_state], - ra->rnti, - current_rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - } - - continue; - } - - NR_UE_info_t *UE_msg3_stage = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); - if (!UE_msg3_stage) { + if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot)) { LOG_W(NR_MAC, - "Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", + "Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n", i, nrra_text[ra->ra_state], ra->rnti, current_rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - return; } - UE_msg3_stage->UE_beam_index = ra->beam_id; + continue; + } - // re-initialize ta update variables after RA procedure completion - UE_msg3_stage->UE_sched_ctrl.ta_frame = frameP; - - LOG_D(NR_MAC, - "reset RA state information for RA-RNTI 0x%04x/index %d\n", + UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup); + if (!UE) { + LOG_W(NR_MAC, + "Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", + i, + nrra_text[ra->ra_state], ra->rnti, - i); + current_rnti); - LOG_I(NR_MAC, - "[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, " - "adding UE MAC Context RNTI 0x%04x\n", - gnb_mod_idP, - current_rnti, - ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + return; + } - NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl; + UE->UE_beam_index = ra->beam_id; - if (ul_cqi != 0xff) { - UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; - UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30); + // re-initialize ta update variables after RA procedure completion + UE->UE_sched_ctrl.ta_frame = frameP; + + LOG_I(NR_MAC, + "[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, " + "adding UE MAC Context RNTI 0x%04x\n", + gnb_mod_idP, + current_rnti, + ra->rnti); + + NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; + + if (ul_cqi != 0xff) { + UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; + UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30); + } + if (timing_advance != 0xffff) + UE_scheduling_control->ta_update = timing_advance; + UE_scheduling_control->raw_rssi = rssi; + LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); + if (ra->cfra) { + LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); + nr_mac_reset_ul_failure(UE_scheduling_control); + reset_dl_harq_list(UE_scheduling_control); + reset_ul_harq_list(UE_scheduling_control); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + process_CellGroup(ra->CellGroup, UE); + + } else { + LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP); + LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n"); + for (int k = 0; k < sdu_lenP; k++) { + LOG_D(NR_MAC, "(%i): 0x%x\n", k, sduP[k]); } - if (timing_advance != 0xffff) - UE_scheduling_control->ta_update = timing_advance; - UE_scheduling_control->raw_rssi = rssi; - LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); - if (ra->cfra) { - LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); - nr_mac_reset_ul_failure(UE_scheduling_control); - reset_dl_harq_list(UE_scheduling_control); - reset_ul_harq_list(UE_scheduling_control); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - process_CellGroup(ra->CellGroup, UE_msg3_stage); - } else { + // 3GPP TS 38.321 Section 5.4.3 Multiplexing and assembly + // Logical channels shall be prioritised in accordance with the following order (highest priority listed first): + // - MAC CE for C-RNTI, or data from UL-CCCH; + // This way, we need to process MAC CE for C-RNTI if RA is active and it is present in the MAC PDU + // Search for MAC CE for C-RNTI + rnti_t crnti = lcid_crnti_lookahead(sduP, sdu_lenP); + if (crnti != 0) { // 3GPP TS 38.321 Table 7.1-1: RNTI values, RNTI 0x0000: N/A + // this UE is the one identified by the RNTI in sduP + ra->rnti = crnti; + // Remove UE context just created after Msg.3 in some milliseconds as the UE is one already known (not now, as the UE + // context is still needed for the moment) + nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); - LOG_A(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP); - LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); - for (int k = 0; k < sdu_lenP; k++) { - LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); + // Replace the current UE by the UE identified by C-RNTI + UE = find_nr_UE(&RC.nrmac[gnb_mod_idP]->UE_info, crnti); + if (!UE) { + // The UE identified by C-RNTI no longer exists at the gNB + // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better + // solution may be implemented + LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti); + mac_remove_nr_ue(RC.nrmac[gnb_mod_idP], ra->rnti); + nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); + return; } + // The UE identified by C-RNTI still exists at the gNB + // Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration + UE->Msg4_ACKed = false; + nr_mac_reset_ul_failure(&UE->UE_sched_ctrl); + // Reset HARQ processes + reset_dl_harq_list(&UE->UE_sched_ctrl); + reset_ul_harq_list(&UE->UE_sched_ctrl); + + if (UE->reconfigCellGroup) { + // Nothing to do + // A RRCReconfiguration message should be already pending (for example, an ongoing RRCReestablishment), and it will be + // transmitted in Msg4 + } else { + // Trigger RRC Reconfiguration + LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE->rnti); + nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE); + } + } else { // UE Contention Resolution Identity // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4 // First byte corresponds to R/LCID MAC sub-header memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6); - // harq_pid set a non valid value because it is not used in this call - // the function is only called to decode the contention resolution sub-header - if (nr_process_mac_pdu(gnb_mod_idP, UE_msg3_stage, CC_idP, frameP, slotP, sduP, sdu_lenP, -1) == 0) { - if (ra->ra_state == nrRA_Msg3_dcch_dtch) { - // Check if the UE identified by C-RNTI still exists at the gNB - NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->rnti); - if (!UE_C) { - // The UE identified by C-RNTI no longer exists at the gNB - // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented - mac_remove_nr_ue(gNB_mac, ra->rnti); - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti); - return; - } else { - // Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration - UE_C->Msg4_ACKed = false; - - // The UE identified by C-RNTI still exists at the gNB - nr_mac_reset_ul_failure(&UE_C->UE_sched_ctrl); - - // Reset HARQ processes - reset_dl_harq_list(&UE_C->UE_sched_ctrl); - reset_ul_harq_list(&UE_C->UE_sched_ctrl); - - // Trigger RRC Reconfiguration - LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE_C->rnti); - nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE_C); - } - } else { - LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]); - ra->ra_state = nrRA_Msg4; - } - } - else { - nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); - } } + + // Decode MAC PDU for the correct UE, after checking for MAC CE for C-RNTI + // harq_pid set a non valid value because it is not used in this call + // the function is only called to decode the contention resolution sub-header + nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, -1); + + LOG_I(NR_MAC, "Activating scheduling RA-Msg4 for TC_RNTI 0x%04x (state %s)\n", ra->rnti, nrra_text[ra->ra_state]); + ra->ra_state = nrRA_Msg4; return; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 6228998942..6e38f491f6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -36,6 +36,7 @@ #include "common/ngran_types.h" void set_cset_offset(uint16_t); +void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers); void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index d537865de5..6f4c832802 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -715,7 +715,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); - nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); instance_t f1inst = get_f1_gtp_instance(); if (f1inst >= 0) // we actually use F1-U gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index a8fa48c849..17c5134bcd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -116,9 +116,8 @@ typedef enum { nrRA_Msg2 = 1, nrRA_WAIT_Msg3 = 2, nrRA_Msg3_retransmission = 3, - nrRA_Msg3_dcch_dtch = 4, - nrRA_Msg4 = 5, - nrRA_WAIT_Msg4_ACK = 6 + nrRA_Msg4 = 4, + nrRA_WAIT_Msg4_ACK = 5, } RA_gNB_state_t; static const char *const nrra_text[] = {"IDLE", "Msg2", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "WAIT_Msg4_ACK"}; diff --git a/openair2/LAYER2/nr_pdcp/asn1_utils.c b/openair2/LAYER2/nr_pdcp/asn1_utils.c index 473c5f2331..6b45a73acf 100644 --- a/openair2/LAYER2/nr_pdcp/asn1_utils.c +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.c @@ -20,6 +20,7 @@ */ #include "common/utils/LOG/log.h" +#include "nr_pdcp_entity.h" int decode_t_reordering(int v) { @@ -36,16 +37,16 @@ int decode_t_reordering(int v) int decode_sn_size_ul(long s) { - if (s == 0) return 12; - if (s == 1) return 18; + if (s == 0) return SHORT_SN_SIZE; + if (s == 1) return LONG_SN_SIZE; LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } int decode_sn_size_dl(long s) { - if (s == 0) return 12; - if (s == 1) return 18; + if (s == 0) return SHORT_SN_SIZE; + if (s == 1) return LONG_SN_SIZE; LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index 2b65cf87f9..e18c8eddfb 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -283,11 +283,12 @@ void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) newGtpuDeleteAllTunnels(n3inst, cmd->gNB_cu_up_ue_id); if (f1inst >= 0) // is there F1-U? newGtpuDeleteAllTunnels(f1inst, cmd->gNB_cu_up_ue_id); - nr_pdcp_remove_UE(cmd->gNB_cu_up_ue_id); - nr_sdap_delete_ue_entities(cmd->gNB_cu_up_ue_id); if (need_ue_id_mgmt) { + // see issue #706: in monolithic, gNB will free PDCP of UE + nr_pdcp_remove_UE(cmd->gNB_cu_up_ue_id); cu_remove_f1_ue_data(cmd->gNB_cu_up_ue_id); } + nr_sdap_delete_ue_entities(cmd->gNB_cu_up_ue_id); e1ap_bearer_release_cplt_t cplt = { .gNB_cu_cp_ue_id = cmd->gNB_cu_cp_ue_id, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index cea73170dc..2a197c3c4f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -32,6 +32,16 @@ #include "LOG/log.h" +/** + * @brief returns the maximum PDCP PDU size + * which corresponds to data PDU for DRBs with 18 bits PDCP SN + * and integrity enabled +*/ +int nr_max_pdcp_pdu_size(sdu_size_t sdu_size) +{ + return (sdu_size + LONG_PDCP_HEADER_SIZE + PDCP_INTEGRITY_SIZE); +} + static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, char *_buffer, int size) { @@ -46,6 +56,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, int rx_deliv_sn; uint32_t rx_deliv_hfn; + if (entity->entity_suspended) { + LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id); + return; + } + if (size < 1) { LOG_E(PDCP, "bad PDU received (size = %d)\n", size); return; @@ -65,21 +80,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, if (entity->has_sdap_rx) sdap_header_size = 1; // SDAP Header is one byte - if (entity->sn_size == 12) { + if (entity->sn_size == SHORT_SN_SIZE) { rcvd_sn = ((buffer[0] & 0xf) << 8) | buffer[1]; - header_size = 2; + header_size = SHORT_PDCP_HEADER_SIZE; } else { rcvd_sn = ((buffer[0] & 0x3) << 16) | (buffer[1] << 8) | buffer[2]; - header_size = 3; + header_size = LONG_PDCP_HEADER_SIZE; } entity->stats.rxpdu_sn = rcvd_sn; /* SRBs always have MAC-I, even if integrity is not active */ if (entity->has_integrity || entity->type == NR_PDCP_SRB) { - integrity_size = 4; + integrity_size = PDCP_INTEGRITY_SIZE; } else { integrity_size = 0; } @@ -113,11 +128,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); if (entity->has_integrity) { - unsigned char integrity[4] = {0}; + unsigned char integrity[PDCP_INTEGRITY_SIZE] = {0}; entity->integrity(entity->integrity_context, integrity, buffer, size - integrity_size, entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); - if (memcmp(integrity, buffer + size - integrity_size, 4) != 0) { + if (memcmp(integrity, buffer + size - integrity_size, PDCP_INTEGRITY_SIZE) != 0) { LOG_E(PDCP, "discard NR PDU, integrity failed\n"); entity->stats.rxpdu_dd_pkts++; entity->stats.rxpdu_dd_bytes += size; @@ -189,8 +204,14 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, int integrity_size; int sdap_header_size = 0; char *buf = pdu_buffer; - DevAssert(size + 3 + 4 <= pdu_max_size); + DevAssert(nr_max_pdcp_pdu_size(size) <= pdu_max_size); int dc_bit; + + if (entity->entity_suspended) { + LOG_W(PDCP, "PDCP entity %d is suspended. Quit SDU processing.\n", entity->rb_id); + return -1; + } + entity->stats.rxsdu_pkts++; entity->stats.rxsdu_bytes += size; @@ -207,20 +228,20 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, dc_bit = 0; } - if (entity->sn_size == 12) { + if (entity->sn_size == SHORT_SN_SIZE) { buf[0] = dc_bit | ((sn >> 8) & 0xf); buf[1] = sn & 0xff; - header_size = 2; + header_size = SHORT_PDCP_HEADER_SIZE; } else { buf[0] = dc_bit | ((sn >> 16) & 0x3); buf[1] = (sn >> 8) & 0xff; buf[2] = sn & 0xff; - header_size = 3; + header_size = LONG_PDCP_HEADER_SIZE; } /* SRBs always have MAC-I, even if integrity is not active */ if (entity->has_integrity || entity->type == NR_PDCP_SRB) { - integrity_size = 4; + integrity_size = PDCP_INTEGRITY_SIZE; } else { integrity_size = 0; } @@ -228,16 +249,16 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, memcpy(buf + header_size, buffer, size); if (entity->has_integrity) { - uint8_t integrity[4] = {0}; + uint8_t integrity[PDCP_INTEGRITY_SIZE] = {0}; entity->integrity(entity->integrity_context, integrity, (unsigned char *)buf, header_size + size, entity->rb_id, count, entity->is_gnb ? 1 : 0); - memcpy((unsigned char *)buf + header_size + size, integrity, 4); - } else if (integrity_size == 4) { + memcpy((unsigned char *)buf + header_size + size, integrity, PDCP_INTEGRITY_SIZE); + } else if (integrity_size == PDCP_INTEGRITY_SIZE) { // set MAC-I to 0 for SRBs with integrity not active - memset(buf + header_size + size, 0, 4); + memset(buf + header_size + size, 0, PDCP_INTEGRITY_SIZE); } if (entity->has_ciphering && (entity->is_gnb || entity->security_mode_completed)) { @@ -400,6 +421,7 @@ static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity) } entity->rx_next = 0; entity->rx_deliv = 0; + entity->entity_suspended = true; } static void free_rx_list(nr_pdcp_entity_t *entity) @@ -427,6 +449,9 @@ static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity) /* receiving entity procedures */ /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) @@ -445,6 +470,9 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) entity->rx_next = 0; entity->rx_deliv = 0; /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) @@ -461,6 +489,9 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) entity->rx_next = 0; entity->rx_deliv = 0; /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 8d342a8206..aae1ffb317 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -29,6 +29,18 @@ #include "nr_pdcp_sdu.h" #include "openair2/RRC/NR/rrc_gNB_radio_bearers.h" +/* PDCP Formats according to clause 6.2 of 3GPP TS 38.323 */ +/* SN Size applicable to SRBs, UM DRBs and AM DRBs */ +#define SHORT_SN_SIZE 12 +/* SN Size applicable to UM DRBs and AM DRBs */ +#define LONG_SN_SIZE 18 +/* Data PDU for SRBs and DRBs with 12 bits PDCP SN (unit: byte) */ +#define SHORT_PDCP_HEADER_SIZE 2 +/* Data PDU for DRBs with 18 bits PDCP SN (unit: byte) */ +#define LONG_PDCP_HEADER_SIZE 3 +/* MAC-I size (unit: byte) */ +#define PDCP_INTEGRITY_SIZE 4 + typedef enum { NR_PDCP_DRB_AM, NR_PDCP_DRB_UM, @@ -167,6 +179,9 @@ typedef struct nr_pdcp_entity_t { // 4- The ITTI task, forwards the message ciphering (e.g., nea2) it. // 5- The gNB cannot understand the ciphered Security Mode Complete message. bool security_mode_completed; + + /* Keep tracks of whether the PDCP entity was suspended or not */ + bool entity_suspended; } nr_pdcp_entity_t; nr_pdcp_entity_t *new_nr_pdcp_entity( @@ -190,4 +205,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( unsigned char *ciphering_key, unsigned char *integrity_key); +/* Get maximum PDCP PDU size */ +int nr_max_pdcp_pdu_size(sdu_size_t sdu_size); + #endif /* _NR_PDCP_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ef2da07d57..b2380e3b2f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -817,10 +817,19 @@ void add_srb(int is_gnb, if (nr_pdcp_get_rb(ue, srb_id, true) != NULL) { LOG_E(PDCP, "warning SRB %d already exist for UE ID %ld, do nothing\n", srb_id, UEid); } else { - pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, is_gnb, srb_id, - 0, false, false, // sdap parameters - deliver_sdu_srb, ue, NULL, ue, - 12, t_Reordering, -1, + pdcp_srb = new_nr_pdcp_entity(NR_PDCP_SRB, + is_gnb, + srb_id, + 0, // PDU session ID (not relevant) + false, // has SDAP RX (not relevant) + false, // has SDAP TX (not relevant) + deliver_sdu_srb, + ue, + NULL, + ue, + SHORT_SN_SIZE, + t_Reordering, + -1, ciphering_algorithm, integrity_algorithm, ciphering_key, @@ -1075,9 +1084,13 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, return 0; } - int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity + int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size); char pdu_buf[max_size]; int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); + if (pdu_size == -1) { + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return 0; + } AssertFatal(rb->deliver_pdu == NULL, "SRB callback should be NULL, to be provided on every invocation\n"); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); @@ -1098,6 +1111,7 @@ void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id) return; } srb->suspend_entity(srb); + LOG_D(PDCP, "SRB %d suspended\n", srb_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1112,6 +1126,7 @@ void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id) return; } drb->suspend_entity(drb); + LOG_D(PDCP, "DRB %d suspended\n", drb_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1211,6 +1226,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) if (rb != NULL) { LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id); rb->reestablish_entity(rb); + LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id); } else { LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id); } @@ -1252,14 +1268,19 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, rb = nr_pdcp_get_rb(ue, rb_id, false); if (rb == NULL) { - LOG_E(PDCP, "no DRB found (ue_id %lx, rb_id %ld)\n", ue_id, rb_id); + LOG_E(PDCP, "[UE %lx] DRB %ld not found\n", rb_id, ue_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); return 0; } - int max_size = sdu_buffer_size + 3 + 4; // 3: max header, 4: max integrity + int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size); char pdu_buf[max_size]; int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); + if (pdu_size == -1) { + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return 0; + } + deliver_pdu deliver_pdu_cb = rb->deliver_pdu; nr_pdcp_manager_unlock(nr_pdcp_ue_manager); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index d1bda61f82..b12142a881 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -118,10 +118,10 @@ static nr_rlc_entity_t *get_rlc_entity_from_lcid(nr_rlc_ue_t *ue, logical_chan_i } } -void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id) +void nr_rlc_release_entity(int ue_id, logical_chan_id_t channel_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if (channel_id == 0) { if (ue->srb0 != NULL) { free(ue->srb0->deliver_sdu_data); @@ -136,7 +136,7 @@ void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id) } void mac_rlc_data_ind(const module_id_t module_idP, - const rnti_t rntiP, + const uint16_t ue_id, const eNB_index_t eNB_index, const frame_t frameP, const eNB_flag_t enb_flagP, @@ -153,11 +153,11 @@ void mac_rlc_data_ind(const module_id_t module_idP, } if (enb_flagP) - T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP), + T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(ue_id), T_INT(channel_idP), T_INT(tb_sizeP)); nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if(ue == NULL) LOG_I(RLC, "RLC instance for the given UE was not found \n"); @@ -169,8 +169,7 @@ void mac_rlc_data_ind(const module_id_t module_idP, rb->set_time(rb, nr_rlc_current_time); rb->recv_pdu(rb, buffer_pP, tb_sizeP); } else { - LOG_E(RLC, "Fatal: no RB found (channel ID %d RNTI %d)\n", - channel_idP, rntiP); + LOG_E(RLC, "Fatal: no RB found (channel ID %d UE ID %d)\n", channel_idP, ue_id); // exit(1); } @@ -178,7 +177,7 @@ void mac_rlc_data_ind(const module_id_t module_idP, } tbs_size_t mac_rlc_data_req(const module_id_t module_idP, - const rnti_t rntiP, + const uint16_t ue_id, const eNB_index_t eNB_index, const frame_t frameP, const eNB_flag_t enb_flagP, @@ -193,7 +192,7 @@ tbs_size_t mac_rlc_data_req(const module_id_t module_idP, int maxsize; nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP); if (rb != NULL) { @@ -209,14 +208,14 @@ tbs_size_t mac_rlc_data_req(const module_id_t module_idP, nr_rlc_manager_unlock(nr_rlc_ue_manager); if (enb_flagP) - T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP), + T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(ue_id), T_INT(channel_idP), T_INT(ret)); return ret; } mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, - const rnti_t rntiP, + const uint16_t ue_id, const eNB_index_t eNB_index, const frame_t frameP, const sub_frame_t subframeP, @@ -229,7 +228,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, mac_rlc_status_resp_t ret; nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP); if (rb != NULL) { @@ -246,7 +245,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, + buf_stat.tx_size; } else { if (!(frameP%128) || channel_idP == 0) //to suppress this warning message - LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id); ret.bytes_in_buffer = 0; } @@ -261,7 +260,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP, } rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module_idP, - const rnti_t rntiP, + const uint16_t ue_id, const eNB_index_t eNB_index, const frame_t frameP, const sub_frame_t subframeP, @@ -284,7 +283,7 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module } nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP); if (rb != NULL) { @@ -302,7 +301,7 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module + buf_stat.tx_size; } else { if (!(frameP%128)) //to suppress this warning message - LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + LOG_W(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id); ret = 0; } @@ -322,18 +321,18 @@ rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const ctxt_pP, const uint32_t *const sourceL2Id, const uint32_t *const destinationL2Id) { - int rnti = ctxt_pP->rntiMaybeUEid; + int ue_id = ctxt_pP->rntiMaybeUEid; nr_rlc_ue_t *ue; nr_rlc_entity_t *rb; - LOG_D(RLC, "rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", - rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP); + LOG_D(RLC, "UE %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", + ue_id, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, MBMS_flagP); if (ctxt_pP->enb_flag) T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rntiMaybeUEid), T_INT(rb_idP), T_INT(sdu_sizeP)); nr_rlc_manager_lock(nr_rlc_ue_manager); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); rb = NULL; @@ -359,19 +358,18 @@ rlc_op_status_t rlc_data_req(const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } -int nr_rlc_get_available_tx_space(const rnti_t rntiP, - const logical_chan_id_t channel_idP) +int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP) { int ret; nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP); if (rb != NULL) { ret = rb->available_tx_space(rb); } else { - LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + LOG_E(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_idP, ue_id); ret = -1; } @@ -440,13 +438,11 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) } } - LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", - __FILE__, __LINE__, __FUNCTION__, ue->rnti); + LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id); exit(1); rb_found: - LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n", - __FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size); + LOG_D(RLC, "Delivering SDU (ue_id %d is_srb %d rb_id %d) size %d\n", ue->ue_id, is_srb, rb_id, size); /* unused fields? */ ctx.instance = 0; @@ -461,9 +457,9 @@ rb_found: ctx.module_id = 0; /* CU (PDCP, RRC, SDAP) use a different ID than RNTI, so below set the CU UE * ID if in gNB, else use RNTI normally */ - ctx.rntiMaybeUEid = ue->rnti; + ctx.rntiMaybeUEid = ue->ue_id; if (is_enb) { - f1_ue_data_t ue_data = du_get_f1_ue_data(ue->rnti); + f1_ue_data_t ue_data = du_get_f1_ue_data(ue->ue_id); ctx.rntiMaybeUEid = ue_data.secondary_ue; } @@ -472,7 +468,7 @@ rb_found: if (is_enb) { T(T_ENB_RLC_UL, T_INT(0 /*ctxt_pP->module_id*/), - T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); + T_INT(ue->ue_id), T_INT(rb_id), T_INT(size)); const ngran_node_t type = RC.nrrrc[0 /*ctxt_pP->module_id*/]->node_type; AssertFatal(!NODE_IS_CU(type), @@ -491,7 +487,7 @@ rb_found: uint8_t *message_buffer = itti_malloc (TASK_RLC_ENB, TASK_DU_F1, size); memcpy (message_buffer, buf, size); F1AP_UL_RRC_MESSAGE(msg).gNB_CU_ue_id = ctx.rntiMaybeUEid; - F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->rnti; + F1AP_UL_RRC_MESSAGE(msg).gNB_DU_ue_id = ue->ue_id; F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id; F1AP_UL_RRC_MESSAGE(msg).rrc_container = message_buffer; F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size; @@ -504,8 +500,8 @@ rb_found: req->buffer=(uint8_t*)(req+1); memcpy(req->buffer,buf,size); req->length=size; - req->offset=0; - req->ue_id=ue->rnti; // use RNTI here, which GTP will use to look up TEID + req->offset = 0; + req->ue_id = ue->ue_id; req->bearer_id=rb_id; LOG_D(RLC, "Received uplink user-plane traffic at RLC-DU to be sent to the CU, size %d \n", size); extern instance_t DUuniqInstance; @@ -558,8 +554,7 @@ static void successful_delivery(void *_ue, nr_rlc_entity_t *entity, int sdu_id) } } - LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", - __FILE__, __LINE__, __FUNCTION__, ue->rnti); + LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id); exit(1); rb_found: @@ -616,8 +611,7 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity) } } - LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", - __FILE__, __LINE__, __FUNCTION__, ue->rnti); + LOG_E(RLC, "Fatal, no RB found for ue %d\n", ue->ue_id); exit(1); rb_found: @@ -644,10 +638,10 @@ rb_found: #endif } -void nr_rlc_reestablish_entity(int rnti, int lc_id) +void nr_rlc_reestablish_entity(int ue_id, int lc_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if (ue == NULL) { LOG_E(RLC, "RLC instance for the given UE was not found \n"); @@ -663,10 +657,11 @@ void nr_rlc_reestablish_entity(int rnti, int lc_id) } nr_rlc_manager_unlock(nr_rlc_ue_manager); } -void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config) + +void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config) { nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if (ue == NULL) LOG_E(RLC, "RLC instance for the given UE was not found \n"); @@ -737,7 +732,7 @@ void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config) nr_rlc_manager_unlock(nr_rlc_ue_manager); } -void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) +void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; int t_status_prohibit; @@ -778,7 +773,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare } nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); AssertFatal(rlc_BearerConfig->servedRadioBearer && (rlc_BearerConfig->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity), @@ -787,7 +782,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare ue->lcid2rb[local_id].type = NR_RLC_SRB; ue->lcid2rb[local_id].choice.srb_id = rlc_BearerConfig->servedRadioBearer->choice.srb_Identity; if (ue->srb[srb_id-1] != NULL) { - LOG_E(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + LOG_E(RLC, "SRB %d already exists for UE %d, do nothing\n", srb_id, ue_id); } else { nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE, RLC_TX_MAXSIZE, @@ -800,12 +795,12 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare sn_field_length); nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am); - LOG_I(RLC, "Added srb %d to UE with RNTI 0x%x\n", srb_id, rnti); + LOG_I(RLC, "Added srb %d to UE %d\n", srb_id, ue_id); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } -static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) +static void add_drb_am(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; @@ -843,7 +838,7 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be } nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); AssertFatal(rlc_BearerConfig->servedRadioBearer && (rlc_BearerConfig->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity), @@ -852,7 +847,7 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be ue->lcid2rb[local_id].type = NR_RLC_DRB; ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity; if (ue->drb[drb_id-1] != NULL) { - LOG_E(RLC, "%s:%d:%s: DRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_E(RLC, "DRB %d already exists for UE %d, do nothing\n", drb_id, ue_id); } else { nr_rlc_entity_t *nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE, RLC_TX_MAXSIZE, @@ -865,12 +860,12 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be sn_field_length); nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am); - LOG_I(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_I(RLC, "Added drb %d to UE %d\n", drb_id, ue_id); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } -static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) +static void add_drb_um(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; @@ -898,7 +893,7 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be } nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); AssertFatal(rlc_BearerConfig->servedRadioBearer && (rlc_BearerConfig->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity), @@ -907,7 +902,7 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be ue->lcid2rb[local_id].type = NR_RLC_DRB; ue->lcid2rb[local_id].choice.drb_id = rlc_BearerConfig->servedRadioBearer->choice.drb_Identity; if (ue->drb[drb_id-1] != NULL) { - LOG_E(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_E(RLC, "DEBUG add_drb_um: warning DRB %d already exist for ue %d, do nothing\n", drb_id, ue_id); } else { nr_rlc_entity_t *nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE, RLC_TX_MAXSIZE, @@ -916,26 +911,25 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be sn_field_length); nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um); - LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_D(RLC, "Added drb %d to UE %d\n", drb_id, ue_id); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } -void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) +void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig) { switch (rlc_BearerConfig->rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(rnti, drb_id, rlc_BearerConfig); + add_drb_am(ue_id, drb_id, rlc_BearerConfig); break; case NR_RLC_Config_PR_um_Bi_Directional: - add_drb_um(rnti, drb_id, rlc_BearerConfig); + add_drb_um(ue_id, drb_id, rlc_BearerConfig); break; default: - LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n", - __FILE__, __LINE__, __FUNCTION__); + LOG_E(RLC, "Fatal: unhandled DRB type\n"); exit(1); } - LOG_I(RLC, "%s:%s:%d: added DRB to UE with RNTI 0x%x\n", __FILE__, __FUNCTION__, __LINE__, rnti); + LOG_I(RLC, "Added DRB to UE %d\n", ue_id); } /* Dummy function due to dependency from LTE libraries */ @@ -951,66 +945,52 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } struct srb0_data { - int rnti; + int ue_id; void *data; - void (*send_initial_ul_rrc_message)(int rnti, - const uint8_t *sdu, - sdu_size_t sdu_len, - void *data); + void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data); }; void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size) { struct srb0_data *s0 = (struct srb0_data *)deliver_sdu_data; - s0->send_initial_ul_rrc_message(s0->rnti, (unsigned char *)buf, size, s0->data); + s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data); } -void nr_rlc_activate_srb0(int rnti, void *data, - void (*send_initial_ul_rrc_message)( - int rnti, - const uint8_t *sdu, - sdu_size_t sdu_len, - void *data)) +void nr_rlc_activate_srb0(int ue_id, + void *data, + void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data)) { - nr_rlc_entity_t *nr_rlc_tm; - nr_rlc_ue_t *ue; - struct srb0_data *srb0_data; - - srb0_data = calloc(1, sizeof(struct srb0_data)); + struct srb0_data *srb0_data = calloc(1, sizeof(struct srb0_data)); AssertFatal(srb0_data != NULL, "out of memory\n"); - srb0_data->rnti = rnti; - srb0_data->data = data; + srb0_data->ue_id = ue_id; + srb0_data->data = data; srb0_data->send_initial_ul_rrc_message = send_initial_ul_rrc_message; nr_rlc_manager_lock(nr_rlc_ue_manager); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if (ue->srb0 != NULL) { - LOG_W(RLC, "SRB0 already exists for UE with RNTI 0x%x, do nothing\n", rnti); + LOG_W(RLC, "SRB0 already exists for UE %d, do nothing\n", ue_id); free(srb0_data); nr_rlc_manager_unlock(nr_rlc_ue_manager); return; } - nr_rlc_tm = new_nr_rlc_entity_tm(10000, + nr_rlc_entity_t *nr_rlc_tm = new_nr_rlc_entity_tm(10000, deliver_sdu_srb0, srb0_data); nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm); - LOG_I(RLC, "activated srb0 for UE with RNTI 0x%x\n", rnti); + LOG_I(RLC, "Activated srb0 for UE %d\n", ue_id); nr_rlc_manager_unlock(nr_rlc_ue_manager); } -rlc_op_status_t rrc_rlc_config_req ( - const protocol_ctxt_t* const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t mbms_flagP, - const config_action_t actionP, - const rb_id_t rb_idP) +rlc_op_status_t rrc_rlc_config_req(const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t mbms_flagP, + const config_action_t actionP, + const rb_id_t rb_idP) { - nr_rlc_ue_t *ue; - int i; - if (mbms_flagP) { LOG_E(RLC, "%s:%d:%s: todo (MBMS NOT supported)\n", __FILE__, __LINE__, __FUNCTION__); exit(1); @@ -1029,8 +1009,8 @@ rlc_op_status_t rrc_rlc_config_req ( exit(1); } nr_rlc_manager_lock(nr_rlc_ue_manager); - LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE RNTI %lx\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rntiMaybeUEid); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rntiMaybeUEid); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %lx\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rntiMaybeUEid); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rntiMaybeUEid); if (srb_flagP) { if (ue->srb[rb_idP-1] != NULL) { ue->srb[rb_idP-1]->delete_entity(ue->srb[rb_idP-1]); @@ -1045,6 +1025,7 @@ rlc_op_status_t rrc_rlc_config_req ( LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP); } /* remove UE if it has no more RB configured */ + int i; for (i = 0; i < 2; i++) if (ue->srb[i] != NULL) break; @@ -1059,11 +1040,11 @@ rlc_op_status_t rrc_rlc_config_req ( return RLC_OP_STATUS_OK; } -void nr_rlc_remove_ue(int rnti) +void nr_rlc_remove_ue(int ue_id) { - LOG_W(RLC, "remove UE %x\n", rnti); + LOG_W(RLC, "Remove UE %d\n", ue_id); nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_manager_remove_ue(nr_rlc_ue_manager, rnti); + nr_rlc_manager_remove_ue(nr_rlc_ue_manager, ue_id); nr_rlc_manager_unlock(nr_rlc_ue_manager); } @@ -1073,17 +1054,17 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } -bool nr_rlc_update_rnti(int from_rnti, int to_rnti) +bool nr_rlc_update_id(int from_id, int to_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_id); if (ue == NULL) { nr_rlc_manager_unlock(nr_rlc_ue_manager); - LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti); + LOG_E(RLC, "Cannot find RLC entity for UE %d\n", from_id); return false; } - ue->rnti = to_rnti; - LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti); + ue->ue_id = to_id; + LOG_I(RLC, "Update old UE ID %d context to ID %d\n", from_id, to_id); for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i) if (ue->srb[i]) ue->srb[i]->reestablishment(ue->srb[i]); @@ -1096,13 +1077,13 @@ bool nr_rlc_update_rnti(int from_rnti, int to_rnti) /* This function is for testing purposes. At least on a COTS UE, it will * trigger a reestablishment. */ -void nr_rlc_test_trigger_reestablishment(int rnti) +void nr_rlc_test_trigger_reestablishment(int ue_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); - nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); if (ue == NULL) { nr_rlc_manager_unlock(nr_rlc_ue_manager); - LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", rnti); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", ue_id); return; } /* we simply assume the SRB exists, because the scheduler creates it as soon @@ -1132,16 +1113,13 @@ void rlc_tick(int a, int b) exit(1); } -void nr_rlc_activate_avg_time_to_tx( - const rnti_t rnti, - const logical_chan_id_t channel_id, - const bool is_on) +void nr_rlc_activate_avg_time_to_tx(const int ue_id, + const logical_chan_id_t channel_id, + const bool is_on) { - nr_rlc_ue_t *ue; nr_rlc_entity_t *rb; - nr_rlc_manager_lock(nr_rlc_ue_manager); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); switch (channel_id) { case 1 ... 3: rb = ue->srb[channel_id - 1]; break; @@ -1153,27 +1131,20 @@ void nr_rlc_activate_avg_time_to_tx( rb->avg_time_is_on = is_on; time_average_reset(rb->txsdu_avg_time_to_tx); } else { - LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rnti %x\n", __FUNCTION__, channel_id, rnti); + LOG_E(RLC, "Radio Bearer (channel ID %d) is NULL for UE %d\n", channel_id, ue_id); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } /* returns false in case of error, true if everything ok */ -bool nr_rlc_get_statistics( - int rnti, - int srb_flag, - int rb_id, - nr_rlc_statistics_t *out) +bool nr_rlc_get_statistics(int ue_id, int srb_flag, int rb_id, nr_rlc_statistics_t *out) { - nr_rlc_ue_t *ue; - nr_rlc_entity_t *rb; - bool ret; - + bool ret; nr_rlc_manager_lock(nr_rlc_ue_manager); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); - rb = NULL; + nr_rlc_entity_t *rb = NULL; if (srb_flag) { if (rb_id >= 1 && rb_id <= 2) @@ -1201,23 +1172,21 @@ bool nr_rlc_get_statistics( return ret; } -void nr_rlc_srb_recv_sdu(const int rnti, const logical_chan_id_t channel_id, unsigned char *buf, int size) +void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size) { - nr_rlc_ue_t *ue; - nr_rlc_entity_t *rb; - - T(T_ENB_RLC_DL, T_INT(0), T_INT(rnti), T_INT(0), T_INT(size)); + T(T_ENB_RLC_DL, T_INT(0), T_INT(ue_id), T_INT(0), T_INT(size)); nr_rlc_manager_lock(nr_rlc_ue_manager); - ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + nr_rlc_entity_t *rb = NULL; if (channel_id == 0) { rb = ue->srb0; } else { rb = ue->srb[channel_id - 1]; } - AssertFatal(rb != NULL, "SDU sent to unknown RB RNTI %04x SRB %d\n", rnti, channel_id); + AssertFatal(rb != NULL, "SDU sent to unknown RB UE-ID %d SRB %d\n", ue_id, channel_id); rb->set_time(rb, nr_rlc_current_time); rb->recv_sdu(rb, (char *)buf, size, -1); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 607538b15c..ea47b00f03 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -41,37 +41,29 @@ struct NR_RLC_Config; struct NR_LogicalChannelConfig; -void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); -void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); +void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); +void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); -void nr_rlc_reestablish_entity(int rnti, int lc_id); logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id); -void nr_rlc_remove_ue(int rnti); -bool nr_rlc_update_rnti(int from_rnti, int to_rnti); +void nr_rlc_reestablish_entity(int ue_id, int lc_id); +void nr_rlc_remove_ue(int ue_id); +bool nr_rlc_update_id(int from_id, int to_id); /* test function for CI to trigger reestablishments */ -void nr_rlc_test_trigger_reestablishment(int rnti); +void nr_rlc_test_trigger_reestablishment(int ue_id); -void nr_rlc_release_entity(int rnti, logical_chan_id_t channel_id); +void nr_rlc_release_entity(int ue_id, logical_chan_id_t channel_id); -void nr_rlc_reconfigure_entity(int rnti, int lc_id, NR_RLC_Config_t *rlc_Config); +void nr_rlc_reconfigure_entity(int ue_id, int lc_id, NR_RLC_Config_t *rlc_Config); -int nr_rlc_get_available_tx_space( - const rnti_t rntiP, - const logical_chan_id_t channel_idP); +int nr_rlc_get_available_tx_space(const int ue_id, const logical_chan_id_t channel_idP); -void nr_rlc_activate_avg_time_to_tx( - const rnti_t rnti, - const logical_chan_id_t channel_id, - const bool is_on); +void nr_rlc_activate_avg_time_to_tx(const int ue_id, const logical_chan_id_t channel_id, const bool is_on); -void nr_rlc_srb_recv_sdu(const int rnti, const logical_chan_id_t channel_id, unsigned char *buf, int size); +void nr_rlc_srb_recv_sdu(const int ue_id, const logical_chan_id_t channel_id, unsigned char *buf, int size); -void nr_rlc_activate_srb0(int rnti, void *data, - void (*send_initial_ul_rrc_message)( - int rnti, - const uint8_t *sdu, - sdu_size_t sdu_len, - void *data)); +void nr_rlc_activate_srb0(int ue_id, + void *data, + void (*send_initial_ul_rrc_message)(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data)); -bool nr_rlc_get_statistics(int rnti, int srb_flag, int rb_id, nr_rlc_statistics_t *out); +bool nr_rlc_get_statistics(int ue_id, int srb_flag, int rb_id, nr_rlc_statistics_t *out); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c index 1770446c9e..0ae270ae0f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c @@ -75,17 +75,17 @@ void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *_m) } /* must be called with lock acquired */ -nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti) +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int ue_id) { /* TODO: optimze */ nr_rlc_ue_manager_internal_t *m = _m; int i; for (i = 0; i < m->ue_count; i++) - if (m->ue_list[i]->rnti == rnti) + if (m->ue_list[i]->ue_id == ue_id) return m->ue_list[i]; - LOG_D(RLC, "%s:%d:%s: new UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, rnti); + LOG_D(RLC, "New UE with ID %d\n", ue_id); m->ue_count++; m->ue_list = realloc(m->ue_list, sizeof(nr_rlc_ue_t *) * m->ue_count); @@ -99,13 +99,13 @@ nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti) exit(1); } - m->ue_list[m->ue_count-1]->rnti = rnti; + m->ue_list[m->ue_count-1]->ue_id = ue_id; return m->ue_list[m->ue_count-1]; } /* must be called with lock acquired */ -void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti) +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int ue_id) { nr_rlc_ue_manager_internal_t *m = _m; nr_rlc_ue_t *ue; @@ -113,13 +113,11 @@ void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti) int j; for (i = 0; i < m->ue_count; i++) - if (m->ue_list[i]->rnti == rnti) + if (m->ue_list[i]->ue_id == ue_id) break; if (i == m->ue_count) { - LOG_W(RLC, "%s:%d:%s: warning: ue %x not found\n", - __FILE__, __LINE__, __FUNCTION__, - rnti); + LOG_W(RLC, "Warning: ue %d not found\n", ue_id); return; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index aa499cfab6..e37d7929d8 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -38,8 +38,7 @@ typedef struct nr_rlc_rb_t { } nr_rlc_rb_t; typedef struct nr_rlc_ue_t { - int rnti; - ue_id_t ue_id; + int ue_id; nr_rlc_entity_t *srb0; nr_rlc_entity_t *srb[3]; nr_rlc_entity_t *drb[MAX_DRBS_PER_UE]; @@ -57,8 +56,8 @@ int nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager_t *m); void nr_rlc_manager_lock(nr_rlc_ue_manager_t *m); void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *m); -nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *m, int rnti); -void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *m, int rnti); +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *m, int ue_id); +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *m, int ue_id); /***********************************************************************/ /* ue functions */ diff --git a/openair2/PHY_INTERFACE/UE_MAC_interface.h b/openair2/PHY_INTERFACE/UE_MAC_interface.h deleted file mode 100644 index e7a833adfa..0000000000 --- a/openair2/PHY_INTERFACE/UE_MAC_interface.h +++ /dev/null @@ -1,438 +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 - */ - -/* This is the interface module between PHY - * Provided the FAPI style interface structures for P7. - */ - -/*! \file openair2/PHY_INTERFACE/IF_Module.h -* \brief data structures for PHY/MAC interface modules -* \author EURECOM/NTUST -* \date 2017 -* \version 0.1 -* \company Eurecom -* \email: raymond.knopp@eurecom.fr -* \note -* \warning -*/ -#ifndef __UE_MAC_INTERFACE__H__ -#define __UE_MAC_INTERFACE__H__ - -#include "nfapi_interface.h" -#include "openair1/PHY/defs_RU.h" -#include "common/openairinterface5g_limits.h" - -#define MAX_NUM_DL_PDU 100 -#define MAX_NUM_UL_PDU 100 -#define MAX_NUM_HI_DCI0_PDU 100 -#define MAX_NUM_TX_REQUEST_PDU 100 - -#define MAX_NUM_HARQ_IND 100 -#define MAX_NUM_CRC_IND 100 -#define MAX_NUM_SR_IND 100 -#define MAX_NUM_CQI_IND 100 -#define MAX_NUM_RACH_IND 100 -#define MAX_NUM_SRS_IND 100 - - -// UE_MAC enums -typedef enum { - UE_MAC_DL_IND_PDSCH_PDU_TYPE =0, - UE_MAC_DL_IND_SI_PDSCH_PDU_TYPE, - UE_MAC_DL_IND_P_PDSCH_PDU_TYPE, - UE_MAC_DL_IND_DLSCH_RAR_PDU_TYPE -} UE_MAC_dl_ind_pdu_type_e; - -// UE_MAC enums -typedef enum { - UE_MAC_Tx_IND_Msg1_TYPE =0, - UE_MAC_Tx_IND_Msg3_TYPE -} UE_MAC_Tx_ind_type_e; - - -// *** UE_Tx.request related structures - -typedef struct { - uint16_t pdu_length; - uint16_t pdu_index; - uint8_t num_segments; - struct { - uint32_t segment_length; - uint8_t* segment_data; - } segments[NFAPI_TX_MAX_SEGMENTS]; -} UE_MAC_tx_request_pdu_t; - - -typedef struct { - nfapi_tl_t tl; - uint16_t number_of_pdus; - UE_MAC_tx_request_pdu_t* ue_tx_pdu_list; -} UE_MAC_tx_request_body_t; - - -typedef struct { - //nfapi_p7_message_header_t header; - uint16_t sfn_sf; - UE_MAC_tx_request_body_t ue_tx_request_body; -} UE_MAC_tx_request_t; - - -typedef struct{ - - -}UE_MAC_sl_config_request_Tx_t; - -typedef struct{ - - -}UE_MAC_sl_config_request_Rx_t; - - -typedef struct{ - - -}UE_MAC_sl_tx_request_t; - - - - - - -// *** UE_DL.indication related structures - -typedef struct{ - unsigned char eNB_index; - uint8_t first_sync; //boolean 0 or 1 - uint8_t sync; // boolean 0 or 1 to indicate whether rrc_out_of_sync_ind() or dl_phy_sync_success() - // should be called from the handler function of the interface respectively. -}UE_MAC_bch_indication_pdu_t; - - -typedef struct{ - nfapi_tl_t tl; - UE_MAC_bch_indication_pdu_t* bch_ind_list; -}UE_MAC_BCH_indication_body_t; - - -// Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p(). -typedef struct{ - uint8_t* data; - uint16_t data_len; -}UE_MAC_dlsch_pdu; - - -// Corresponding to inputs of MAC function: process_rar(). -typedef struct{ - rnti_t ra_rnti; - uint8_t* rar_input_buffer; // Originating from PHY - rnti_t* t_crnti; - uint8_t preamble_index; - uint8_t* rar_output_buffer; //should be returned to PHY: dlsch0->harq_processes[0]->b -}UE_MAC_dlsch_rar_pdu; - - -typedef struct{ - uint8_t pdu_type; - uint8_t eNB_index; - union{ - UE_MAC_dlsch_pdu dlsch_pdu_ind; - UE_MAC_dlsch_rar_pdu dlsch_rar_pdu_ind; - }; -}UE_MAC_dlsch_indication_pdu_t; - - -typedef struct{ - nfapi_tl_t tl; - uint16_t number_of_pdus; - UE_MAC_dlsch_indication_pdu_t* dlsch_ind_list; -}UE_MAC_DLSCH_indication_body_t; - - - - - - -// *** UE_SL.indication related structures - -typedef struct{ - -}ue_sci_indication_body_t; - - -typedef struct{ - -}ue_SLSCH_indication_body_t; - - -typedef struct{ - -}ue_SLDCH_indication_body_t; - -typedef struct{ - -}ue_SLBCH_indication_body_t; - - -// *** UE_Config_common.request related structures - -typedef struct { - uint8_t subframeAssignment; - uint8_t specialSubframePatterns; -}UE_PHY_tdd_frame_structure_t; - - -typedef struct { - uint16_t rootSequenceIndex; - uint8_t prach_Config_enabled; - uint8_t prach_ConfigIndex; - uint8_t highSpeedFlag; - uint8_t zeroCorrelationZoneConfig; - uint8_t prach_FreqOffset; -}UE_PHY_prach_config_t; - -typedef struct { - uint8_t deltaPUCCH_Shift; - uint8_t nRB_CQI; - uint8_t nCS_AN; - uint16_t n1PUCCH_AN; -}UE_PHY_pucch_config_t; - - -typedef struct { - int8_t referenceSignalPower; - uint8_t p_b; -}UE_PHY_pdsch_config_t; - - -typedef struct { - uint8_t n_SB; - PUSCH_HOPPING_t hoppingMode; - uint8_t pusch_HoppingOffset; - uint8_t enable64QAM; - uint8_t groupHoppingEnabled; - uint8_t groupAssignmentPUSCH; - uint8_t sequenceHoppingEnabled; - uint8_t cyclicShift; -}UE_PHY_pusch_config_t; - - -typedef struct{ - uint8_t enabled_flag; - uint8_t srs_BandwidthConfig; - uint8_t srs_SubframeConfig; - uint8_t ackNackSRS_SimultaneousTransmission; - uint8_t srs_MaxUpPts; -}UE_PHY_SRS_config_t; - -typedef struct{ - int8_t p0_NominalPUSCH; - PUSCH_alpha_t alpha; - int8_t p0_NominalPUCCH; - int8_t deltaPreambleMsg3; - long deltaF_PUCCH_Format1; - long deltaF_PUCCH_Format1b; - long deltaF_PUCCH_Format2; - long deltaF_PUCCH_Format2a; - long deltaF_PUCCH_Format2b; -}UE_PHY_UL_power_control_config_t; - - -typedef struct{ - uint8_t maxHARQ_Msg3Tx; -}UE_PHY_HARQ_Msg3_config_t; - -typedef struct{ - uint8_t nb_antennas_tx; -}UE_PHY_antenna_config_t; - -typedef struct{ - PHICH_RESOURCE_t phich_resource; - PHICH_DURATION_t phich_duration; -}UE_PHY_phich_config_t; - - -typedef struct { - UE_PHY_tdd_frame_structure_t ue_tdd_frame_structure_config; - UE_PHY_prach_config_t ue_prach_config; - UE_PHY_pucch_config_t ue_pucch_config; - UE_PHY_pdsch_config_t ue_pdsch_config; - UE_PHY_pusch_config_t ue_pusch_config; - UE_PHY_SRS_config_t ue_srs_config; - UE_PHY_UL_power_control_config_t ue_ul_pow_cntl_config; - UE_PHY_HARQ_Msg3_config_t ue_harq_msg3_config; - /* Where can we find the types and values of the configuration for the PCH? - UE_MAC_pusch_config_t ue_pch_config - radioResourceConfigCommon->pcch_Config.defaultPagingCycle, radioResourceConfigCommon->pcch_Config.nB*/ - UE_PHY_antenna_config_t ue_ant_config; - UE_PHY_phich_config_t ue_phich_config; - /* MBSFN?*/ -}UE_PHY_config_common_request_t; - - - - - - - -// *** UE_Config_dedicated. request related structures - -typedef struct{ - PA_t p_a; -}UE_PHY_pdsch_config_dedicated_t; - - -typedef struct{ - uint8_t ackNackRepetition; - ANFBmode_t tdd_AckNackFeedbackMode; - //ACKNAKREP_t repetitionFactor; - //uint16_t n1PUCCH_AN_Rep; -}UE_PHY_pucch_config_dedicated_t; - - -typedef struct{ - uint16_t betaOffset_ACK_Index; - uint16_t betaOffset_RI_Index; - uint16_t betaOffset_CQI_Index; -}UE_PHY_pusch_config_dedicated_t; - - -typedef struct{ - int8_t p0_UE_PUSCH; - uint8_t deltaMCS_Enabled; - uint8_t accumulationEnabled; - int8_t p0_UE_PUCCH; - int8_t pSRS_Offset; - uint8_t filterCoefficient; -}UE_PHY_ul_power_control_config_dedicated_t; - - -typedef struct{ - uint16_t sr_PUCCH_ResourceIndex; - uint8_t sr_ConfigIndex; - DSR_TRANSMAX_t dsr_TransMax; -}UE_PHY_SR_config_dedicated_t; - - -typedef struct{ - uint8_t srsConfigDedicatedSetup; - uint8_t duration; - uint8_t cyclicShift; - uint8_t freqDomainPosition; - uint8_t srs_Bandwidth; - uint16_t srs_ConfigIndex; - uint8_t srs_HoppingBandwidth; - uint8_t transmissionComb; - //uint8_t srsCellSubframe; - //uint8_t srsUeSubframe; -}UE_PHY_srs_ul_config_dedicated_t; - - -typedef struct{ - CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic; - CQI_REPORTPERIODIC CQI_ReportPeriodic; - //int8_t nomPDSCH_RS_EPRE_Offset; -}UE_PHY_cqi_report_config_dedicated_t; - - - -typedef struct{ - uint8_t transmission_mode [NUMBER_OF_CONNECTED_eNB_MAX]; - UE_PHY_pdsch_config_dedicated_t ue_pdsch_config; - UE_PHY_pucch_config_dedicated_t ue_pucch_config; - UE_PHY_pusch_config_dedicated_t ue_pusch_config; - UE_PHY_ul_power_control_config_dedicated_t ue_ul_pow_cntrl_config; - UE_PHY_SR_config_dedicated_t ue_SR_config; - UE_PHY_srs_ul_config_dedicated_t ue_srs_ul_config; - UE_PHY_cqi_report_config_dedicated_t ue_cqi_report_config; -}UE_PHY_config_dedicated_request_t; - -#endif - - - - - - - - - - - - - - - - - - - -/* -typedef struct { - nfapi_p4_p5_message_header_t header; - uint8_t num_tlv; - nfapi_subframe_config_t subframe_config; - nfapi_rf_config_t rf_config; - nfapi_phich_config_t phich_config; - nfapi_sch_config_t sch_config; - nfapi_prach_config_t prach_config; - nfapi_pusch_config_t pusch_config; - nfapi_pucch_config_t pucch_config; - nfapi_srs_config_t srs_config; - nfapi_uplink_reference_signal_config_t uplink_reference_signal_config; - nfapi_laa_config_t laa_config; - nfapi_emtc_config_t emtc_config; - nfapi_tdd_frame_structure_t tdd_frame_structure_config; - nfapi_l23_config_t l23_config; - nfapi_nb_iot_config_t nb_iot_config; - - // addition nfapi tlvs as per table 2-16 in idle or configure - nfapi_nfapi_t nfapi_config; - - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_config_request_t; - - - - - -typedef struct { - nfapi_tl_t tl; - uint8_t dci_format; - uint8_t cce_index; - uint8_t aggregation_level; - uint16_t rnti; - uint8_t resource_block_start; - uint8_t number_of_resource_block; - uint8_t mcs_1; - uint8_t cyclic_shift_2_for_drms; - uint8_t frequency_hopping_enabled_flag; - uint8_t frequency_hopping_bits; - uint8_t new_data_indication_1; - uint8_t ue_tx_antenna_seleciton; - uint8_t tpc; - uint8_t cqi_csi_request; - uint8_t ul_index; - uint8_t dl_assignment_index; - uint32_t tpc_bitmap; - uint16_t transmission_power; -} nfapi_hi_dci0_dci_pdu_rel8_t; - -*/ diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 06e5f75442..782e568c49 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -363,7 +363,7 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco break; case 2: resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; - resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1, sizeof(uint8_t)); resourceMapping.frequencyDomainAllocation.choice.other.size = 1; resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4; @@ -372,7 +372,7 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco break; case 4: resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4; - resourceMapping.frequencyDomainAllocation.choice.row4.buf = calloc(2, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.row4.buf = calloc(1, sizeof(uint8_t)); resourceMapping.frequencyDomainAllocation.choice.row4.size = 1; resourceMapping.frequencyDomainAllocation.choice.row4.bits_unused = 5; resourceMapping.frequencyDomainAllocation.choice.row4.buf[0] = 32; @@ -507,6 +507,47 @@ static void config_csiim(int do_csirs, csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL; } + +void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig, + const NR_ServingCellConfigCommon_t *scc, + const NR_UE_NR_Capability_t *uecap) +{ + + if(!pdsch_servingcellconfig->ext1) + pdsch_servingcellconfig->ext1=calloc(1,sizeof(*pdsch_servingcellconfig->ext1)); + if(!pdsch_servingcellconfig->ext1->maxMIMO_Layers) + pdsch_servingcellconfig->ext1->maxMIMO_Layers = calloc(1,sizeof(*pdsch_servingcellconfig->ext1->maxMIMO_Layers)); + + NR_SCS_SpecificCarrier_t *scs_carrier = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]; + int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + const frequency_range_t freq_range = band < 100 ? FR1 : FR2; + const int scs = scs_carrier->subcarrierSpacing; + const int bw_size = scs_carrier->carrierBandwidth; + + NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL; + if (fs) { + const int bw_index = get_supported_band_index(scs, freq_range, bw_size); + AssertFatal(bw_index >= 0, "BW corresponding to %d PRBs not found\n", bw_size); + // go through UL feature sets and look for one with current SCS + for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) { + NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i]; + long supported_bw; + if (freq_range == FR1) + supported_bw = dl_fs->supportedBandwidthDL.choice.fr1; + else + supported_bw = dl_fs->supportedBandwidthDL.choice.fr2; + if (scs == dl_fs->supportedSubcarrierSpacingDL && + bw_index == supported_bw && + dl_fs->maxNumberMIMO_LayersPDSCH) { + long ue_supported_layers = (2 << *dl_fs->maxNumberMIMO_LayersPDSCH); + *pdsch_servingcellconfig->ext1->maxMIMO_Layers = NR_MAX_SUPPORTED_DL_LAYERS < ue_supported_layers ? NR_MAX_SUPPORTED_DL_LAYERS : ue_supported_layers; + return; + } + } + } + *pdsch_servingcellconfig->ext1->maxMIMO_Layers = 2; +} + // TODO: Implement to b_SRS = 1 and b_SRS = 2 long rrc_get_max_nr_csrs(const int max_rbs, const long b_SRS) { @@ -759,8 +800,9 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, *bandNRinfo->pusch_256QAM = NR_BandNR__pusch_256QAM_supported; } if (mcs_table_dl == 1) { - int bw = get_supported_band_index(numerology, band, rbsize); - if (band>256) { + const frequency_range_t freq_range = band < 257 ? FR1 : FR2; + int bw = get_supported_band_index(numerology, freq_range, rbsize); + if (freq_range == FR2) { bandNRinfo->pdsch_256QAM_FR2 = CALLOC(1,sizeof(*bandNRinfo->pdsch_256QAM_FR2)); *bandNRinfo->pdsch_256QAM_FR2 = NR_BandNR__pdsch_256QAM_FR2_supported; } @@ -775,7 +817,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, fs->featureSetsDownlinkPerCC = CALLOC(1,sizeof(*fs->featureSetsDownlinkPerCC)); NR_FeatureSetDownlinkPerCC_t *fs_cc = CALLOC(1,sizeof(NR_FeatureSetDownlinkPerCC_t)); fs_cc->supportedSubcarrierSpacingDL = numerology; - if(band>256) { + if(freq_range == FR2) { fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr2; fs_cc->supportedBandwidthDL.choice.fr2 = bw; } @@ -1135,17 +1177,18 @@ static void set_dl_mcs_table(int scs, int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; struct NR_FrequencyInfoDL__scs_SpecificCarrierList scs_list = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList; int bw_rb = -1; - for(int i=0; isubcarrierSpacing){ bw_rb = scs_list.list.array[i]->carrierBandwidth; break; } } - AssertFatal(bw_rb>0,"Could not find scs-SpecificCarrierList element for scs %d",scs); + AssertFatal(bw_rb > 0,"Could not find scs-SpecificCarrierList element for scs %d", scs); bool supported = false; - if (band>256) { - for (int i=0;irf_Parameters.supportedBandListNR.list.count;i++) { + const frequency_range_t freq_range = band > 256 ? FR2 : FR1; + if (freq_range == FR2) { + for (int i = 0; i < cap->rf_Parameters.supportedBandListNR.list.count; i++) { NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; if(bandNRinfo->bandNR == band && bandNRinfo->pdsch_256QAM_FR2) { supported = true; @@ -1514,10 +1557,12 @@ static void config_csi_codebook(const nr_pdsch_AntennaPorts_t *antennaports, { const int num_ant_ports = antennaports->N1 * antennaports->N2 * antennaports->XP; codebookConfig->codebookType.present = NR_CodebookConfig__codebookType_PR_type1; - codebookConfig->codebookType.choice.type1 = calloc(1, sizeof(*codebookConfig->codebookType.choice.type1)); + if(!codebookConfig->codebookType.choice.type1) + codebookConfig->codebookType.choice.type1 = calloc(1, sizeof(*codebookConfig->codebookType.choice.type1)); // Single panel configuration codebookConfig->codebookType.choice.type1->subType.present = NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel; - codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel = calloc(1, sizeof(*codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel)); + if(!codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel) + codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel = calloc(1, sizeof(*codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel)); struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *singlePanelConfig = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; singlePanelConfig->typeI_SinglePanel_ri_Restriction.size = 1; singlePanelConfig->typeI_SinglePanel_ri_Restriction.bits_unused = 0; @@ -1525,85 +1570,88 @@ static void config_csi_codebook(const nr_pdsch_AntennaPorts_t *antennaports, singlePanelConfig->typeI_SinglePanel_ri_Restriction.buf[0] = (1 << max_layers) - 1; // max_layers bit set to 1 if (num_ant_ports == 2) { singlePanelConfig->nrOfAntennaPorts.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two; - singlePanelConfig->nrOfAntennaPorts.choice.two = calloc(1, sizeof(*singlePanelConfig->nrOfAntennaPorts.choice.two)); - singlePanelConfig->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size = 1; - singlePanelConfig->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused = 2; - singlePanelConfig->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf = calloc(1, sizeof(uint8_t)); - singlePanelConfig->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0] = 0xfc; // no restriction (all 6 bits enabled) + if(!singlePanelConfig->nrOfAntennaPorts.choice.two) { + asn1cCalloc(singlePanelConfig->nrOfAntennaPorts.choice.two, two); + two->twoTX_CodebookSubsetRestriction.size = 1; + two->twoTX_CodebookSubsetRestriction.bits_unused = 2; + asn1cCallocOne(two->twoTX_CodebookSubsetRestriction.buf, 0xfc); // no restriction (all 6 bits enabled) + } } else { singlePanelConfig->nrOfAntennaPorts.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo; - singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo = calloc(1, sizeof(*singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo)); - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *moreThanTwo = singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo; - switch (num_ant_ports) { - case 4: - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.size = 1; - moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf = calloc(1, sizeof(uint8_t)); - moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf[0] = 0xff; // TODO verify the meaning of this parameter - break; - case 8: - if (antennaports->N1 == 2) { - AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.size = 8; - moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.buf = calloc(8, sizeof(uint8_t)); - for (int i = 0; i < 8; i++) - moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else if (antennaports->N1 == 4) { - AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.size = 2; - moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.buf = calloc(2, sizeof(uint8_t)); - for (int i = 0; i < 2; i++) - moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else - AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); - break; - case 12: - if (antennaports->N1 == 3) { - AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.size = 12; - moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.buf = calloc(12, sizeof(uint8_t)); - for (int i = 0; i < 12; i++) - moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else if (antennaports->N1 == 6) { - AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.size = 3; - moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.buf = calloc(3, sizeof(uint8_t)); - for (int i = 0; i < 3; i++) - moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else - AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); - break; - case 16: - if (antennaports->N1 == 4) { - AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.size = 16; - moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.buf = calloc(16, sizeof(uint8_t)); - for (int i = 0; i < 16; i++) - moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else if (antennaports->N1 == 8) { - AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); - moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction; - moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.size = 4; - moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.bits_unused = 0; - moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.buf = calloc(4, sizeof(uint8_t)); - for (int i = 0; i < 4; i++) - moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter - } else - AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); - break; - default: - AssertFatal(1 == 0, "%d antenna ports not supported\n", num_ant_ports); + if(!singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo) { + singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo = calloc(1, sizeof(*singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo)); + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *moreThanTwo = singlePanelConfig->nrOfAntennaPorts.choice.moreThanTwo; + switch (num_ant_ports) { + case 4: + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.size = 1; + moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.bits_unused = 0; + // TODO verify the meaning of this parameter + asn1cCallocOne(moreThanTwo->n1_n2.choice.two_one_TypeI_SinglePanel_Restriction.buf, 0xff); + break; + case 8: + if (antennaports->N1 == 2) { + AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.size = 8; + moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.buf = calloc(8, sizeof(uint8_t)); + for (int i = 0; i < 8; i++) + moreThanTwo->n1_n2.choice.two_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else if (antennaports->N1 == 4) { + AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.size = 2; + moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.buf = calloc(2, sizeof(uint8_t)); + for (int i = 0; i < 2; i++) + moreThanTwo->n1_n2.choice.four_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else + AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); + break; + case 12: + if (antennaports->N1 == 3) { + AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.size = 12; + moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.buf = calloc(12, sizeof(uint8_t)); + for (int i = 0; i < 12; i++) + moreThanTwo->n1_n2.choice.three_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else if (antennaports->N1 == 6) { + AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.size = 3; + moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.buf = calloc(3, sizeof(uint8_t)); + for (int i = 0; i < 3; i++) + moreThanTwo->n1_n2.choice.six_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else + AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); + break; + case 16: + if (antennaports->N1 == 4) { + AssertFatal(antennaports->N2 == 2, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.size = 16; + moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.buf = calloc(16, sizeof(uint8_t)); + for (int i = 0; i < 16; i++) + moreThanTwo->n1_n2.choice.four_two_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else if (antennaports->N1 == 8) { + AssertFatal(antennaports->N2 == 1, "N1 and N2 not in accordace with the specifications\n"); + moreThanTwo->n1_n2.present = NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction; + moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.size = 4; + moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.bits_unused = 0; + moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.buf = calloc(4, sizeof(uint8_t)); + for (int i = 0; i < 4; i++) + moreThanTwo->n1_n2.choice.eight_one_TypeI_SinglePanel_Restriction.buf[i] = 0xff; // TODO verify the meaning of this parameter + } else + AssertFatal(1 == 0, "N1 %d and N2 %d not supported for %d antenna ports\n", antennaports->N1, antennaports->N2, num_ant_ports); + break; + default: + AssertFatal(1 == 0, "%d antenna ports not supported\n", num_ant_ports); + } } } codebookConfig->codebookType.choice.type1->codebookMode = 1; @@ -1679,7 +1727,8 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_PUCCH_CSI_Resource_t *pucchcsires, int do_csi, // if rsrp is based on CSI or SSB int rep_id, - int uid) + int uid, + int num_antenna_ports) { NR_CSI_ReportConfig_t *csirep = calloc(1, sizeof(*csirep)); csirep->reportConfigId = rep_id; @@ -1688,7 +1737,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list]; if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) { - if (do_csi) { + if (do_csi && num_antenna_ports < 4) { if (csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) resource_id = csires->csi_ResourceConfigId; } else { @@ -1707,7 +1756,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, true); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); - if (do_csi) { + if (do_csi && num_antenna_ports < 4) { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP; csirep->reportQuantity.choice.cri_RSRP = (NULL_t)0; } else { @@ -2264,6 +2313,13 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, SpCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->present = NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup; SpCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup = pdsch_servingcellconfig; + pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; + pdsch_servingcellconfig->xOverhead = NULL; + pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); + *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; + pdsch_servingcellconfig->pucch_Cell = NULL; + set_dl_maxmimolayers(pdsch_servingcellconfig, scc, NULL); + // Downlink BWPs int n_dl_bwp = 0; if (servingcellconfigdedicated && servingcellconfigdedicated->downlinkBWP_ToAddModList @@ -2404,23 +2460,15 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, pucchcsi, pdsch_Config, &configuration->pdsch_AntennaPorts, - NR_MAX_SUPPORTED_DL_LAYERS, + *pdsch_servingcellconfig->ext1->maxMIMO_Layers, bwp_id, uid); } NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp)); pucchrsrp->uplinkBandwidthPartId = bwp_id; pucchrsrp->pucch_Resource = pucch_Resource; - config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid); + config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, pdsch_AntennaPorts); } - pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; - pdsch_servingcellconfig->xOverhead = NULL; - pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); - *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; - pdsch_servingcellconfig->pucch_Cell = NULL; - pdsch_servingcellconfig->ext1 = calloc(1, sizeof(*pdsch_servingcellconfig->ext1)); - pdsch_servingcellconfig->ext1->maxMIMO_Layers = calloc(1, sizeof(*pdsch_servingcellconfig->ext1->maxMIMO_Layers)); - *pdsch_servingcellconfig->ext1->maxMIMO_Layers = 2; if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_SpCellConfig, SpCellConfig); @@ -2472,6 +2520,16 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig; + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = SpCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup; + set_dl_maxmimolayers(pdsch_servingcellconfig, scc, uecap); + + NR_CSI_MeasConfig_t *csi_MeasConfig = SpCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + for (int report = 0; report < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; report++) { + NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[report]; + if(csirep->codebookConfig) + config_csi_codebook(&configuration->pdsch_AntennaPorts, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, csirep->codebookConfig); + } + int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); NR_UplinkConfig_t *uplinkConfig = SpCellConfig && SpCellConfig->spCellConfigDedicated ? SpCellConfig->spCellConfigDedicated->uplinkConfig : NULL; @@ -2561,7 +2619,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, ul_bwp->bwp_Dedicated->srs_Config = get_config_srs(scc, uecap, bwp_size, uid, i + 1, maxMIMO_Layers, configuration->do_SRS); } } - update_cqitables(bwp_Dedicated->pdsch_Config, SpCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup); + update_cqitables(bwp_Dedicated->pdsch_Config, csi_MeasConfig); } void free_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig) @@ -2842,9 +2900,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; pdsch_servingcellconfig->pucch_Cell = NULL; - pdsch_servingcellconfig->ext1 = calloc(1, sizeof(*pdsch_servingcellconfig->ext1)); - pdsch_servingcellconfig->ext1->maxMIMO_Layers = calloc(1, sizeof(*pdsch_servingcellconfig->ext1->maxMIMO_Layers)); - *pdsch_servingcellconfig->ext1->maxMIMO_Layers = NR_MAX_SUPPORTED_DL_LAYERS; + set_dl_maxmimolayers(pdsch_servingcellconfig, servingcellconfigcommon, uecap); pdsch_servingcellconfig->ext1->processingType2Enabled = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig = NULL; @@ -2929,15 +2985,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC pucchcsires1->uplinkBandwidthPartId = bwp->bwp_Id; pucchcsires1->pucch_Resource = 2; - config_csi_meas_report(csi_MeasConfig, - servingcellconfigcommon, - pucchcsires1, - bwp->bwp_Dedicated->pdsch_Config, - pdschap, - NR_MAX_SUPPORTED_DL_LAYERS, - bwp->bwp_Id, - uid); - config_rsrp_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, do_csirs, bwp->bwp_Id + 10, uid); + config_csi_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, bwp->bwp_Dedicated->pdsch_Config, pdschap, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, bwp->bwp_Id, uid); + config_rsrp_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, do_csirs, bwp->bwp_Id + 10, uid, dl_antenna_ports); } secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index b92150e65b..6a5c9f691f 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -249,6 +249,8 @@ typedef enum { } rrc_action_t; typedef struct gNB_RRC_UE_s { + time_t last_seen; // last time this UE has been accessed + drb_t established_drbs[MAX_DRBS_PER_UE]; NR_DRB_ToReleaseList_t *DRB_ReleaseList; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index e034005ceb..310a955ba9 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -44,7 +44,8 @@ #include "NR_SecurityConfig.h" #include "NR_CellGroupConfig.h" -#define NR_MAX_SUPPORTED_DL_LAYERS 2 +#define NR_MAX_SUPPORTED_DL_LAYERS 4 +void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan); void rrc_gNB_process_SgNBAdditionRequest( const protocol_ctxt_t *const ctxt_pP, @@ -63,6 +64,7 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerLi void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti); +void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p); void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_ServingCellConfig_t *servingcellconfigdedicated, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3b73bae843..89eb31e5a5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "nr_rrc_config.h" #include "nr_rrc_defs.h" @@ -226,7 +227,7 @@ static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_ else AssertFatal(false, "Invalid absoluteFrequencyPointA: %d\n", dl_arfcn); - int bw_index = get_supported_band_index(scs, band, get_dl_bw(cell_info)); + int bw_index = get_supported_band_index(scs, band > 256 ? FR2 : FR1, get_dl_bw(cell_info)); int band_size_hz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, bw_index) * 1000 * 1000; uint32_t ssb_arfcn = to_nrarfcn(band, freqssb, scs, band_size_hz); @@ -1939,6 +1940,19 @@ static void rrc_delete_ue_data(gNB_RRC_UE_t *UE) ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, UE->measResults); } +void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p) +{ + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + /* we call nr_pdcp_remove_UE() in the handler of E1 bearer release, but if we + * are in E1, we also need to free the UE in the CU-CP, so call it twice to + * cover all cases */ + nr_pdcp_remove_UE(UE->rrc_ue_id); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(0, UE->rrc_ue_id); + LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); + rrc_delete_ue_data(UE); + rrc_gNB_remove_ue_context(rrc, ue_context_p); +} + static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) { const int instance = 0; @@ -1949,16 +1963,8 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", complete->gNB_CU_ue_id); return; } - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - /* we call nr_pdcp_remove_UE() in the handler of E1 bearer release, but if we - * are in E1, we also need to free the UE in the CU-CP, so call it twice to - * cover all cases */ - nr_pdcp_remove_UE(UE->rrc_ue_id); - rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance, UE->rrc_ue_id); - LOG_I(NR_RRC, "removed UE CU UE ID %u/RNTI %04x \n", UE->rrc_ue_id, UE->rnti); - rrc_delete_ue_data(UE); - rrc_gNB_remove_ue_context(rrc, ue_context_p); + rrc_remove_ue(RC.nrrrc[0], ue_context_p); } static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) @@ -2290,6 +2296,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) return; } + time_t now = time(NULL); int i = 0; rrc_gNB_ue_context_t *ue_context_p = NULL; /* cast is necessary to eliminate warning "discards ‘const’ qualifier" */ @@ -2309,6 +2316,8 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) fprintf(f, " S-TMSI %x", ue_ctxt->Initialue_identity_5g_s_TMSI.fiveg_tmsi); fprintf(f, ":\n"); + time_t last_seen = now - ue_ctxt->last_seen; + fprintf(f, " last RRC activity: %ld seconds ago\n", last_seen); fprintf(f, " RRC status %s\n", get_rrc_connection_status_text(ue_ctxt->StatusRrc)); if (ue_ctxt->nb_of_pdusessions == 0) @@ -2668,23 +2677,6 @@ rrc_gNB_generate_RRCRelease( }; deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id}; nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data); - - /* a UE might not be associated to a CU-UP if it never requested a PDU - * session (intentionally, or because of erros) */ - if (ue_associated_to_cuup(rrc, UE)) { - sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); - e1ap_bearer_release_cmd_t cmd = { - .gNB_cu_cp_ue_id = UE->rrc_ue_id, - .gNB_cu_up_ue_id = UE->rrc_ue_id, - }; - rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd); - } - -#ifdef E2_AGENT - signal_rrc_state_changed_to(UE, RC_SM_RRC_IDLE); -#endif - - /* UE will be freed after UE context release complete */ } int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 2fafec982a..e198ab0748 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -73,6 +73,10 @@ #include "conversions.h" #include "RRC/NR/rrc_gNB_radio_bearers.h" +#ifdef E2_AGENT +#include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h" +#endif + #include "uper_encoder.h" extern RAN_CONTEXT_t RC; @@ -1178,7 +1182,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); return (-1); } else { - /* TODO release context. */ + /* Send the response */ MessageDef *msg_resp_p; msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); @@ -1195,7 +1199,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in */ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance) { - //----------------------------------------------------------------------------- + gNB_RRC_INST *rrc = RC.nrrrc[0]; uint32_t gNB_ue_ngap_id = 0; protocol_ctxt_t ctxt; gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id; @@ -1214,9 +1218,34 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_ } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); - ctxt.eNB_index = 0; - rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); +#ifdef E2_AGENT + signal_rrc_state_changed_to(UE, RC_SM_RRC_IDLE); +#endif + + /* a UE might not be associated to a CU-UP if it never requested a PDU + * session (intentionally, or because of erros) */ + if (ue_associated_to_cuup(rrc, UE)) { + sctp_assoc_t assoc_id = get_existing_cuup_for_ue(rrc, UE); + e1ap_bearer_release_cmd_t cmd = { + .gNB_cu_cp_ue_id = UE->rrc_ue_id, + .gNB_cu_up_ue_id = UE->rrc_ue_id, + }; + rrc->cucp_cuup.bearer_context_release(assoc_id, &cmd); + } + + /* special case: the DU might be offline, in which case the f1_ue_data exists + * but is set to 0 */ + if (cu_exists_f1_ue_data(UE->rrc_ue_id) && cu_get_f1_ue_data(UE->rrc_ue_id).du_assoc_id != 0) { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0); + ctxt.eNB_index = 0; + rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); + + /* UE will be freed after UE context release complete */ + } else { + // the DU is offline already + rrc_remove_ue(rrc, ue_context_p); + } + return 0; } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index c560753807..18edf9e856 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -32,11 +32,16 @@ #include #include #include +#include #include "common/utils/LOG/log.h" #include "rrc_gNB_UE_context.h" #include "openair2/F1AP/f1ap_ids.h" +static void rrc_gNB_ue_context_update_time(rrc_gNB_ue_context_t *ctxt) +{ + ctxt->ue_context.last_seen = time(NULL); +} //------------------------------------------------------------------------------ int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP) @@ -68,6 +73,7 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance return NULL; } new_p->ue_context.rrc_ue_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator) + 1; + rrc_gNB_ue_context_update_time(new_p); for(int i = 0; i < NB_RB_MAX; i++) new_p->ue_context.pduSession[i].xid = -1; @@ -92,8 +98,10 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST *rrc_instance_ rrc_gNB_ue_context_t *ue_context_p; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_context_p->ue_context.rrc_ue_id); - if (ue_data.du_assoc_id == assoc_id && ue_context_p->ue_context.rnti == rntiP) + if (ue_data.du_assoc_id == assoc_id && ue_context_p->ue_context.rnti == rntiP) { + rrc_gNB_ue_context_update_time(ue_context_p); return ue_context_p; + } } LOG_W(NR_RRC, "search by RNTI %04x and assoc_id %d: no UE found\n", rntiP, assoc_id); return NULL; @@ -104,8 +112,10 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_in rrc_gNB_ue_context_t *ue_context_p; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { - if (ue_context_p->ue_context.rnti == rntiP) + if (ue_context_p->ue_context.rnti == rntiP) { + rrc_gNB_ue_context_update_time(ue_context_p); return ue_context_p; + } } LOG_W(NR_RRC, "search by rnti not found %04x\n", rntiP); return NULL; @@ -146,8 +156,10 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_random_exist(gNB_RRC_INST *rrc_instance { rrc_gNB_ue_context_t *ue_context_p = NULL; RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { - if (ue_context_p->ue_context.random_ue_identity == ue_identityP) + if (ue_context_p->ue_context.random_ue_identity == ue_identityP) { + rrc_gNB_ue_context_update_time(ue_context_p); return ue_context_p; + } } return NULL; } @@ -161,8 +173,10 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { LOG_I(NR_RRC, "Checking for UE 5G S-TMSI %ld: RNTI %04x\n", s_TMSI, ue_context_p->ue_context.rnti); - if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) + if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) { + rrc_gNB_ue_context_update_time(ue_context_p); return ue_context_p; + } } return NULL; } diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index dc78d534e4..cb2de0bf4c 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -20,6 +20,7 @@ */ #include "rrc_gNB_du.h" +#include "rrc_gNB_NGAP.h" #include "common/ran_context.h" #include "nr_rrc_defs.h" #include "rrc_gNB_UE_context.h" @@ -211,10 +212,14 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id) f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id); if (ue_data.du_assoc_id == assoc_id) { /* this UE belongs to the DU that disconnected, set du_assoc_id to 0, - * meaning DU is offline */ + * meaning DU is offline, then trigger release request */ cu_remove_f1_ue_data(ue_id); - f1_ue_data_t new = {.secondary_ue = ue_data.secondary_ue, .du_assoc_id = 0 }; - cu_add_f1_ue_data(ue_id, &new); + ue_data.du_assoc_id = 0; + cu_add_f1_ue_data(ue_id, &ue_data); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(0, + ue_context_p, + NGAP_CAUSE_RADIO_NETWORK, + NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); count++; } } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 23da4916e0..42540222f0 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -459,7 +459,9 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n"); return; } - + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message); + // Actions following cell selection while T311 is running NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (is_nr_timer_active(timers->T311)) { @@ -717,10 +719,6 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, (const void *)Sdu, Sdu_len); - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message); - } - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(NR_RRC, "[UE %ld] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", rrc->ue_id, dec_rval.consumed); log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n"); @@ -730,6 +728,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, return -1; } + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message); + } + if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1->present) { case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index dfc0f64aa9..cf1897ae16 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1261,6 +1261,9 @@ void *nas_nrue(void *args_p) offset++; } } break; + case FGS_PDU_SESSION_ESTABLISHMENT_REJ: + LOG_E(NAS, "Received PDU Session Establishment reject\n"); + break; default: LOG_W(NR_RRC, "unknown message type %d\n", msg_type); break; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index b5bb026c0b..a892bf1b4b 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -65,6 +65,7 @@ // message type for 5GS session management #define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */ #define FGS_PDU_SESSION_ESTABLISHMENT_ACC 0b11000010 /* 194= 0xc2 */ +#define FGS_PDU_SESSION_ESTABLISHMENT_REJ 0b11000011 /* 195= 0xc3 */ #define INITIAL_REGISTRATION 0b001